skip to Main Content

So we have a custom page template in our WordPress theme, that fetches 3 different pages’ content and renders them into a tabbed layout. It includes the glossary section like so:

<div class="glossary-content content e8-tab-panel" data-tab="glossary">
    <?php
    $content = apply_filters( 'the_content', get_the_content( null, false, 80 ) );
    echo ($content);
    ?>
</div>

When we use a block (like Kadence Blocks TOC) or another Table of Contents plugin, the TOC is not rendered.

If I modify the above and get rid of the apply_filters call, then the code for the TOC shows up as a comment.

<div class="glossary-content content e8-tab-panel" data-tab="glossary">
    <?php
    $content = get_the_content( null, false, 80 );
    echo ($content);
    ?>
</div>

Gives me this in the content output:

<!-- wp:kadence/tableofcontents {"uniqueID": ...

Keeping the apply_filters call in there, strips the block info comments out.

Is there a filter I need to call in order to get this page to render custom blocks? Specifically the Kadence Blocks TOC, but really I’ll use any TOC plugin at this point. I have a feeling that I am missing a step that will parse the content through all the filters registered by installed plugins, but my search has come up empty.

Thanks.

2

Answers


  1. Chosen as BEST ANSWER

    Went down a deep rabbit hole trying to figure out how to trigger the rendering of blocks. Turns out that WP relies heavily on a super global array and it must contain the Page to be rendered. But by default it is set to my containing page which is using this custom template (not my 3 loaded page fragments).

    So I set it manually for each of the 3 sections before fetching and filtering the content.

    <div class="glossary-content content e8-tab-panel" data-tab="glossary">
        <?php
            $GLOBALS['post'] = WP_Post::get_instance( 80 ); // Override to ensure block parsing.
            $content = apply_filters( 'the_content', get_the_content( null, false, 80 ) );
            echo $content;
        ?>
    </div>
    

    Interestingly you must set a post global value with an instance of WP_Post even though this is a Page.


  2. Solution provided to me on Mastodon. Credit to @[email protected].

    A more "canonical" way of doing that is:

    function my_render_post_content(int $id): void {
        $GLOBALS['post'] = get_post($id);
        the_content();
        wp_reset_postdata();
    }
    

    This ensures full compatibility with plugins listening for different hooks and ensures you don’t have issues accessing data from the "wrapper" page later.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search