Can’t get an echo to do what I want in WordPress plugin

So I’m trying to write a new plugin since I haven’t been able to find one that does exactly what I want with the extensibility that I desire. The goal of the plugin is to be able to use a simple shortcode to display an image slider that automatically populates with your blog’s latest posts.

I’ve got the basic plugin files ready and the shortcode implemented and tested. I had a snafu solved yesterday on SO but the solution highlighted a new problem. Here’s the code:

Read More
function slyd( $category, $slydcount ) {
    global $post;
    $tmp_post = $post;                                                                              // Create $tmp_post to empty $post once Slyd is done with it

    $args = array(
        'category'      =>  $category,
        'numberposts'   =>  $slydcount
    );
    $slydposts = get_posts( $args );
    foreach( $slydposts as $post ) : setup_postdata($post);
        $post_title         =   get_the_title();                                                    // Get the post's title
        $post_content       =   get_the_content();                                                  // Get the post's content - will write code to get excerpt later
        $post_thumb         =   wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );     // Get the post's featured image's src
        $post_permalink     =   get_permalink();                                                    // Get the post's permalink
        echo '<h2><a href="' . $post_permalink . '">' . $post_title . '</a></h2>'
        . '<p>' . $post_content . '</p>'
        . '<p>' . $post_thumb . '</p>';
    endforeach;
    $post = $tmp_post;                                                                              // Empty $post once Slyd is done with it
}

// Create the shortcode
function slyd_shortcode( $atts ) {
    // $atts        ::=     array of attributes
    // examples:            [slyd]
    //                      [slyd category='slide']
    //                      [slyd slydcount='5']
    //                      [slyd theme='default']

    /* Retrieve attributes set by the shortcode and set defaults for
    unregistered attributes. */
    extract( shortcode_atts( array(
        'category'      =>  'slyd',                                                                 // Which category(s) to display posts from
        'slydcount'     =>  '5',                                                                    // How many Slyds to display
        'theme'         =>  'default'                                                               // Which Slyd theme to use
    ), $atts ) );

    return "<p>category = {$category}, count = {$slydcount}</p>"
    . slyd( $category, $slydcount );
}

add_shortcode( 'slyd', 'slyd_shortcode' );

The issue is in the foreach loop in function slyd();. I was originally using a return where the echo is now to put the result on the screen. That worked to display the first post but it would, of course, escape the function. I need it to cycle through and display all of the posts.

From researching the PHP documentation I found that I could use print in place of echo or return but it’s giving me the same result as echo. What’s happening is the code seems to be executing twice. It places itself where it needs to be the first time, then it also echoes to the browser and places it just below the head of the page.

I suppose my question is whether there’s an alternative to return, echo, or print that would solve my problem?

Thanks in advance.

Now I’m trying to get the plugin to pull in the blog’s latest posts but I’m running into a bit of a snafu. When I use the_title() and the_permalink() they display outside of the code I’m trying to contain them in. Further, the_content() is displaying once with the_permalink() and the_title() and then a second time where it’s supposed to.

You can see the behavior here.

Related posts

Leave a Reply

1 comment

  1. return is what you want in this case. You want to return a value (i.e. html code) from the slyd function so you can use it (in this case append it) in the slyd_shortcode function. However, you need to first collect all output into an additional variable ($ret below), and then return that value:

    function slyd( $category, $slydcount ) {
        global $post;
        $tmp_post = $post;
        $args = array(
            'category'      =>  $category,
            'numberposts'   =>  $slydcount
        );
        $slydposts = get_posts( $args );
        $ret = '';
        foreach( $slydposts as $post ) {
            setup_postdata($post);
            $post_title         =   get_the_title();
            $post_content       =   get_the_content();
            $post_thumb         =   wp_get_attachment_image_src( get_post_thumbnail_id(), 'full' );
            $post_permalink     =   get_permalink();
            $ret .= '<h2><a href="' . $post_permalink . '">' . $post_title . '</a></h2>'
            . '<p>' . $post_content . '</p>'
            . '<p>' . $post_thumb . '</p>';
        }
        $post = $tmp_post;                                                                  
        return $ret;
    }
    

    As you see you should first initialize the $ret variable with an empty string, then append to it on each iteration of the foreach loop. return is used to return the whole string after the loop.