Aart den Braber
Aart den Braber

Reputation: 862

Wordpress do_shortcode with content and shortcodes inside adds shortcode before the content instead of inline

It seems that do_shortcode() (as well as apply_filters()) adds shortcodes in front of the content instead of inline. How could I go about solving this?

To explain: I'm calling something like this inside my post:

[add_entry_content]
<p>Some text that needs to be displayed *before* the called list.</p>

[add_display_code_list]<!-- the list-content I add -->[/add_display_code_list]

<p>Some text that needs to be displayed *after* the called list.</p>

[/add_entry_content]

My functions.php contains this:

// add_entry_content
function add_entry_content_func( $atts, $content = '' ) { ?>

    <div class="entry-content content">
        <?php echo apply_filters('the_content', $content); ?>
    </div><!-- .entry-content -->

<?php }
add_shortcode( 'add_entry_content', 'add_entry_content_func' );


// add a function to display the code-list
function add_display_code_list_func( $atts, $content = '' ) { ?>

    <ul>
        <li>Dynamically added 1</li>
        <li>Dynamically added 2</li>
    </ul>

<?php }
add_shortcode( 'add_display_code_list', 'add_display_code_list_func' );

I would expect the parser to display this:

Some text that needs to be displayed *before* the called list.

Some text that needs to be displayed *after* the called list.


But it instead displays this (the list is displayed inside the container, but before the text-content):

Some text that needs to be displayed *before* the called list.

Some text that needs to be displayed *after* the called list.


Upvotes: 0

Views: 1976

Answers (1)

Mary
Mary

Reputation: 96

This is because you are displaying the HTML directly within your shortcode callback. You need to return the HTML back through the shortcode. Think of this like a WordPress filter. This will render your short code and output it wherever in the content it was placed.

function add_entry_content_func( $atts, $content = '' ) { 

 $html = '<div class="entry-content content">';
 $html .= apply_filters('the_content', $content);
 $html .= '</div>';

 return $html;
 }

Or try this with ob_start();

<?php function add_entry_content_func( $atts, $content = '' ) { 

ob_start(); ?>

<div class="entry-content content">
    <?php echo apply_filters('the_content', $content); ?>
</div><!-- .entry-content -->

<?php 

 return ob_get_clean();
} ?>

Upvotes: 2

Related Questions