I have set up the following to create ‘pretty’ post type and category permalinks:
function kdev_add_category_rules() {
$post_types = array(
'kdev_photos',
'kdev_videos',
'kdev_articles'
);
foreach($post_types as $post_type) {
$pt_obj = get_post_type_object($post_type);
$pt_rewrite = $pt_obj->rewrite;
$pt_slug = $pt_rewrite['slug'];
add_rewrite_rule('^'.$pt_slug.'/category/([^/]*)/?','index.php?post_type='.$post_type.'&category_name=$matches[1]','top');
}
}
add_action( "init", "kdev_add_category_rules" );
This works great. When I visit sitename.com/photos/category/landscape/ I get all the ‘photos’ in the ‘landscape’ category.
Unfortunately, my pagination on these pages is broken.
I would like sitename.com/photos/category/landscape/page/2 to show the second page in this query. Currently it just refreshes the same page. On inspection of the query paged=1.
I’ve tried the following, but my knowledge of regex is poor.
add_rewrite_rule('^'.$pt_slug.'/category/([^/]*)/page/([^/]*)/?','index.php?post_type='.$post_type.'&category_name=$matches[1]&paged=$matches[2]','top');
What is the correct rewrite rule?
Progress
Interestingly, removing the first ‘add_rewrite_rule’ allows the new one to work (but obviuosly breaks all the other rewrites). I.e. /photos/category/test-category/page/2/ will work, but /photos/category/test-category/ won’t.
EDIT: Additional info
I have refreshed the permalinks loads!
On sitename.com/photos/category/landscape/page/2/, get_query_var('paged')
is returning 1
.
/category/test-category/page/2/ and /photos/page/2/ both work.
Post types being created using:
// Register Custom Post Type
function custom_post_type() {
$labels = array(
'name' => _x( 'Photos', 'Post Type General Name', 'text_domain' ),
'singular_name' => _x( 'Photo', 'Post Type Singular Name', 'text_domain' ),
'menu_name' => __( 'Photos', 'text_domain' ),
'parent_item_colon' => __( 'Parent Photo:', 'text_domain' ),
'all_items' => __( 'All Photos', 'text_domain' ),
'view_item' => __( 'View Photos', 'text_domain' ),
'add_new_item' => __( 'Add New Photo', 'text_domain' ),
'add_new' => __( 'New Photo', 'text_domain' ),
'edit_item' => __( 'Edit Photo', 'text_domain' ),
'update_item' => __( 'Update Photo', 'text_domain' ),
'search_items' => __( 'Search photos', 'text_domain' ),
'not_found' => __( 'No photos found', 'text_domain' ),
'not_found_in_trash' => __( 'No photos found in Trash', 'text_domain' ),
);
$args = array(
'label' => __( 'kdev_photos', 'text_domain' ),
'description' => __( 'Shared photos', 'text_domain' ),
'labels' => $labels,
'supports' => array( 'title' ),
'taxonomies' => array( 'category', 'post_tag' ),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'show_in_nav_menus' => true,
'show_in_admin_bar' => true,
'menu_position' => 5,
'menu_icon' => '',
'can_export' => true,
'has_archive' => true,
'rewrite' => array( 'slug' => 'photos' ),
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'page',
);
register_post_type( 'kdev_photos', $args );
}
The site is using the Roots theme which uses Scribu’s theme wrapper technique.
The first template called is base.php:
<?php if(is_front_page()) {
wp_redirect( get_bloginfo('url').'/photos/', 302 );
exit;
} ?>
<?php get_template_part('templates/head'); ?>
<?php
$post_type_query = get_query_var( 'post_type' );
if(!is_array($post_type_query)) $post_type = $post_type_query;
?>
<body <?php body_class($post_type); ?>>
<?php
do_action('get_header');
// Use Bootstrap's navbar if enabled in config.php
if (current_theme_supports('bootstrap-top-navbar')) {
get_template_part('templates/header-top-navbar');
} else {
get_template_part('templates/header');
}
?>
<div class="wrap container" role="document">
<div class="content row">
<div class="main <?php echo roots_main_class(); ?>" role="main">
<?php include roots_template_path(); ?>
</div><!-- /.main -->
<?php if (roots_display_sidebar()) : ?>
<aside class="sidebar <?php echo roots_sidebar_class(); ?>" role="complementary">
<div class="well">
<?php include roots_sidebar_path(); ?>
</div>
</aside><!-- /.sidebar -->
<?php endif; ?>
</div><!-- /.content -->
</div><!-- /.wrap -->
<?php get_template_part('templates/footer'); ?>
</body>
</html>
Which then calls index.php:
<?php get_template_part('templates/page', 'header'); ?>
<?php $paged = (get_query_var('paged')) ? get_query_var('paged') : 1; ?>
<h1>Currently Browsing Page <?php echo $paged; ?></h1>
<?php if (!have_posts()) : ?>
<div class="alert">
<?php _e('Sorry, no results were found.', 'roots'); ?>
</div>
<?php get_search_form(); ?>
<?php endif; ?>
<?php
$post_type_query = get_query_var( 'post_type' );
if($post_type_query == 'kdev_photos') $use_grid = TRUE; else $use_grid = FALSE; ?>
<?php
if($use_grid) echo '<ul class="thumbnails">';
while (have_posts()) : the_post();
if($use_grid) get_template_part('templates/content', 'photo');
else get_template_part('templates/content', get_post_format());
endwhile;
if($use_grid) echo '</ul>'; ?>
<?php
global $wp_query;
$big = 999999999; // need an unlikely integer
$pag_links = paginate_links( array(
'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
'format' => '?paged=%#%',
'end_size' => 1,
'mid_size' => 1,
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
) );
echo '<div class="pagination">'.$pag_links.'</div>';
?>
I would say you need to add the following rewrite rule in your foreach loop: