[SOLVED] Custom post type with categories

This isn’t especially Roots related, but I’d like to get answers here to make sure I’m using any Roots specific features/not messing up the wrapper too much.

Let’s say I have a list of publications and a list of blog posts. The publications are a custom post type. They both share categories. So far I have got the publication archive to work by creating archive-publications.php which will show all publications. But I need to display them by category so I’ve created a wp_list_categories function that will only display categories used by publications. Unfortunately these just link to the blog section.

Normal behaviour is as follows:

But when in the publications section I’d like it to go:

So essentially there are two problems.

  1. How can I link to a category listing of only this custom post type, without messing up the other one?
  2. How can I make that use the same template as archive-publications.php?


(If you’re at all confused about what problem I"m having just check out this stackoverflow link of someone else with the same question that was never answer (but ignore the term stuff))

Hi @matthewlyle,

I feel like your only option would be custom rewrite rules. I did something vaguely similar for a project a couple of month ago and this article helped me conceptualize it.

The gist is if you go to localhost/?post_type=publications&category=cat1 you should see only publications in cat1. So you can create a rewrite rule like so

function proj_add_rewrite_rules() {
    global $wp_rewrite;
    $new_rules = array(
        'publications/category/(.+)/?$' => 'index.php?post_type= publications&category=' . $wp_rewrite->preg_index(1)
    $wp_rewrite->rules = $new_rules + $wp_rewrite->rules;
add_action( 'generate_rewrite_rules', 'proj_add_rewrite_rules' );

Then visit your Settings > Permalinks page to flush the rules.

If you don’t have category.php already, then I think it will use archive-publications.php. However, if you have category.php or plan to add it later, I am not sure which of the two will win and you may have to force WordPress to use the template file you’d like or add some conditionals to category.php to include the correct template

1 Like

@enollo Hm that seems like a pretty good solution. Although I’m a little concerned about the category.php page as that seems to win over the archive-publications for everything except the one specific archive page. Still, I’ll be looking at this one first for next time. Thank you.

I forgot to update here the other day when I “solved” this problem, but what I ended up doing was creating a custom taxonomy called publications_category that matched the other categories (I don’t require mixing the post types in any way), and then created taxonomy-publications_category.php. Then, to query only whatever category you’re trying to view I used:

// get the current term page by the last part of the url
$r = explode('/publication_category/', $r);
$r = array_filter($r);
$r = array_merge($r, array()); //reset keys
$term = $r[1];

where $term goes in the loop. Then wp_list_categories with the taxonomy set to publications_category to create the navigation for the section. This solution wasn’t perfect and isn’t as automated as I’d like, but since this project didn’t require more than 2 of these custom post types it’s fine. The urls ended up being localhost/publications/publications_category/whatever.

1 Like

I am glad you figured out a solution. I understood you wanted to use the default category taxonomy. With a custom taxonomy you don’t need to worry about the category.php template file and you can add a rewrite rule to change your url structure to ‘/publications/category/whatever’.

If your snippet there is only being used to get the term, you can try using get_query_var() instead

<?php $term = get_query_var('publication_category'); ?>

One thing I forgot to mention about is that you would filter the term link to reflect your new url structure
(in case you want to use this in the future)

function proj_filter_publication_category_term_link($termlink, $term, $taxonomy) {
   if ($taxonomy == 'publication_category') {
      // do stuff to $termlink to reflect your desired URL structure
   return $termlink;
add_filter('term_link', 'proj_filter_publication_category_term_link', 10, 3);
1 Like