1

In the theme I am using customizer to show content before (and after) posts, single post etc.

/**
Page Before Category
*/
$wp_customize->add_setting( 'content_before_category', array(
    'default'           => 0,
    'sanitize_callback' => 'theme_name_sanitize_integer',
) );
$wp_customize->add_control( 'content_before_category', array(
    'label'       => esc_html__( 'Page Before Category', 'theme_name' ),
    'description' => esc_html__( 'Content of the selected page will be shown on Blog Page before all posts.', 'theme_name' ),
    'type'        => 'dropdown-pages',
    'section'     => 'section_blog',
) );

And then in the index.php I used

$content_before_category = get_theme_mod( 'content_before_category', false );

if ( $content_before_category ) {
    $page_id = get_page( $content_before_category );
    echo apply_filters( 'the_content', $page_id->post_content ); // WPCS: xss ok.
}

But I've been told that using the_content filter directly is not good, since it could break plugins as described here.

So I did the following:

In my functions.php I added

if ( ! function_exists( 'mytheme_content_filter' ) ) {
    /**
     * Default content filter
     *
     * @param  string $content Post content.
     * @return string          Post content.
     */
    function mytheme_content_filter( $content ) {
        return $content;
    }
}

/**
 * Adds custom filter that filters the content and is used instead of 'the_content' filter.
 */
add_filter( 'mytheme_content_filter', 'wptexturize' );
add_filter( 'mytheme_content_filter', 'convert_smilies' );
add_filter( 'mytheme_content_filter', 'convert_chars' );
add_filter( 'mytheme_content_filter', 'wpautop' );
add_filter( 'mytheme_content_filter', 'shortcode_unautop' );
add_filter( 'mytheme_content_filter', 'do_shortcode' );

And then the changed the filter to

$content_before_category = get_theme_mod( 'content_before_category', false );

if ( $content_before_category ) {
    $page_id = get_page( $content_before_category );
    echo apply_filters( 'mytheme_content_filter', $page_id->post_content ); // WPCS: xss ok.
}

Which works for everything except embedded content.

The youtube videos, twitter won't render as they normally do.

I tried searching for an embed filter but couldn't find one.

Any advice?

  • Applying the_content filter is not bad as long as you are explicit. Use it! – Nathan Powell Mar 1 '17 at 8:11
  • Explicit? Can you elaborate a bit? You mean what cybmeta mentioned in the answer below with the global $post content? – dingo_d Mar 1 '17 at 8:29
  • Explicit as in your if statement being true. Yes, his example is perfect imo. – Nathan Powell Mar 1 '17 at 8:49
3

the_content filter is as good as other filters are. The issue is that it is supposed to be run inside a loop with the glogal $post correctly set to current post in the loop. So, you could do something like this (not tested, just written here as example):

$content_before_category = get_theme_mod( 'content_before_category', false );

if ( $content_before_category ) {

    global $post;

    // get_page() is deprecated; use get_post() instead
    // $page_id = get_page( $content_before_category );
    $post = get_post( $content_before_category );

    // Setup global post data with our page
    setup_postdata( $post );

    // Output the content
    the_content();

    // Reset global post data
    wp_reset_postdata();

}

If you prefer to run your custom filters, you can. The problem you have with embedded content is that you have not run the auto embbed filter; just add it:

global $wp_embed;
add_filter( 'mytheme_content_filter', array( $wp_embed, 'autoembed') );
  • 2
    This does the trick! The autoembed one. Thanks! I think that's easier than defining the $post global and then resetting it everywhere I used the_content filter (there are a few more places I used it in). So this does it ^^ – dingo_d Mar 1 '17 at 8:25

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.