[wp-hackers] Post excerpts within the_content filter callback functions

Otto otto at ottodestruct.com
Wed Jun 16 03:57:17 UTC 2010


Question: Are your shortcodes actually being applied at this point in
the code? Several plugins I've seen hide the add_shortcode function
call behind some sort of function that only takes place on the main
blog page itself, not in the admin screens.

I'll give you an example from Nextgen Gallery:

// Load backend libraries
if ( is_admin() ) {	
	... load a bunch of stuff here ...
// Load frontend libraries							
} else {
...
	require_once (dirname (__FILE__) . '/lib/shortcodes.php'); 		// 92.664
}	

In this case, the shortcode processing bits are only loaded in the
non-admin screens. So, if your code which is trying to get that
excerpt is in the admin screens, then the shortcodes, which are not
loaded, won't be processed.

The key is to make sure that your shortcode functions are *always*
loaded, even in the admin areas. This way, anything trying to get the
content will get the shortcodes processed into normal HTML.

-Otto



On Tue, Jun 15, 2010 at 9:55 PM, John Blackbourn
<johnbillion+wp at gmail.com> wrote:
> In short: How can a plugin fetch the post excerpt from within a
> 'the_content' filter callback function?
>
> In long:
>
> This is technically a bug, but I'm not sure it can be fixed easily, so
> recommendations for how it can be worked around would be appreciated.
>
> A plugin of mine adds a filter to 'the_content'. In the callback
> function for this filter, I'd like to get the post excerpt. We could
> just use the $post->post_excerpt property, but this will only give us
> an excerpt if one has been explicitly set; it won't give us a
> generated excerpt. So we use get_the_excerpt() like we should. Problem
> is, the following code will not work:
>
> function my_content_callback( $content ) {
>        global $post;
>        $excerpt = get_the_excerpt( $post->ID );
>        // do something with $excerpt
>        return $content;
> }
> add_filter( 'the_content', 'my_content_callback' );
>
> The reason this doesn't work is because this will cause an infinite
> loop in PHP if the post's post_excerpt field is empty. Why? When
> get_the_excerpt() is called, if the post's post_excerpt field is empty
> then wp_trim_excerpt() will generate an excerpt using the post
> content, and this post content has the_content filter applied to it,
> giving us our infinite loop.
>
> Not to worry, we can get around this by removing our content filter
> before fetching the excerpt, then re-applying the filter after we get
> it:
>
> function my_content_callback( $content ) {
>        global $post;
>        remove_filter( 'the_content', 'my_content_callback' );
>        $excerpt = get_the_excerpt( $post->ID );
>        add_filter( 'the_content', 'my_content_callback' );
>        // do something with $excerpt
>        return $content;
> }
> add_filter( 'the_content', 'my_content_callback' );
>
> This is far from ideal, but it works.
>
> So we've got around this problem, but we now introduce another
> problem. Somehow, somewhere, our shortcodes have all broken. Our
> shortcodes are simply not parsed and the body of our post just
> displays the raw shortcodes (eg [myshortcode]).
>
> Why is this happening? The do_shortcode() function (which is a filter
> applied to the_content in order to parse all our shortcodes) uses
> preg_replace_callback(). Because we're calling get_the_excerpt() from
> within a function which is itself a callback function for the
> 'the_content' filter, it means we have nested use of
> preg_replace_callback(), and that doesn't work (it's a PHP bug:
> http://bugs.php.net/bug.php?id=16040). This is (I *think*) why our
> shortcodes are not being parsed in this situation.
>
> So to recap: get_the_excerpt() uses wp_trim_excerpt() which applies
> 'the_content' filter. Calling get_the_excerpt() from within a
> 'the_content' filter callback function causes nested use of
> do_shortcode() which in turn causes nested use of
> preg_replace_callback() which causes a PHP bug, and this breaks
> shortcodes.
>
> How then do we get the post excerpt from within a 'the_content' filter
> callback function without breaking shortcodes?
>
> A plugin could use its own version of the get_the_excerpt() function
> which doesn't apply the 'the_content' filter - is this the only way?
>
> Caveat: preg_replace_callback() might not be to blame, but if it's not
> then I don't know what is.
>
> John
> _______________________________________________
> wp-hackers mailing list
> wp-hackers at lists.automattic.com
> http://lists.automattic.com/mailman/listinfo/wp-hackers
>


More information about the wp-hackers mailing list