Multiple Post Pages

Hello,

I’m curious as to what is the best way, using Sage, to solve the following use case.

I need to have two pages that display a series of blog posts, e.g. Blog page and About page.

On the “Blog” page I want to show all blog posts of Category X, Y, Z and on the “About” page I want to show the latest three blog posts from Category W.

I’d appreciate any advice on how to best achieve this and if there is any limitations I should be aware of.

Example 1: Is it as simple as creating x2 page templates, then creating two separate controllers with custom WP_Query’s that return posts of each given category? or is the a more eloquent way?

Example 2: Is it best to keep the Blog posts page as the regular Posts Page under Settings, then to create a custom post type for the About page and show the custom posts there?

Many Thanks.

Given that a blog page is already there to use, you can use pre_get_posts to filter out the categories you don’t want. Then, you can make a new page template and a controller to query the other selection of posts you want and output them.

Example 1 is more code than is necessary and if you use your custom template for blog and set it as your blog page, you’ll end up with multiple queries being ran (which you don’t want).
A custom post type for example 2 also isn’t necessary since you can just categorise your posts.

Hope that helps!

1 Like

Thank you.

Where is the best place to add the pre_get_posts logic? …in the controller?

public static function exclude_about() {         
        if (is_home()) {             
            $query->set( 'category_name', 'about' );
        }
    }
    add_action('pre_get_posts', __NAMESPACE__ . '\\exclude_about');

There isn’t any best place, it’s up to you. However, a Controller is not where you should place it as that is intended for passing data to templates.

No worries, is there a place you would recommend that best makes sense to add the logic? e.g. setup.php? would I new up an instance of WP_Query() to use or is there a better way to override the main query in Sage?

I would probably put it in the filter.php as the goal is to filter the categories used within the loop.

In pre_get_posts you work with the given WP_Query instance and don’t create a new one. There might be other plugins using that hook for various reasons.

To keep files light, in a recent Sage9 project we added another folder app/Filters and in this a file app/Filters/Loop.php

<?php

namespace App\Filters;

class Loop
{
    /**
     * Manipulate the main query.
     *
     * @param \WP_Query $query
     * @return void
     */
    public static function preGet($query): void
    {
        // avoid complication with other uses of WP_Query
        if (!$query->is_main_query() || is_admin()) {
            return;
        }

        if (is_home()) {
            // query manipulation
        }
    }
}

and in the app/filters.php only call it like so

add_action('pre_get_posts', [Filters\Loop::class, 'preGet']);
1 Like

This topic was automatically closed after 42 days. New replies are no longer allowed.