Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I want to use HTML5 in my WordPress theme, how do I turn off wptexturize?

I don't mind WP adding breaks, but I want them to be <br> and not <br />. How do I get control over how those breaks show up in my code?

EDIT: I only really care about the <br> tag issue, I don't mind the typographic changes it makes.

EDIT2: Actually, I guess <img> tags matter too. Any self-closing standalone tags will matter here. So, <hr> might be an issue as well. Not to mention such wp_head() items as <link> and various <meta> tags.

share|improve this question
1  
what's wrong with <br />? –  Scott M. Aug 11 '10 at 23:36
1  
It's fine, but if I want to hew to the non-XML version of HTML5, I won't want the XML-style ` />` endings. –  artlung Aug 12 '10 at 3:10
    
I thought <br /> was valid html and xhtml? When was it not? –  Ryan Gibbons Aug 13 '10 at 20:14
4  
I believe this question is extremely misleading. wptexturize doesn't, in any way, prevent a site from being HTML 5 compliant. –  Ryan Gibbons Aug 13 '10 at 22:04
2  
Can someone please re-title this along the lines of "How do I remove trailing-slashes from self-closing elements in wordpress-generated markup"? –  Bobby Jack Sep 6 '10 at 12:16
show 7 more comments

6 Answers 6

up vote 20 down vote accepted

Line breaks are added by wpautop(), not wptexturize(). wpautop() is also the function that automatically adds paragraph tags.

You're better off fixing the <br />'s than you are replacing the filter. Since wpautop() runs at priority 10, you can just hook in after that and fix it.

add_filter( 'the_content', 'html5_line_breaks', 25 );

function html5_line_breaks( $content ) {
    return str_replace( '<br />', '<br>', $content );
}

Edit after OP update:

WordPress functions are designed to output XHTML. In order to get rid of those trailing slashes site-wide, you're going to have to use an output buffer. You could use a filter similar to the one above to replace slashes in the post contents, but that wouldn't catch your head, sidebar, etc.

It's a bit ugly and might have a small impact on performance, but here you go (drop this in a plugin or your theme's functions.php file):

if ( !is_admin() && ( ! defined('DOING_AJAX') || ( defined('DOING_AJAX') && ! DOING_AJAX ) ) ) {
    ob_start( 'html5_slash_fixer' );
    add_action( 'shutdown', 'html5_slash_fixer_flush' );
}

function html5_slash_fixer( $buffer ) {
    return str_replace( ' />', '>', $buffer );
}

function html5_slash_fixer_flush() {
    ob_end_flush();
}

That code says if you're not in the administration area and not doing an AJAX request handling, then start buffering the output through a filter and then using the WordPress shutdown hook, output that buffer.

share|improve this answer
    
I haven't had time to crack open functions.php yet, but could you elaborate on where that if block goes? It might be evident once I get a chance to open that file up, but I figure I'd get the question out of the way. –  Thomas Owens Aug 20 '10 at 0:31
    
@Thomas: Your theme's functions.php file is just like a plugin file. Any code in there will automatically be executed. It doesn't matter where it goes as long as it's valid PHP. –  Viper007Bond Aug 20 '10 at 1:00
    
Ah. Interesting. I'm fairly new to WordPress development, so I'm still learning a lot. Thanks for clearing that up. –  Thomas Owens Aug 20 '10 at 1:24
add comment

Here you go:

function my_awesome_tag_fixer( $input ){
  return preg_replace( '/(<.+)\s\/>/', '$1>', $input );
}

foreach( array('the_content', 'the_excerpt', 'comment_text') as $filter )
  add_filter( $filter, 'my_awesome_tag_fixer', 12 );

It's not the most elegant solution, but it gets it done a lot quicker than rewriting wpautop and wptexturize.

share|improve this answer
1  
+1 I did something very similar for HTML 4.01 Strict compliance. –  Trevor Bramble Aug 14 '10 at 21:18
add comment

This can be disabled in e.g. the theme's function.php file by taking advantage of the remove_filter() function (http://codex.wordpress.org/Function_Reference/remove_filter)

remove_filter("the_content", "wptexturize");
share|improve this answer
1  
Can I get more granular control over this? Won't I lose the typographic marks if I do it this way? –  artlung Aug 11 '10 at 19:44
    
I'm not aware of any simple approach off the top of my head, but let me see what I can figure out for you. –  thomasjo Aug 11 '10 at 19:46
    
Short of reproducing the desired functionality found in wptexturize(), I was unable to find any other viable solutions. –  thomasjo Aug 11 '10 at 20:13
    
I wonder if there would be a way to simply reverse the <br /> - replace those with <br> maybe? –  artlung Aug 11 '10 at 20:30
add comment

Just found it; self-closing tags on void elements are valid html.

In HTML5 we've allowed the / on void elements (like <meta>, <img>, <br>, <input>, etc), to ease migration to and from XML.

http://lists.whatwg.org/pipermail/help-whatwg.org/2008-August/000137.html

More infomation:

http://wiki.whatwg.org/wiki/FAQ#Should_I_close_empty_elements_with_.2F.3E_or_.3E.3F

share|improve this answer
    
"However, due to the widespread attempts to use XHTML1, there are a significant number of pages using the trailing slash. Because of this, the trailing slash syntax has been permitted on void elements in HTML in order to ease migration from XHTML1 to HTML5." Permitted as a legacy. I think the way forward is ditching the extra "/", thus my question. I think WordPress needs to allow for the option to create code to xhtml, or html4.01 or html5. –  artlung Aug 13 '10 at 20:29
    
That is the problem you are reading into what is being said. Trailing slashes are permitted, which means it is valid syntax. You are speculating that it is going to be removed? Why guess where the standards are going and create work to solve a problem that doesn't exist? –  Ryan Gibbons Aug 13 '10 at 21:02
    
I'm not speculating on anything. I'm not guessing into anything. The / mark is not required by the spec, and I want to have the option to remove it in WordPress. –  artlung Aug 13 '10 at 21:09
    
I like XHTML, do we have to go back to the disorderly look of old HTML. –  Arlen Beiler Aug 14 '10 at 14:12
    
Arlen, I like orderly html, I like xhtml. I'm a big fan of validators. I have written my own doctype to do validation on my own code. I've used html 3.2, html 4, 4.01, even html 2.0! lab.artlung.com/html-2.0 -- but I would like the option to remove self-closing tags in WordPress. It does not seem like it should be such a big deal. I feel like arguing with the premise of my question is very unhelpful. –  artlung Aug 14 '10 at 14:47
show 1 more comment

I have an starter theme for html5 and WordPress and also a function not for wptexturize, but for wpautop(). Include also other elements of html, like thead, tfoot, aside and use the syntax of html5 like
and

/**
 * wpautop for HTML5, allowed: table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend|section|article|aside|header|footer|hgroup|figure|details|figcaption|summary)
 * @link http://nicolasgallagher.com/using-html5-elements-in-wordpress-post-content/
 * @author nicolas@nicolasgallagher.com
 */
function html5wpautop($pee, $br = 1) {
    if ( trim($pee) === '' )
            return '';

    $pee = $pee . "\n"; // just to make things a little easier, pad the end
    $pee = preg_replace('|<br />\s*<br />|', "\n\n", $pee);
    // Space things out a little
    // *insertion* of section|article|aside|header|footer|hgroup|figure|details|figcaption|summary
    $allblocks = '(?:table|thead|tfoot|caption|col|colgroup|tbody|tr|td|th|div|dl|dd|dt|ul|ol|li|pre|select|form|map|area|blockquote|address|math|style|input|p|h[1-6]|hr|fieldset|legend|section|article|aside|header|footer|hgroup|figure|details|figcaption|summary)';
    $pee = preg_replace('!(<' . $allblocks . '[^>]*>)!', "\n$1", $pee);
    $pee = preg_replace('!(</' . $allblocks . '>)!', "$1\n\n", $pee);
    $pee = str_replace(array("\r\n", "\r"), "\n", $pee); // cross-platform newlines
    if ( strpos($pee, '<object') !== false ) {
            $pee = preg_replace('|\s*<param([^>]*)>\s*|', "<param$1>", $pee); // no pee inside object/embed
            $pee = preg_replace('|\s*</embed>\s*|', '</embed>', $pee);
    }
    $pee = preg_replace("/\n\n+/", "\n\n", $pee); // take care of duplicates
    // make paragraphs, including one at the end
    $pees = preg_split('/\n\s*\n/', $pee, -1, PREG_SPLIT_NO_EMPTY);
    $pee = '';
    foreach ( $pees as $tinkle )
            $pee .= '<p>' . trim($tinkle, "\n") . "</p>\n";
    $pee = preg_replace('|<p>\s*</p>|', '', $pee); // under certain strange conditions it could create a P of entirely whitespace
    // *insertion* of section|article|aside
    $pee = preg_replace('!<p>([^<]+)</(div|address|form|section|article|aside)>!', "<p>$1</p></$2>", $pee);
    $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee); // don't pee all over a tag
    $pee = preg_replace("|<p>(<li.+?)</p>|", "$1", $pee); // problem with nested lists
    $pee = preg_replace('|<p><blockquote([^>]*)>|i', "<blockquote$1><p>", $pee);
    $pee = str_replace('</blockquote></p>', '</p></blockquote>', $pee);
    $pee = preg_replace('!<p>\s*(</?' . $allblocks . '[^>]*>)!', "$1", $pee);
    $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*</p>!', "$1", $pee);
    if ($br) {
            $pee = preg_replace_callback('/<(script|style).*?<\/\\1>/s', create_function('$matches', 'return str_replace("\n", "<WPPreserveNewline />", $matches[0]);'), $pee);
            $pee = preg_replace('|(?<!<br />)\s*\n|', "<br />\n", $pee); // optionally make line breaks
            $pee = str_replace('<WPPreserveNewline />', "\n", $pee);
    }
    $pee = preg_replace('!(</?' . $allblocks . '[^>]*>)\s*<br />!', "$1", $pee);
    // *insertion* of img|figcaption|summary
    $pee = preg_replace('!<br />(\s*</?(?:p|li|div|dl|dd|dt|th|pre|td|ul|ol|img|figcaption|summary)[^>]*>)!', '$1', $pee);
    if (strpos($pee, '<pre') !== false)
            $pee = preg_replace_callback('!(<pre[^>]*>)(.*?)</pre>!is', 'clean_pre', $pee );
    $pee = preg_replace( "|\n</p>$|", '</p>', $pee );

    return $pee;
}

// remove the original wpautop function
remove_filter('the_excerpt', 'wpautop');
remove_filter('the_content', 'wpautop');

// add our new html5autop function
add_filter('the_excerpt', 'html5wpautop');
add_filter('the_content', 'html5wpautop');

see more on the svn of the html5 starter theme, not a framework!

share|improve this answer
add comment

Disable WPtexturize plugin worked for me: Disable WPtexturize

It's pretty straigtforward though:

remove_filter('the_content', 'wptexturize');
remove_filter('the_excerpt', 'wptexturize');
remove_filter('comment_text', 'wptexturize');
share|improve this answer
add comment

protected by toscho Jul 27 '12 at 7:48

Thank you for your interest in this question. Because it has attracted low-quality answers, posting an answer now requires 10 reputation on this site.

Would you like to answer one of these unanswered questions instead?

Not the answer you're looking for? Browse other questions tagged or ask your own question.