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!

  • Thanks for replying! For some reason, I get the content after the custom content. I don't understand how can this be possible. – drjorgepolanco Sep 12 '19 at 22:25
  • I have extended my comment above. Please provide the code in ow_create_section(). The issue is there 100%. – freejack Sep 12 '19 at 22:27
  • Thanks @freejack. I edited my question with the function. – drjorgepolanco Sep 12 '19 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 Sep 12 '19 at 22:54
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

|improve this answer|||||
  • Thanks for your help @freejack! – drjorgepolanco Sep 12 '19 at 22:54

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.