Last active
December 10, 2023 02:22
-
-
Save neverything/7118663 to your computer and use it in GitHub Desktop.
WordPress: pre_get_posts filter to display one post per category. Displays the latest sticky post and therefore excludes the category of the sticky post as we only want one post per category.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Main Query for the Front Page | |
* | |
* Display the latest post per category. The latest sticky post goes to the | |
* top. It's category is then excluded as we only want 1 post per category. | |
* | |
* @param object $query WP_Query | |
*/ | |
function sh_pre_get_posts_front_page( $query ) { | |
// Check that we have the right query | |
if ( ( $query->is_front_page() || $query->is_home() ) && $query->is_main_query() ) { | |
// Set up the category ids and post ids arrays | |
$category_ids = array(); | |
$post_ids = array(); | |
// Get the sticky_posts array | |
$sticky_posts = get_option( 'sticky_posts' ); | |
// Check if we have sticky posts | |
if ( is_array( $sticky_posts ) ) { | |
// Give me the latest first | |
rsort( $sticky_posts ); | |
// Only 1 sticky post needed | |
$sticky_post = array_shift( $sticky_posts ); | |
// Get the cateogry of the sticky post | |
$sticky_post_categories = wp_get_post_categories( $sticky_post ); | |
} | |
// Set up category args | |
$category_args = array( 'parent' => 0 ); | |
// Exclude cateogry of the sticky post | |
if ( isset( $sticky_post_categories ) ) { | |
$category_args['exclude'] = join( ',', $sticky_post_categories ); | |
} | |
// Get parent categories | |
$categories = get_categories( $category_args ); | |
// Get category term_ids | |
foreach ( $categories as $category ) { | |
$category_ids[] = $category->term_id; | |
} | |
// Get post ID of latest post per category. | |
foreach ( $category_ids as $category_id ) { | |
if ( $cat_posts = get_posts( array( 'cat' => $category_id, 'posts_per_page' => 1 ) ) ) { | |
$first = array_shift( $cat_posts ); | |
$post_ids[] = $first->ID; | |
} | |
} | |
// Add the sticky post to the front of the array | |
if ( $sticky_post ) { | |
array_unshift( $post_ids, $sticky_post ); | |
} | |
// Set the additional query vars in the main Query. | |
$query->set( 'post__in', $post_ids ); | |
// We handle sticky posts already | |
$query->set( 'ignore_sticky_posts', 1 ); | |
// Preserver post__in array order | |
$query->set( 'orderby', 'post__in' ); | |
} | |
} | |
add_action( 'pre_get_posts', 'sh_pre_get_posts_front_page' ); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment