WordPress Shortcode Returning “Array”

I am making a custom shortcode which basically is just meant to return my custom post type, here’s my code:

function shortcode_slider($atts, $content=null){  
    extract(shortcode_atts( array('id' => ''), $atts));  
    $return = $content;
    $return .= query_posts( array( 'post_status' => 'publish' , 'post_type' => 'slider'  ) );
    return $return;  
}  
add_shortcode('slider', 'shortcode_slider');

The shortcode works ok apart from one thing – when it returns all of the posts it also returns “array” at the top of the list – any idea why this would happen?

Read More

Also, I want to be able to use the “id” input to be able to specify a category, e.g.

 $return .= query_posts( array( 'post_status' => 'publish' , 'post_type' => 'slider', 'category' => $id  ) );

but I am unsure of the correct syntax for this.

Any help is much appreciated.

Related posts

Leave a Reply

3 comments

  1. First of all, don’t use query_posts.
    Please, check:

    In a shortcode case, I’d go with get_posts. It will return what you need and won’t mess with the loop.

    It is worth noting that you don’t really need to extract the attributes, using $atts['id'] does the work.

    Follows a working shortcode, see comments:

    add_shortcode( 'slider', 'shortcode_slider' );
    
    function shortcode_slider( $atts, $content=null )
    {  
        // Initialize variable and check for shortcode content
        $return = '';
        if( $content ) {
            $return = $content;
        }
    
        // Shortcode attribute: title="Lorem Ipsum"
        if( isset( $atts['title'] ) ) 
        {
            $return .= '<br><h2>' . $atts['title'] . '</h2>';
        }
    
        // Get our custom posts
        // 'category' is the category ID or a comma separated list of ID numbers
        $sliders = get_posts( array( 
            'post_status' => 'publish', 
            'post_type' => 'slider',
            'numberposts' => 10, 
            'order'=> 'ASC', 
            'orderby' => 'title',
            'category' => $atts['id']  
        ) );
    
    
        // Auxiliary variable, don't print <br> in the first element
        $first = '';
    
        // Iterate through the resulting array
        // and build the final output
        // Use $slide->post_author, ->post_excerpt, as usual
        //   $slide->ID can be used to call auxiliary functions 
        //   such as get_children or get_permalink
        foreach( $sliders as $slide ) 
        {
            $link = get_permalink( $slide->ID );
            $return .= 
                $first
                . '<a href="' . $link . '">'
                . $slide->post_title 
                . '</a>
            ';
            $first = '<br>';
        }
    
        return $return;  
    }  
    

    Shortcode applied in a default post type:

    shortcode

    Custom post types:

    cpt

    Result:

    cpt shortcode result

    Useful links:

  2. It seems that “array” is being included because you are using $content first. To be really sure, you would have to post how you are writing this shortcode in a post, but this is the general idea. You probably don’t need the line:

    $return = $content;
    

    If your shortcode syntax is [slider]some text[/slider], then the above line is okay.

    As for the second part, you would retrieve the id using $atts[‘id’] in your code. Your shortcode would be:

    [slider id="5"]
    
  3. The reason it’s printing Array is right here:

    $return .= query_posts( ...
    

    First, you set $return to the content string. Then, you append an array returned by query_posts() to it. I’m a little surprised you’re not getting an “array to string conversion” error, but perhaps you’re suppressing them.

    WordPress auto-echos shortcode, so whatever you return it will echo out. Using the shortcode to get posts is probably not the best idea. Shortcodes should return strings.

    This answer feels incomplete because it’s unclear what you’re trying to accomplish. query_posts is meant to alter the loop, but by the time shortcodes are fired you’re already in the loop.