I have tried to apply the advice offered by TheDeadMedic in this post to achieve the following URL structure:
example.com/activities = a WP page
example.com/activities/type-term = a custom archive
example.com/activities/type-term/activity-post = a custom post
All URL's work until the lowest one which returns a Wordpress "not found" error.
I don't know whether I need to filter the rewrite rules to make this work. The post I linked above suggests that I have done everything needed.
Any help would be greatly appreciated, thanks. Here's my code:
/*
* Register custom content objects on initiation
*/
add_action('init', 'register_type'); // Type taxonomy (activities)
add_action('init', 'register_activity'); // Activity post-type
add_filter('post_type_link', 'filter_activity_link', 10, 2); // Filter permalinks for activity post-type
/*
* Register Type custom taxonomy for activities
*/
function register_type() {
$labels = array(
'name' => ('Types'),
'singular_name' => ('Type'),
'add_new' => ('Add New Type'),
'add_new_item' => ('Add New Type'),
'edit_item' => ('Edit Type'),
'new_item' => ('New Type'),
'view_item' => ('View Type'),
'search_items' => ('Search Type'),
);
$args = array(
'labels' => $labels,
'public' => true,
'query_var' => true,
'rewrite' => array( 'slug' => 'activities', 'with_front' => false ),
);
register_taxonomy( 'type', 'activity', $args );
}
/*
* Register Activity custom post-type
*/
function register_activity() {
$labels = array(
'name' => ('Activities'),
'singular_name' => ('Activity'),
'all_items' => ('All Activities'),
'add_new_item' => ('Add New Activity'),
'edit_item' => ('Edit Activity'),
'new_item' => ('New Activity'),
'view_item' => ('View Activity'),
'search_items' => ('Search Activities')
);
$args = array(
'labels' => $labels,
'public' => true,
'show_in_nav_menus' => false, // Do not appear directly in navigation
'menu_position' => 5,
'hierarchical' => false,
'query_var' => true,
'supports' => array( 'title', 'editor', 'type', 'revisions', 'comments' ),
'rewrite' => array( 'slug' => 'activities/%tax_type%', 'with_front' => false )
);
register_post_type( 'activity', $args );
}
/*
* Update Type rewrite slug with applicable terms
*/
function filter_activity_link($link, $post) {
if ($post->post_type != 'activity')
return $link;
if ($cats = get_the_terms($post->ID, 'type'))
$link = str_replace('%tax_type%', array_pop($cats)->slug, $link);
return $link;
}
UPDATE
OK, it turns out you will always need to add rewrite rules to finish this process. The URL's may appear correctly but the database doesn't understand them. This post helped me enormously, along with this reference information on regex.
I just needed to add the code
add_rewrite_rule('^activities/([^/]*)/([^/]*)/?$' ,'index.php?activity=$matches[2]','top';
Hope this helps someone.