Question

i found this great snippet of code on http://codex.wordpress.org/Template_Tags/get_posts and I edited it a little to suit me. It works.

<p>
    <?php


        $args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => 1 );

        $myposts = get_posts( $args );
        foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
        <?php the_title(); ?>
        </br>
     <?php endforeach; 
     wp_reset_postdata();?>
</p>

I would like to transform it into a shortcode with one changeable variable - category id. But, well, since I don't know php, all I came up is:

function tytuly_postow($atts) {
   extract(shortcode_atts(array(
      'id' => 1,
   ), $atts));

   $args = array( 'posts_per_page' => 0, 'offset'=> 0, 'category' => $id );
   $q ="<p>
    <?php

$myposts = get_posts( $args );
foreach ( $myposts as $post ) : setup_postdata( $post ); ?>
    <?php the_title(); ?>
  </br>
<?php endforeach; 
wp_reset_postdata();?>
</p>";
}
add_shortcode('tytuly','lista_postow');  

Of course, it doesn't work. I use Karma theme and added it in shortcodes.php file. Please, help :)

Was it helpful?

Solution

The code you have is certainly on the right track. Here's how I'd do it:

function tytuly_postow( $atts ) {
   extract( shortcode_atts( array(
      'id' => 1,
   ), $atts ) );

   $posts = get_posts( array(
       'posts_per_page' => -1,
       'post_status'    => 'publish',
       'cat'       => $id,
   ) );

   $output = '';

   if ( $posts ) {
       $output .= '<p>';

       foreach ( $posts as $post ) {
           $output .= apply_filters( 'the_title', $post->post_title ) . '<br />';
       } 

       $output .= '</p>';
   }

   return $output;
}
add_shortcode( 'tytuly', 'tytuly_postow' );  

Offset by default is 0 so you don't need to add it as an argument. I've set posts_per_page to -1. This means get all.

Since you're just listing off titles it may make sense to order them by title. At the moment they'll be ordered by date descending.

I'm setting output to a blank string and returning output at the end. This means no matter what happens the shortcode will always return something, even if that something happens to be an empty string.

Then I'm checking if posts were found. If that's the case I'm adding a paragraph tag before and after the foreach. This was to match your original code.

Finally it loops through each post and uses the_title filter on the post titles then ends each title with a break tag.

OTHER TIPS

By taking a look at the Shortcode API and add_shortcode Function Reference, you can check that the parameters of function add_shortcode are $tag and $func. So, to start fixing your code, you need to fix it:

//[tutuly]
function tytuly_postow($atts) {
    ...
}
add_shortcode('tytuly', 'tytuly_postow'); 

By doing this, you will have a working structure for your shortcode. Now, your second mistake is that your function needs to return a value, thats what your shortcode will be transformed into. To do this, you need to use return.

Edit: Plus, your logic to retrive posts names was wrong, so I fixed it:

So, your fixed code will look like:

//[tutuly id="1"]
function tytuly_postow($atts) {
   extract(shortcode_atts(array(
      'id' => 1,
   ), $atts));

   $args = array(
          'posts_per_page' => -1,
          'category'       => $id,
          'post_status'    => 'publish'
   );
   $myposts = get_posts($args);
   if ($myposts) {
          $q = '<p>';
          foreach ($myposts as $post) {
                 $q .= apply_filters('the_title', $post->post_title) . '<br />';
          }
          $q .= '</p>';
   } else {
          $q = '';
   }

   return $q;
}
add_shortcode('tytuly','tytuly_postow');  

posts_per_page is now set to -1 to retrieve all posts, post_status is used to retrieve only posts that are published.

If you want to retrieve links for your posts, instead of just the name, you can change this line:

$q .= apply_filters('the_title', $post->post_title) . '<br />';

to

$q .= '<a href=' . get_permalink($post->ID) . '>' . apply_filters('the_title', $post->post_title) . '</a><br />';

Notice that if you don't have enough programming skills, you can always use the awesome GenerateWP Shorcodes Generator.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top