-1

EDIT: This shortcode is meant to be used and valid on any WP page. // Thanks Jacob for the note.

I am trying to display a sidebar inside a shortcode.

However, the result of the shortcode, jumps out from the wrapping element (div) in which I am trying to display it.

The red rectangle in screenshots illustrates the problem.

The shortcode source code:

<?php

/*** Featured (1 post + sidebar) ***/

  function blog_loop_feat( $atts ) {
      extract( shortcode_atts( array(), $atts ) );
        echo '<div class="clear"></div>';
                        $args = array();
                        $splendid_query = new  WP_Query( $args );
        $output = '<div class="row">';// Row Open

        while ( $splendid_query->have_posts() ) : $splendid_query->the_post();
                      '<div class="col-md-8 grid-entry-wrapper"> <!-- grid-entry-wrapper open -->
                            <!-- BLOG LOOP -->
                       </div><!-- grid-entry-wrapper close -->';
        endwhile;
        wp_reset_query();

      $output .= '<div class="col-md-4">';

        if ( !function_exists('dynamic_sidebar') || !dynamic_sidebar("Featured sidebar") ) :
        endif;

      $output .= '</div></div>'; // Row Close
      return $output;
  }
add_shortcode('blog_loop_feat', 'blog_loop_feat');

And functions.php snippet:

if ( function_exists('register_sidebar') )
  register_sidebar(array(
    'name' => 'Featured sidebar',
    'before_widget' => '<div class = "widgetizedArea">',
        'meta' => 'feat_widget',
    'after_widget' => '</div>',
    'before_title' => '<h3>',
    'after_title' => '</h3>',
  )
);

The HTML output: enter image description here

Illustrations: enter image description here enter image description here

  • You haven't shown where you put the shortcode to begin with. – Jacob Peattie Jan 23 '18 at 0:19
  • @JacobPeattie my bad. The shortcode is meant to be used on a page. – Scott Agirs Jan 23 '18 at 0:31
  • 1
    All of a shortcode's content must be returned, no echos. If it contains a function that directly outputs content, you need to use output buffering to capture that output. – Milo Jan 23 '18 at 0:43
2

You're using a mix of echoing and returning.

Here you're starting by echoing:

echo '<div class="clear"></div>';

Here you're putting the output into a variable (correctly):

$output = '<div class="row">';

And here you're just writing the content in quotes without echoing or assigning to a variable:

'<div class="col-md-8 grid-entry-wrapper"> <!-- grid-entry-wrapper open -->
     <!-- BLOG LOOP -->
</div><!-- grid-entry-wrapper close -->';

Shortcodes need to return the entirety of their output. So you either need to build up a variable like the second example all the way through, or use output buffering to 'capture' the output to return later.

Here's an example of what you're doing but using output buffering:

function blog_loop_feat( $atts ) {
    $args = array();
    $splendid_query = new WP_Query( $args );
    ob_start();
    ?>

    <div class="clear"></div>

    <div class="row">
        <?php while ( $splendid_query->have_posts() ) : $splendid_query->the_post(); ?>
            <div class="col-md-8 grid-entry-wrapper"> <!-- grid-entry-wrapper open -->
                <!-- BLOG LOOP -->
            </div><!-- grid-entry-wrapper close -->
        <?php endwhile; wp_reset_query(); ?>

        <div class="col-md-4">
            <?php if ( ! function_exists('dynamic_sidebar') || ! dynamic_sidebar("Featured sidebar") ) : endif; ?>
        </div>
    </div>

    <?php
    return ob_get_clean();
}
add_shortcode( 'blog_loop_feat', 'blog_loop_feat' );

ob_start() starts capturing the output, and ob_get_clean() gets the captured output, which in this example is returned at the end of the function.

  • 1
    You are a true hero of 22nd January of 2018 for me, Jacob! Thank you so much bud! This solved everything and taught me a valuable php lesson, haha. – Scott Agirs Jan 23 '18 at 3:10
0

You could also use closing and opening PHP tags like this :

?>
'<div class="col-md-8 grid-entry-wrapper"> <!-- grid-entry-wrapper open -->
<!-- BLOG LOOP -->
</div><!-- grid-entry-wrapper close -->';
<?php

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.