Black Friday Sale! Get up to $40 off GP Premium!Learn more

[Resolved] How can I create an custom post type archive by year?

Home Forums Support How can I create an custom post type archive by year?

Viewing 10 posts - 1 through 10 (of 10 total)
  • Author
    Posts
  • #503162
    Charles

    Hi Tom,

    My site is built from custom post types. I would like to build an archive page by year for each custom post type (that auto generates each year to include from the most current year to the first year that a post was published in that type).

    I have set all of my custom post types to 'has_archive' => 'true'. However, I’m confused by the documentation I’ve read so far. I understand that archives are built into WordPress as archive.php – but is that template used when someone manually sets a post to archive? If so, that’s not what I want.

    I’m also confused by the URLs. I know that if you create a page template called page-news.php you can view it at mysite.com/news/ – but I also see that if you create an archive page called archive-news.php it can be viewed at mysite.com/news which can’t be possible. And, if you go to mysite.com/archives there is a template with the title “Archives” generated, I presume from the parent theme. Where is that coming from? It’s not in archive.php.

    Should I forget the archive thing and just build a custom page template? Can you point me in the right direction?

    Thanks
    Charles

    #503366
    Tom
    Lead Developer
    Lead Developer

    Archives in WordPress are just pages that display a group of posts. So when you set your CPT to have an archive, it means WP will automatically provide a “page” where all of those posts in the CPT are listed.

    By default, it will use the archive.php template, but you can use your own templates if you name them after the CPT: https://developer.wordpress.org/themes/template-files-section/custom-post-type-template-files/

    As for the permalinks, I think you’re looking for the rewrite option. Check the “rewrite” section here: https://codex.wordpress.org/Function_Reference/register_post_type

    #504058
    Charles

    Thanks Tom,

    I sorted out that what I want is a custom template for my CPTs which I created by just making a page template and a content template as if it wasn’t an archive, and then adding a loop to pick up the dates and title links from each year. I still need to figure out how to make this auto-update because the current year is 'year' => $today["year"]-1 but then how does it know how many to go back to the first year when the first year is always one more than it was in January, if you follow me. If you have any idea how to do this please let me know.

    I made a critical mistake by having 'has_archive' => 'true' in the $labels array instead of the $args array. I eventually used the $args array outlined here. which added a lot of items that I didn’t have which might have made a difference.

    I also kept getting the permalinks buggy 404 error which I solved with the technique on the same page change %postname% to /%category%/%postname% save and then remove %category% and save again.

    Charles

    #504261
    Tom
    Lead Developer
    Lead Developer

    That first question might be one for stackoverlow. I haven’t done any queries like that before. How it $today defined?

    As for the permalinks, you can just hit the save button and it will flush the rewrites – no need to add the category bit.

    #506104
    Charles

    I tried WordPress Stack Exchange but didn’t get an answer so I’ll just go ahead and write it myself unless you know of an easier way to do this.

    I want something like this for the initial archive page.

    News CPT

    2018 News Posts
    2017 News Posts
    2016 News Posts

    …. etc. same for other CPT categories all on one page.

    I figure in pseudo-code it’s something like:

    I know the year of the oldest post
    I know the current year
    Create a counter and a loop to count how many years of links to display. But then I’m going to have to use a session or something to know which year to display on the content page.

    Here’s the code I’m using for each content page (news in this case):

    <?php $today = getdate();          
        $loop = new WP_Query( array( 
        'post_type' => 'news',
        'posts_per_page' => -1, 
        'year'  => $today["year"]
     ) ); ?>
     <?php while ($loop->have_posts()) : $loop->the_post(); ?>

    'posts_per_page' => -1, is all the posts.

    I think I incorrectly stated that -1 was the current year above. Actually, the current year is:
    'year' => $today["year"]
    One year previous is:
    'year' => $today["year"]-1
    Two years previous is:
    'year' => $today["year"]-2
    etc.

    It seems overly complicated for a simple archive by year but I don’t know how else to do it.

    Charles

    #506529
    Tom
    Lead Developer
    Lead Developer

    You should actually just be able to query the year: https://codex.wordpress.org/Class_Reference/WP_Query#Date_Parameters

    $loop = new WP_Query( array( 
        'post_type' => 'news',
        'posts_per_page' => -1, 
        'year'  => '2018'
     ) );
    #507016
    Charles

    Yes, I know that but it still doesn’t solve the problem of having to hand code the year as ‘2019’ next year.

    I’m thinking of abandoning this for now and just putting every link from a category on one long page, but at some point if there ends up being dozens of links it’s not practical to have one archive page with every article title in a category from the first to the most recent.

    Charles

    #507495
    Tom
    Lead Developer
    Lead Developer

    I’m sure it’s possible to do it automatically, but it would definitely take quite a bit of trial and error I think,

    Manually might be best for now. Perhaps there’s someone on Codeable you can hire to write the entire solution for you?

    Personally I would do this:

    $years = array(
        '2018',
        '2017',
        '2016',
        '2015',
    );
    
    foreach ( $years as $year ) {
        $loop = new WP_Query( array( 
            'post_type' => 'news',
            'posts_per_page' => -1, 
            'year'  => $year
        ) );
    
        // Other stuff.
    }

    That way you just need to add to the $years array as years go by.

    #507975
    Charles

    Sounds good. I think a loop of first and last is the way to go and then increment the last number of each year with it eventually, but you’re right, for now it’s easier to just do it the manual way. Thanks for your help.

    Charles

    #508135
    Tom
    Lead Developer
    Lead Developer
Viewing 10 posts - 1 through 10 (of 10 total)
  • You must be logged in to reply to this topic.