Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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

?>
share|improve this question
    
What if you change &page= to &paged=? see this question for more information. –  Mike Madern May 13 '13 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 '13 at 13:48
add comment

1 Answer

up vote 1 down vote accepted

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');
share|improve this answer
    
Thanks Brady but still doesn't work! Can you suggest and tests that I could run? –  kdev May 13 '13 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. –  Brady May 13 '13 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 '13 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 –  Brady May 14 '13 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. –  Brady May 15 '13 at 10:52
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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