1
votes

I want to display in the article sidebar (in wordpress) a list of 5 recent articles from that category to which it belongs. I'm using the code below to (using a shortcode) show the 5 posts (from category 62 in this case). Is there a way to write this code in functions.php so that it is optimised, and I don't have to rewrite everything for each new category?

 /** 
  * function to add recent posts widget 
  */ 
function wpcat_postsbycategory_musculacao() {
 // the query
 $the_query = new WP_Query( array( 'cat' => '62', 'posts_per_page' => 5 ) ); 
 // The Loop
 if ( $the_query->have_posts() ) {
     $string .= '<ul class="postsbytag widget_recent_entries">';
     while ( $the_query->have_posts() ) {
         $the_query->the_post();
             if ( has_post_thumbnail() ) {
             $string .= '<li>';
             $string .= '<a href="' . get_the_permalink() .'" rel="bookmark">' . get_the_post_thumbnail($post_id, array( 80, 80) ) . get_the_title() .'</a></li>';
             } else { 
             // if no featured image is found
             $string .= '<li><a href="' . get_the_permalink() .'" rel="bookmark">' . get_the_title() .'</a></li>';
             }
             }
     } else {
     // no posts found
 }
 $string .= '</ul>';
 return $string;
 /* Restore original Post Data */
 wp_reset_postdata();
 }
 // Add a shortcode
 add_shortcode('categoryposts-musculacao', 'wpcat_postsbycategory_musculacao');
 
 /** 
  * function to change search widget placeholder 
  */
 function db_search_form_placeholder( $html ) {
        $html = str_replace( 'placeholder="Pesquisar ', 'placeholder="Buscar ', $html );
        return $html;
}
add_filter( 'get_search_form', 'db_search_form_placeholder' );
1
Posts can have multiple categories in Wordpress, so it depends on what you want to do about that. My answer below gives you different ways to do this depending on how you want to do it. Let me know how you get on with those!FluffyKitten

1 Answers

0
votes

The complication here is that in WP a post can have multiple categories. You need to decide how to handle that - get from all categories, or if you only want to show posts from one category, how do you choose which?

I've given a few answers below depending on how you want to handle that.

1. Get posts in any of the categories of the current post

As posts can have multiple categories, you can get all of the ids and use this to query for posts that are in any of those categories:

// 1. get the categories for the current post
global $post;
$post_categories = get_the_category( $post->ID );

// 2. Create an array of the ids of all the categories for this post
$categoryids = array(); 
foreach ($post_categories as $category)
    $categoryids[] = $category->term_id;

// 3. use the array of ids in your WP_Query to get posts in any of these categories
$the_query = new WP_Query( array( 'cat' => implode(",",$categoryids), 'posts_per_page' => 5 ) ); 

1a. Get posts in any of the categories but not their children

Note cat will include children of those category ids. If you want to include those exact categories only and not children, use category__in instead of cat:

$the_query = new WP_Query( array('category__in' => $categoryids, 'posts_per_page' => 5) ); 

2. Get posts that have all of the categories of the current post

If you want posts that have all the same categories as the current one, this is done in the same way as above, except we use category__and instead of cat (Note that this does not include children of those categories) :

$the_query = new WP_Query( array('category__in' => $categoryids, 'posts_per_page' => 5) ); 

3. If you know your post will only have one category

If you know you only have one category per post, then you can just use the first element from the category array:

// 1. Just use the id of the first category
$categoryid = $post_categories[0]->term_id;
$the_query = new WP_Query( array( 'cat' => $categoryid, 'posts_per_page' => 5 ) ); 

4. Pass the category into the shortcode

If you want to specify which category to show, you can pass the category id into the shortcode, letting you choose whichever category you want. (FYI you can also get it to work with slug instead of id, which might be a bit more user-friendly)

Your shortcode is currently used like this, I assume:

[categoryposts-musculacao]

We can change the function so you can pass the category like this:

[categoryposts-musculacao category=62]

Shortcode function can accept an $attributes argument that has the information or "attributes" we're adding to the shortcode, e.g. category. We use this to get the category passed in as a variable called $category and then just use it instead of the hardcoded value in the rest of your function.

// 1. include the $attributes argument
function wpcat_postsbycategory_musculacao(  $attributes ) {
    // 2. get the value passed in as category - this will save it into a variable called `$category`
    extract( shortcode_atts( array(
        'category' => ''
    ), $attributes ) );

    // 3. if there is no category don't do anything (or sohw a message or whatever you want
    if (!$category) return "";

    // 4. Now just use your variable instead of the hardcoded value in the rest of the code
     $the_query = new WP_Query( array( 'cat' => $category, 'posts_per_page' => 5 ) ); 
 
    // do the rest of your stuff!
}

Reference: Wordpress Codex Shortcode API

4a. Pass the category into the shortcode by slug

If you want the category attribute in your shortcode to work with a slug instead of the id, you just need to change WP_Query to use category_name instead of cat:

$the_query = new WP_Query( array( 'category_name' => $category, 'posts_per_page' => 5 ) );