skip to Main Content

Using Timber, I’m trying to render a custom archive page for my custom post type. CPT is person, and I’m simply trying to render archive-person.php when visiting “mysite.com/person”. No matter what I do, all I get is the output of archive.php, never archive-person.php.

Yes, I have been hitting ‘Save’ on permalinks as many people suggest.

As a test, using WP’s 2020 base theme, I made an equivalent archive-post_type.php in the classic WordPress way, and everything works fine. This is indicating my cpt’s and permalinks are ok, and the issue perhaps has to do with my Timber-based theme specifically.

I’ve tried changing my CPT name properties to make sure I’m not creating permalink conflicts.

Timber views/partials, pages, singles and single-post_type.php are all rendering fine.

Other than tinkering with archive*.php pages, what’s the first thing I should be looking at? Within functions.php Timber initialization, anything major that would specifically affect archives only?

UPDATE: In writing this post I see what could be an issue. Do I have to register my CPTs and taxonomies explicitly through Timber init, for it to be fully aware of them?

archive.php (very similar to one from Timber starter theme)

<?php

use TimberTimber;

global $paged;

if ( ! isset( $paged ) || ! $paged ) {
    $paged = 1;
}

$templates = array( 'pages/archive.twig', 'pages/index.twig' );

$context = Timber::context();
$context['title'] = 'Archive';
if ( is_day() ) {
    $context['title'] = 'Archive: ' . get_the_date( 'D M Y' );
} elseif ( is_month() ) {
    $context['title'] = 'Archive: ' . get_the_date( 'M Y' );
} elseif ( is_year() ) {
    $context['title'] = 'Archive: ' . get_the_date( 'Y' );
} elseif ( is_tag() ) {
    $context['title'] = single_tag_title( '', false );
} elseif ( is_category() ) {
    $context['title'] = single_cat_title( '', false );
    array_unshift( $templates, 'archive-' . get_query_var( 'cat' ) . '.twig' );
} elseif ( is_post_type_archive() ) {
    $context['title'] = post_type_archive_title( '', false );
    array_unshift( $templates, 'archive-' . get_post_type() . '.twig' );
}

// Grabs everything on the site, regular posts and CPT's.
$context['posts'] = new TimberPostQuery();

    // Just for testing, to check if "person" posts can at least be rendered via archive.php. They do.
    //$args    = ['post_type' => 'person'];
    //$context['posts'] = new TimberPostQuery($args);

Timber::render( $templates, $context );

?>

archive-person.php Just a pared-down version of archive.php, with ‘person’ forced as post_type (as opposed to grabbing all posts):

use TimberTimber;

global $paged;

if ( ! isset( $paged ) || ! $paged ) {
    $paged = 1;
}

$templates = array( 'pages/archive-person.twig' );

$context = Timber::context();
$context['title'] = 'Archive: Person';

$args    = [
    'posts_per_page' => 10,
    'paged'          => $paged,
    'post_type' => 'person',
];

$context['posts'] = new TimberPostQuery($args);

Timber::render( $templates, $context );

functions.php

class mySite extends TimberSite {
    public function __construct() {
        add_theme_support( 'post-thumbnails' );
        add_theme_support( 'menus' ); 

        add_filter( 'timber_context', array( $this, 'add_to_context' ) );
        parent::__construct();
    }

    function add_to_context( $context ) {
        $context['menu'] = new TimberMenu('main-menu');
        $context['site'] = $this;

        return $context;
    }
}

new mySite();

function create_posttypes() {

      register_post_type( 'person',
            array(
                'labels' => array(
                    'name' => __( 'Persons' ),
                    'singular_name' => __( 'Person' )
                ),
                'public' => true,
                'has_archive' => true,
                'show_in_rest' => true,
                'supports' => array( 'title', 'editor', 'author', 'thumbnail', 'excerpt', 'trackbacks', 'custom-fields', 'comments', 'revisions', 'page-attributes' )
            )
        );

}

add_action( 'init', 'create_posttypes' );

2

Answers


  1. what you did seems enough to me, however add this to your functions.php to force the identification of your new post type

    add_action('init', 'person_archive_rewrite');
    
    function person_archive_rewrite(){
       add_rewrite_rule('^person/?','index.php?post_type=person','top');
    }
    

    then hit save permalink

    keep me updated

    Login or Signup to reply.
  2. Would you be able to add the code you wrote to register your custom post type ‘person’? The default archive setting has_archive is false when you register a CPT – make sure that’s set to true. https://developer.wordpress.org/reference/functions/register_post_type/#has_archive

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search