How can I create an entirely new, separate display of posts?

Here’s what I ended up with:

  • Everything within my child-theme
  • file example-single.php for displaying individual posts within a template
  • file example.php a new template as a destination for new routes.
  • new routes and a filter on ‘pre_get_posts’

All of the following can simply go in functions.php in the child theme:

function example_routes() {
    // add "/example/" routes
    add_rewrite_rule(
        '^example/(\d+)[/]?$', // for "/example/42" paging of posts
        'index.php?example=1&number=$matches[1]',
        'top'
    );
    add_rewrite_rule(
        '^example/?$',  // for "/example/" display of current posts
        'index.php?example=1&number=current',
        'top'
    );
}
add_action('init', 'example_routes'); // visit Permalinks pg to intialize

Next example and number are new query vars that need defining…

add_filter(
    'query_vars',
    function($query_vars) {
        $query_vars[] = 'example';
        $query_vars[] = 'number';
        return $query_vars;
    }
);

When to load that new example.php template file from the child theme…

add_action(
    'template_include',
    function($template) {
        if ( get_query_var('example') == false || get_query_var('example') == '' ) {
            return $template;
        }
        // get_stylesheet_directory() will path to the active child theme.
        // get_template_directory() does not.
        return get_stylesheet_directory() .'/example.php';
    }
);

Finally, modify the query when the template loads via the new routes. There’s also a calculation function (rather than simple inline code) because this calculation is also useful on the template’s page. The October 2022 dates in the code are the specific dates of posts for my particular use case.

function example_current_number() {
    $origin = new DateTimeImmutable('2022-10-09'); // the very first issue's pub date
    $today = new DateTimeImmutable(date('Y-m-d'));
    $interval = $origin->diff($today);
    $days = $interval->format('%a'); // %a is number of days
    return 1 +floor($days/7.0); 
}
add_action(
    'pre_get_posts',
    function($query) {

        // Query modification for "example" pages…
        if ( true == get_query_var('example') && $query->is_main_query() && !is_single() ) {
            $current = example_current_number();
            if ( 'current' == ($number=get_query_var('number')) ) {
                $number = $current;
                set_query_var('number', $number);
            }
            if ( $number > $current ) {
                $number = $current; // no peeking ahead
                set_query_var('number', $number);
            }
            $offset=" +".($number-1).' weeks';

            $query->set(
                'date_query',
                [[ // note array of arrays
                    'after' => '00:00 October 3, 2022'.$offset,
                    'before' => '23:59 October 9, 2022'.$offset,
                    'inclusive' => true
                ]]
            );
        }

        return $query;
    }
);

And then all-together it works like this, https://constantine.name/7-for-sunday/

ɕ