Support » Plugins » the_content breaking inline javascript

  • In the file wp-includes\post-template.php, the function the_content().

    After it calls 'the_content' filters, it runs the following code:
    $content = str_replace(']]>', ']]>', $content);

    I know this code has a reason to be there, but I google it everywhere and didn’t find it.

    The problem I found is that, when a <script> code is added, we must put it inside CDATA tags so that XHTML validates it. And this code is breaking validation, since it removes CDATA closing tag.

    And what’s “funny” is that filters call is just above it and even so it is hardcoded, we can’t remove it using the hook system, being forced to hack the core.

    Does anybody know why that replacement is done in the_content? And how to surpass it and be able to add valid scripts into our posts?

Viewing 9 replies - 1 through 9 (of 9 total)
  • That’s interesting why are we converting closing CDATA tags into ‘]]& gt;’?

    I’ve found a track ticket of 3 years old and still alive where ppl ask to modify it, nobody knows why that’s being done, and they just keep passing the ticket to next version, and it’s never committed.

    It seems that posts are packed in CDATA in RSS, and a nested CDATA would break RSS structure. But nobody knows it’s being done for the whole the_content and not only in feed, and why it’s not in a filter.

    Where is that trac? Do you remember the thread?

    It was assigned to 3.0, but I doubt they will commit a 3 years old ticket that is running since 2.1, received 2 fix suggestions and wasn’t committed, so I moved it to 2.9.2 hoping that, in a 19 ticket version, it will get more attention.

    In the meantime, how can we add XHTML valid inline JavaScript code inside posts?

    In the meantime, how can we add XHTML valid inline JavaScript code inside posts?

    I’m not sure. The developers seem to be making that difficult and I can’t work out exactly why.

    If you have reusable scripts you could use a css class plus jQuery and load the jQuery from functions.php. I’m not sure if shortcodes would get around the issue. You could re-process the content in your loop to re-replace the CDATA end tag.

    Both ideas won’t work I think.

    Anything added to the post directly, or by filters (including shortcode), passes by that str_replace().

    In my theme I could use get_the_content(), which doesn’t have it, and manually call apply_filter(). It would fix the problem in my sites, but a plugin can’t request this theme change for each ppl willing to use it.

    The solution I found is use HTML comment tag instead of CDATA flat. Doing so XHTML sees the JavaScript as a comment and passes by, while JS engines runs it. But that’s not a good solution, because as I’ve read some newer browsers may skip HTML-commented scripts. But since WordPress doesn’t let us use CDATA inside posts…

    I’m starting to get pissed, this is the 2nd validation bug I find in WordPress ( It’s easy to fix but we get none, forcing me to change standard WP functions to custom ones in my theme.

    First time I could fix it for myself while I wait a definite solution, but now I can’t ask all plugin users to change their themes!

    Anything added to the post directly, or by filters (including shortcode), passes by that str_replace().

    Yes but you can re-parse the content inside your loop. But you are right that you can’t ask users to edit their theme. However, if a plugin is doing this why can’t you add the javascript to head or load it in the footer including a class value or shortcode or something in your post to trigger the script? Why do you have to embed the script in the post content?

    I can add the JavaScript class to header or footer, but I need a call to each link it obfuscates.

    I have the option to add those calls all together in the footer, with the advantage of doing so being able to add the class to the footer too. And since at that time I know how many links there are to be obfuscated, I can avoid adding the class if there are none. But it also has the problem of wp_enqueue_script() not working when called inside wp_print_footer_scripts, and also all calls are together in the same place, easier for spambots to find them.

    If I add each call in the side of each link, they become spreaded among the HTML document and harder for spambots. But I must add the js to the header so that it’s available when a call is done, and also when there is no call in the whole document, and these calls can’t be properly XHTML validated because of that str_replace().

    I couldn’t use your idea of reverting the replacement because the_content() already prints it. What I could do is use get_the_content() and apply the filters. But as I said I can’t ask other ppl to do the same, and if I do so in my theme I’m leaving the standard.

    The sad thing is that I can’t see why it’s hardcoded and not in a filter, there must be a very serious reason and whoever did that didn’t add the explanation and seems to not be available anymore for explaining, and current ppl with authority to change it are neglecting to do so, maybe because they also don’t know and are afraid of changing and creating a bug.

    And if it’s there because of feeds, I believe feeds don’t support JavaScript at all, so we should have a filter that runs in all situations except feeds, and be able to add XHTML valid JavaScript and won’t go in feeds.

    It’s a simple solution and damn ugly. And nobody seems to have the courage to fix it.

    Was also plagued by this bug and resorted to using an HTML comment instead of the CDATA section for now.

    The core developers are well aware of the issue and it looks like a resolution will be on track for 3.1.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘the_content breaking inline javascript’ is closed to new replies.