0

I am trying to hook some content AFTER the_content, but no matter how I do it I still get my custom content BEFORE the_content:

add_filter( 'the_content', 'ow_add_sctns_to_ctnt' );
function ow_add_sctns_to_ctnt( $content ) {
    $section = ow_create_section( 'section' );
    return '<div>' . $content . '</div>' . $section;
}

Then I still get:

<p>My custom content</p>
<div>
    <p>The Content</p>
</div>

Looking at the code I would expect My custom content to show AFTER The Content.

ow_create_section is a function that gets content from Advanced Custom Fields. Here is it:

function ow_create_section( $name ) {

    if ( have_rows( $name ) ):
        while ( have_rows( $name ) ): the_row();
            if ( get_row_layout() === 'section_accordions' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_accordions = new OwSctnAccordions( 'accns', $args );

            elseif ( get_row_layout() === 'section_content_single' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_content_single = new OwSctnContentSingle( 'ctnt-sgl', $args );

            elseif ( get_row_layout() === 'section_content_double' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_content_double = new OwSctnContentDouble( 'ctnt-dbl', $args );

            elseif ( get_row_layout() === 'section_callouts' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_callouts = new OwSctnCallouts( 'clts', $args );

            elseif ( get_row_layout() === 'section_gallery_image' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_gallery_image = new OwSctnGalleryImage( 'grid', $args );

            elseif ( get_row_layout() === 'section_gallery_media' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_gallery_media = new OwSctnGalleryMedia( 'grid', $args );

            elseif ( get_row_layout() === 'section_slider_image' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_slider_image = new OwSctnSliderImage( 'slider', $args );

            elseif ( get_row_layout() === 'section_slider_content' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_slider_content = new OwSctnSliderContent( 'slider', $args );

            elseif ( get_row_layout() === 'section_slider_slick' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_slider_slick = new OwSctnSliderSlick( 'slider', $args );

            elseif ( get_row_layout() === 'section_tabs' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_tabs = new OwSctnTabs( 'tabs', $args );

            elseif ( get_row_layout() === 'section_video' ):
                $args = array( 'content' => get_sub_field( 'content' ) );
                $ow_sctn_video = new OwSctnVideo( 'video', $args );

            endif;
        endwhile;
    endif;
}

What am I missing? Thanks in advance!

4
  • Thanks for replying! For some reason, I get the content after the custom content. I don't understand how can this be possible.
    – epicrato
    Commented Sep 12, 2019 at 22:25
  • I have extended my comment above. Please provide the code in ow_create_section(). The issue is there 100%.
    – freejack
    Commented Sep 12, 2019 at 22:27
  • Thanks @freejack. I edited my question with the function.
    – epicrato
    Commented Sep 12, 2019 at 22:36
  • Your code is correct and works well for me. I have changed the content of $sections with plain HTML and it appears after the post content as expected. What is the code in ow_create_section? Are you using ob_start / ob_get_clean to return the extra content from that function? If not calling ow_create_section function would render before the content.
    – freejack
    Commented Sep 12, 2019 at 22:54

1 Answer 1

2

When the_content hook is called WordPress is already busy generating the page HTML. the_content is a filter hook so the function must not render any content but should return it as a string. If you call a function from within the hook and that functions renders some content it will be rendered before the post content.

Using the code below as an example, there are two functions called inside the_content. The first functions renders a red paragraph. This will appear before the content. The second functions uses ob_start() to buffer the HTML content then it returns it using ob_get_clean(). This will appear as expected after the content.

function ow_create_section_1(){
    echo '<p style="width:100%;height:50px;background:red;">Section 1</p>';
}

function ow_create_section_2(){
    ob_start();
    echo '<p style="width:100%;height:50px;background:green;"></p>';
    return ob_get_clean();
}

add_filter( 'the_content', 'ow_add_sctns_to_ctnt' );
function ow_add_sctns_to_ctnt( $content ) {
    $section_1 = ow_create_section_1();
    $section_2 = ow_create_section_2();
    return '<div>' . $content . '</div>' . $section_1 . $section_2;
}

This means that your ow_create_section function is rendering some content directly instead of using the buffer and returning it. Make sure that the classes used inside ow_create_section are returning the content and not rendering it directly.

https://www.php.net/manual/en/function.ob-start.php https://www.php.net/manual/en/function.ob-get-clean.php

1
  • Thanks for your help @freejack!
    – epicrato
    Commented Sep 12, 2019 at 22:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.