0

I'm using the following function to create a shortcode that displays a dropdown for post type archives:

// Email Archives Shortcode
function email_archives_shortcode() { ?>
    <select name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
    <option value=""><?php echo esc_attr( __( 'Select Month' ) ); ?></option> 
    <?php wp_get_archives( array( 'type' => 'monthly', 'format' => 'option', 'show_post_count' => 1, 'post_type' => 'emails' ) ); ?>
    </select>
<?php }
add_shortcode('email-archives', 'email_archives_shortcode');

It works fine except when I insert the shortcode in a widget, it displays above the widget title instead of below.

4
  • 2
    shortcodes should return a value, not echo it Jan 19, 2018 at 17:29
  • Thanks @Mark Kaplun but how do I fix it? Jan 19, 2018 at 17:36
  • either construct it as a string to be returned, or use ob_start and its sibling to capture the output into a string Jan 19, 2018 at 18:28
  • If you could edit my code and it works, I can accept it as the correct answer. Thanks! Jan 19, 2018 at 18:40

1 Answer 1

5

Either use output buffering:

// Email Archives Shortcode
function email_archives_shortcode() { 
    ob_start(); ?>
    <select name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
    <option value=""><?php echo esc_attr( __( 'Select Month' ) ); ?></option> 
    <?php wp_get_archives( array( 'type' => 'monthly', 'format' => 'option', 'show_post_count' => 1, 'post_type' => 'emails' ) ); ?>
    </select>
    <?php return ob_get_clean();
}
add_shortcode('email-archives', 'email_archives_shortcode');

Or a string

function email_archives_shortcode() {
  return sprintf(
    '<select name="archive-dropdown" onchange="document.location.href=this.options[this.selectedIndex].value;">
    <option value="">%1$s</option>
    %2$s
    </select>',
    esc_attr( __( 'Select Month' ) ),
    wp_get_archives( array( 
      'type' => 'monthly', 
      'format' => 'option', 
      'show_post_count' => 1, 
      'post_type' => 'emails', 
      echo => false, 
    ) )
  );
}
add_shortcode('email-archives', 'email_archives_shortcode');
1
  • I used the first example and works like a charm. Thanks! Jan 25, 2018 at 19:29

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.