2

On a page in Wordpress, If I enter the following code:

var r='<li><a href="#"><img src="' + slide.src + '" width="50" height="50" /></a></li>';

it is rendered in the browser as

  var r='
<li><a href="#"><img src="' + slide.src + '" width="50" height="50" /></a></li>

';

and it gives me this error in FF Console SyntaxError: unterminated string literal var r='

This is a single-user blog, so I am "Administrator".

How do I prevent Wordpress from fouling my code?

3

The Problem

Really annoying! WordPress wpautop parses the whole page and adds line-breaks in HTML code after certain tags. Unfortunately WP does not recognize when HTML strings occur inside javascript and this can mess up the JS source code of your page!!

// This breaks your JS code:
<script>
json={"html":"<ul><li>one</li><li>two</li></ul>"};
</script>

// After wpautop is done with your code it becomes invalid JSON/JS:
<script>
json={"html":"<ul>
<li>one</li>
<li>two</li>
</ul>"};
</script>

★★ Easy solution ★★

wpautop has a small exception built in: It will not add line breaks inside <pre></pre> blocks :) We can use this to our advantage, simply by wrapping our <script> tags with <pre>:

// Simple solution!
<pre><script>
json={"html":"<ul><li>one</li><li>two</li></ul>"};
</script></pre>

// Extra: Add |style| to ensure the empty <pre> block is not rendered:
<pre style="display:none"><script>
json={"html":"<ul><li>one</li><li>two</li></ul>"};
</script>
  • So grateful for the caveat! Of course we would've thought the nut who wrote wpautop would've done the same for <script> and <style> tags, esp. considering wpautop runs after shortcodes. – Codesmith Sep 5 '17 at 14:40
2

In the new WordPress (WP 5+) Editor - Gutenberg, you can use a "Custom HTML" block to prevent the automatic line breaks and paragraphs:

on Visual Editor click + > Formatting > Custom HTML - and put your JavaScript in there

on Code Editor enclose your JavaScript with <!-- wp:html --> <!-- /wp:html -->

1

You have to bracket the function in <script> tags and then either

1) take all the whitespace out of the script so WordPress does not add <p> tags and then the JS will work, or

2) disable autop in the post editor for all posts/pages (see http://codex.wordpress.org/Function_Reference/wpautop ) so WP doesn't add paragraph breaks, or

3) do the following, which leaves autop enabled globally, but lets you disable it with and tags in individual posts and pages.

Add the function below to functions.php and use the two tags

<!-- noformat on --> and <!-- noformat off -->

in your page/post editor, i.e.

    text will be rendered *with* autop

    <!-- noformat on -->

    text will be rendered *without* autop

    <!-- noformat off -->

    text will be rendered *with* autop

Content outside of the two format tags will have autop enabled, as noted.

Add to functions.php of the theme:

// <!-- noformat on --> and <!-- noformat off --> functions

function newautop($text)
{
    $newtext = "";
    $pos = 0;

    $tags = array('<!-- noformat on -->', '<!-- noformat off -->');
    $status = 0;

    while (!(($newpos = strpos($text, $tags[$status], $pos)) === FALSE))
    {
        $sub = substr($text, $pos, $newpos-$pos);

        if ($status)
            $newtext .= $sub;
        else
            $newtext .= convert_chars(wptexturize(wpautop($sub)));      //Apply both functions (faster)

        $pos = $newpos+strlen($tags[$status]);

        $status = $status?0:1;
    }

    $sub = substr($text, $pos, strlen($text)-$pos);

    if ($status)
        $newtext .= $sub;
    else
        $newtext .= convert_chars(wptexturize(wpautop($sub)));      //Apply both functions (faster)

    //To remove the tags
    $newtext = str_replace($tags[0], "", $newtext);
    $newtext = str_replace($tags[1], "", $newtext);

    return $newtext;
}

function newtexturize($text)
{
    return $text;   
}

function new_convert_chars($text)
{
    return $text;   
}

remove_filter('the_content', 'wpautop');
add_filter('the_content', 'newautop');

remove_filter('the_content', 'wptexturize');
add_filter('the_content', 'newtexturize');

remove_filter('the_content', 'convert_chars');
add_filter('the_content', 'new_convert_chars');
  • I thought "<script>" was obvious but it's still good info for future readers. – TecBrat Mar 29 '16 at 2:04
  • Awesome solution :) Something like this should make it into core... – Philipp Aug 30 '16 at 17:30
0

This is my version of newautop adapted from above:

function toggleable_autop($text, $filter_state = 'autop_enabled') {
    /* Each tag is associated with the key that will toggle the state from current */
    $filter_driver = [
        'autop_enabled' => [ 'tag' => '<!-- noformat on -->', 'filter' => function($text) { return convert_chars(wptexturize(wpautop($text))); } ],
        'autop_disabled'  => [ 'tag' => '<!-- noformat off -->', 'filter' => function($text) { return $text; } ],
    ];

    if ( strlen($text) === 0 ) {
        return '';
    }

    $end_state_position = strpos($text, $filter_driver[$filter_state]['tag']);
    if ( $end_state_position === false ) {
        $end_state_position = strlen($text);
    }
    return $filter_driver[$filter_state]['filter'](substr($text, 0, $end_state_position))
        . toggleable_autop(
            substr($text, $end_state_position + strlen($filter_driver[$filter_state]['tag'])),
            $filter_state === 'autop_enabled' ? 'autop_disabled' : 'autop_enabled'
        );
}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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