WordPress.org

Forums

Modify popular_posts_per_category function (10 posts)

  1. vahost
    Member
    Posted 11 months ago #

    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?

  2. thaikolja
    Member
    Posted 11 months ago #

    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.

  3. vahost
    Member
    Posted 11 months ago #

    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.

  4. thaikolja
    Member
    Posted 11 months ago #

    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.

  5. vahost
    Member
    Posted 11 months ago #

    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.

  6. thaikolja
    Member
    Posted 11 months ago #

    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"?

  7. vahost
    Member
    Posted 11 months ago #

    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.

  8. thaikolja
    Member
    Posted 11 months ago #

    Well, then change

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

    with

    $posts = array();

  9. vahost
    Member
    Posted 11 months ago #

    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>";
    	}
  10. thaikolja
    Member
    Posted 11 months ago #

    Glad to hear that.

Reply

You must log in to post.

About this Topic