2

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>';

?>
2
  • What if you change &page= to &paged=? see this question for more information. May 13, 2013 at 13:41
  • Hi Mike, Thanks, but that doesn't seem to change things. I've updated the question to include your edit.
    – kdev
    May 13, 2013 at 13:48

1 Answer 1

2

I would say you need to add the following rewrite rule in your foreach loop:

add_rewrite_rule('^'.$pt_slug.'/category/(.+?)/page/?([0-9]{1,})/?','index.php?post_type='.$post_type.'&category_name=$matches[1]&paged=$matches[2]','top');
5
  • Thanks Brady but still doesn't work! Can you suggest and tests that I could run?
    – kdev
    May 13, 2013 at 16:54
  • Install monkeyman rewrite analyzer plugin, reload your permalink then go to wp-admin->tools->rewrite-analyzer and start typing in your url that you think should be paged by the above rewrite. It should show you rules that match.
    – Scott
    May 13, 2013 at 17:01
  • The rule that it shows is exactly the one that you suggested. Still no joy though. There must be something else going on.
    – kdev
    May 14, 2013 at 4:54
  • Can you add to your original question how you are adding your CPT's and any template file you are trying to use to show your content
    – Scott
    May 14, 2013 at 8:18
  • 1
    Also make sure you add the second rule in the right order to your first one so that the new rule has precedence over the original.
    – Scott
    May 15, 2013 at 10:52

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.