How to display post content via jQuery and the_content()

I solved an interesting little problem I ran across recently; investigating it led me to a fuller understanding of how WordPress does some things.

I solved an interesting little problem I ran across recently; investigating it led me to a fuller understanding of how WordPress does some things.

Here’s the setup: when you click a link, a particular div will have its inner HTML set to a particular post content via jQuery. The code would look something like this:

while ( $loop->have_posts() ) : $loop->the_post();
  $content = get_the_content();
?>
  Link to click
  

Could that be made more efficient? Maybe. I guess you could do it through AJAX, passing in the post ID and returning the content, if only to avoid having a potentially long string in the page source—which in this instance is not an issue. The bottom line is, though, we’re passing in the_content() in .html().

And JavaScript won’t take it. When I try, I get the following error:

Uncaught SyntaxError: Unexpected token ILLEGAL

It seems that the_content() adds an extra character (a newline) at the end, and it’s causing the hiccup. Note that get_the_content(), which returns the unformatted post body, does not cause this error.

My solution was to add a filter to remove that extra character. How? Like this, in my theme’s functions.php

function my_content_filter ($content) {
	return substr($content,0,-1);
}

add_filter( 'the_content', 'my_content_filter', 20);

As you know, this hooks a filter function to the ‘the_content’ action, so that my_content_filter() is applied before being rendered. As you can see all the function does is remove the last character of the content string. The last argument is he priority, and determines in what order the filter functions are applied. Naturally, I assumed that since the default priority is 10, anything greater than that meant that my filter would be applied to the formatted content, having already gone through the default filters—adding <p> tags and educated quotes and that pesky illegal unexpected token.

And it worked! However, I was still curious. I’d never delved into filters before, so it seemed like a good time. Starting with the_content(), defined in wp-includes/post-template.php:

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(']]>', ']]>', $content);
  echo $content;
}

Pretty straightfoward, right? You retrieve the content, apply any filters, and return it. I’m not sure what str_replace(']]>', ']]>', $content) is supposed to do, though…

As for the default filters, they’re set in wp-includes/default-filters.php

add_filter( 'the_content', 'wptexturize'        );
add_filter( 'the_content', 'convert_smilies'    );
add_filter( 'the_content', 'convert_chars'      );
add_filter( 'the_content', 'wpautop'            );
add_filter( 'the_content', 'shortcode_unautop'  );
add_filter( 'the_content', 'prepend_attachment' );

We can see that the filters are indeed set with the default priority. And, the formats are defined in yet a third file, wp-includes/formatting.php. It’s ‘wpautop’ that interests us. This is the filter that creates <p> and <br /> tags from single- and double-returns. And yes, it does add a “\n” at the very end. So there you go, question answered and problem solved. I know that my solution works, and I know why.

I’m wondering if I could do better, though. Would remove_filter() be useful? But then I’d still have to re-implement something like wpautop—basically, reinventing the wheel. Nah, I won’t worry about it. This is good enough for now.