I am trying to set up a multi-level custom post type structure with permalinks that look like authors/books/chapters
, with authors, books, and chapters all set up as their own custom post type. For example, a typical URL on this site might look like example.com/authors/stephen-king/the-shining/chapter-3/
Each chapter can only belong to one book, and each book can only belong to one author. I've considered using taxonomies instead of CPTs for authors and books, but I need to associate metadata with each item and I prefer the post interface for this.
I'm most of the way there by simply setting up each custom post as a child of an entry in the CPT one level up. For example, I create "Chapter 3" and assign "The Shining" as a parent using a custom meta-box. "The Shining" in turn has "Stephen King" as a parent. I haven't had any trouble creating these relationships.
I'm using rewrite tags in the CPT slugs and the permalinks want to work, but they're not quite right. Using a re-write analyzer, I can see that the rewrite rules are actually generated, but they don't seem to be in the right order and so other rules are processed first.
Here's how I've registered my CPTs:
function cpt_init() {
$labels = array(
'name' => 'Authors'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author',
'with_front' => FALSE,
),
'with_front' => false,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('authors',$args);
$labels = array(
'name' => 'Books'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author/%authors%',
'with_front' => FALSE,
),
'with_front' => false,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('books',$args);
$labels = array(
'name' => 'Chapters'
);
$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'show_in_menu' => true,
'query_var' => true,
'rewrite' => array(
'slug' => 'author/%authors%/%books%',
'with_front' => FALSE,
),
'with_front' => FALSE,
'capability_type' => 'post',
'has_archive' => false,
'hierarchical' => true,
'menu_position' => null,
'supports' => array( 'title', 'editor' )
);
register_post_type('chapters',$args);
}
add_action( 'init', 'cpt_init' );
So is there any way to change the priority of my rewrite rules so that authors, books, and chapters are all matched first?
I also know that I'm going to have to add a post_type_link
filter, but that seems secondary to getting the permalinks right in the first place. If anyone knows where I can find a comprehensive overview of how that filter works, it would be appreciated.