Prevent add_shortcode from escaping a tag

In my plugin, I’m rendering a shortcode with some inline JavaScript. WordPress seems to hate the closing CDATA tag (]]>), as it escapes it. I’m using CDATA blocks so as to render well-formed XHTML, which allows other processes to scrape the page content easily (legacy systems which suck and are beyond the scope of this question).

Is there a way to get the closing CDATA tag to output as expected?

Steps to Reproduce

Here’s a snippet of my code with the unimportant parts removed:

add_shortcode( 'foo', array( $this, 'foo_code' ) );

function foo_code( $a ) { 
  return "
  <script>
  //]]>
  </script>";
}

Expected output

<script>
//]]>
</script>";

Actual output

<script>
//]]&gt;
</script>  

Additional Information

I figured out that the opening <script> tag is triggering the escape. If I change the code to

return "
//]]>
</script>";

It outputs

//]]>

For some reason it doesn’t output the closing script tag(!)

It doesn’t matter what else is in the JavaScript block: the ]]> tag is always escaped.

I tried html_entity_decode() on the string before returning it, but that didn’t do anything.

I’ve googled and searched the WordPress.org forums and StackExchange for the solution (or any similar problem) and haven’t found anything remotely applicable.

1 Answer
1

Look at the source of the_content():

function the_content($more_link_text = null, $stripteaser = false) {
    $content = get_the_content($more_link_text, $stripteaser);
    $content = apply_filters('the_content', $content);
    $content = str_replace(']]>', ']]&gt;', $content);
    echo $content;
}

As you can see, there is no filter to prevent that. If you really need inline JavaScript in an XML document you have to escape dangerous characters like < or avoid the_content().

Ruin your day with the six years old Ticket #3670 Removing CDATA close tag ( ]]> ) unbalances the CDATA block. 🙂

Leave a Comment