• I found the following code for adding links to posts in the same category. It works great, but I need a modification, and I don’t know how to do it.

    function popular_posts_per_category() {
    	global $post;
    	$categories = get_the_category();
    	foreach($categories as $category) {
    		$cats[] = $category->cat_ID;
    	}
    	$cats_unique = array_unique($cats);
    	$args = array(
    		'category__in' => $cats_unique,
    		'orderby' => 'date',
    		'order' => 'DESC',
    		'post_type' => 'post',
    		'post_status' => 'publish',
    		'posts_per_page' => 50
    	);
    	echo '<ul>';
    	$popular_posts = null;
    	$popular_posts = new WP_Query($args);
    	while ($popular_posts->have_posts()) : $popular_posts->the_post();
    		$title_trim = get_the_title();
    		if (strlen($title_trim) > 60) {
    			$title_trim = substr($title_trim,0,60);
    		} ?>
    
    		<li><a href="<?php the_permalink(); ?>"><?php echo $title_trim; ?></a></li>
    	<?php endwhile;
    	rewind_posts();
    	echo '</ul>';
    }

    Basically, this function returns links to posts in descending date order, newest post first. I need to modify it so that, instead of starting with the most recent post in the category, it starts with the current post as most recent and works its way back from there.

    So if the current post was published on June 14, 2014, and the newest post in the category was published July 26, 2014, instead of showing the 50 most recent posts in the category starting July 26, 2014, I want it to show posts starting with the post most immediately preceding this current post, published before June 14, 2014.

    Can anyone tell me how to modify this function in order to accomplish this change?

Viewing 9 replies - 1 through 9 (of 9 total)
  • Try this:

    /**
    	 * @param int $post_id
    	 *
    	 * @return array
    	 */
    	function get_posts_from_this_category($post_id = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		/** Get the category/categories that belong(s) to the post */
    		$post_categories_ids = wp_get_post_categories($post_id);
    		$posts               = array(
    			get_post($post_id)
    		);
    		/** Get all posts in that/these category/categories */
    		$category_posts = get_posts(array(
    			"orderby"      => "date", // Actually you don't have to set this and...
    			"order"        => "DESC", // ...this since it's the default value anyway.
    			"category__in" => $post_categories_ids,
    			"post__not_in" => array($post_id) // Exclude the current post
    		));
    		/** Add the posts to the output array */
    		foreach($category_posts as $category_post) {
    			$posts[] = $category_post;
    		}
    
    		return $posts;
    	}

    And if you want to display them as a list as well, call this function:

    /**
    	 * @param int $post_id
    	 */
    	function the_posts_from_this_category_links($post_id = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		$posts = get_posts_from_this_category($post_id);
    		foreach($posts as $post) {
    			echo "<li>";
    			echo '<a href="' . get_permalink($post->ID) . '">';
    			echo get_the_title($post->ID);
    			echo "</a>";
    			echo "</li>";
    		}
    	}

    The only thing you have to do is creating an array with the current post in it. Then use foreach() to push the other posts to it.

    Thread Starter vahost

    (@vahost)

    Thanks, but that doesn’t work the way I intended. I want to be able to control the number of links (currently set to 50) to past articles.

    Also, for some reason, it starts listing from the date of the most recent post in the category rather than from the date of the post shown on the page.

    Ah I see, I didn’t see you mentioning that part. Then replace the two functions with these:

    /**
    	 * @param int $post_id
    	 * @param int $showposts
    	 *
    	 * @return array
    	 */
    	function get_posts_from_this_category($post_id = 0, $showposts = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		/** Get the category/categories that belong(s) to the post */
    		$post_categories_ids = wp_get_post_categories($post_id);
    		$posts               = array(
    			get_post($post_id)
    		);
    		/** Get all posts in that/these category/categories */
    		$category_posts = get_posts(array(
    			"orderby"      => "date", // Actually you don't have to set this and...
    			"order"        => "DESC", // ...this since it's the default value anyway.
    			"category__in" => $post_categories_ids,
    			"post__not_in" => array($post_id), // Exclude the current post
    			"date_query"   => array(
    				"before" => (array(
    						"year"  => get_the_date("Y", $post_id),
    						"month" => get_the_date("m", $post_id),
    						"day"   => get_the_date("d", $post_id)
    					))
    			)
    		));
    		/** Add the posts to the output array */
    		foreach($category_posts as $category_post) {
    			$posts[] = $category_post;
    		}
    		/** Show all posts if $showposts is not set */
    		if(!$showposts) {
    			$showposts = count($posts);
    		}
    		/** Reduce posts according to $showposts */
    		$posts = array_splice($posts, 0, $showposts);
    
    		return $posts;
    	}
    
    	/**
    	 * @param int $post_id
    	 * @param int $showposts
    	 */
    	function the_posts_from_this_category_links($post_id = 0, $showposts = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		$posts = get_posts_from_this_category($post_id, $showposts);
    		foreach($posts as $post) {
    			echo "<li>";
    			echo '<a href="' . get_permalink($post->ID) . '">';
    			echo get_the_title($post->ID);
    			echo "</a>";
    			echo "</li>";
    		}
    	}

    And call it like this, for example:

    <?php the_posts_from_this_category_links(0, 3); ?>

    Setting the post ID to 0 gets the current post ID. 3 is the number of links you want to display.

    Thread Starter vahost

    (@vahost)

    Hmmm … well we’re getting closer, but we’re not there quite yet.

    The first item in the list is the current post, rather than the post preceding the current post.

    No matter what number I put in the second value, I get 6 links.

    Excuse me, but you said “instead of starting with the most recent post in the category, it starts with the current post as most recent”. But now you want “the post preceding the current post”?

    Thread Starter vahost

    (@vahost)

    My apologies. I expressed that badly the first time around. Let me try again.

    I’m talking about three different posts.

    1. The most recent post in the category.
    2. The post currently displayed on the page in the same category.
    3. The post preceding the currently displayed post, meaning the post that was published previous to the current post in the same category.

    I want the list to start with #3 above rather than with #1 above. The version of the code I was reacting to started the list with #1 above rather than with #3 above. That’s what I was trying to say the first time.

    Well, then change

    $posts = array(
    	get_post($post_id)
    );

    with

    $posts = array();

    Thread Starter vahost

    (@vahost)

    Thanks for your help, thaikolja. I think I have it now. I made a couple of modifications, and it works the way I intended. Here’s what I have:

    /**
    	 * @param int $post_id
    	 * @param int $showposts
    	 *
    	 * @return array
    	 */
    	function get_posts_from_this_category($post_id = 0, $showposts = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		/** Get the category/categories that belong(s) to the post */
    		$post_categories_ids = wp_get_post_categories($post_id);
    		$posts = array(
    			get_post($post_id)
    		);
    		/** Get all posts in that/these category/categories */
    		$category_posts = get_posts(array(
    			"orderby"      => "date", // Actually you don't have to set this and...
    			"order"        => "DESC", // ...this since it's the default value anyway.
    			"category__in" => $post_categories_ids,
    			"posts_per_page" => $showposts,
    			"date_query"   => array(
    				"before" => (array(
    						"year"  => get_the_date("Y", $post_id),
    						"month" => get_the_date("m", $post_id),
    						"day"   => get_the_date("d", $post_id)
    					))
    			)
    		));
    		/** Add the posts to the output array */
    		foreach($category_posts as $category_post) {
    			$posts[] = $category_post;
    		}
    		/** Show all posts if $showposts is not set */
    		if(!$showposts) {
    			$showposts = count($posts);
    		}
    		/** Reduce posts according to $showposts */
    		$posts = array_splice($posts, 0, $showposts);
    
    		return $posts;
    	}
    
    	/**
    	 * @param int $post_id
    	 * @param int $showposts
    	 */
    	function the_posts_from_this_category_links($post_id = 0, $showposts = 0) {
    		if(!$post_id) {
    			$post_id = get_the_ID();
    		}
    		$posts = get_posts_from_this_category($post_id, $showposts);
    		echo "<ul>";
    		foreach($posts as $post) {
    			if($post->ID != $post_id) {
    				echo "<li>";
    				echo '<a href="' . get_permalink($post->ID) . '">';
    				echo get_the_title($post->ID);
    				echo "</a>";
    				echo "</li>";
    			}
    		}
    		echo "</ul>";
    	}

    Glad to hear that.

Viewing 9 replies - 1 through 9 (of 9 total)
  • The topic ‘Modify popular_posts_per_category function’ is closed to new replies.