zeshan-a
12/20/2017 - 4:55 PM

PHP Rewrite Rule - Fix Pagination of Page Same Slug as CPT Rewrite Slug

Fix pagination of page with same slug as of CPT's rewrite slug. This function will fix the same slug conflict of CPT and a static page with pagination.

<?php // Don't copy this line...

/**
 * This function will Kill 'blogs/editor' rewrite rules
 * to fix the broken pagination issue on this page:
 * '/blogs/editor/'
 *
 * This fix was needed because we add rewrite rules for CPT: editor
 * And because '/blogs/editor/' is also a static page, the pagination
 * on that page e.g., '/blogs/editor/page/4/' was broken. 
 *
 * What I did here is to change priority of rewrite rules served
 * by WordPress so my custom rewrite rule takes precedence over 
 * other rules. 
 * 
 * To get it to work:
 * 
 * $cpt_slug     = CPT slug.
 * $rewrite_slug = rewrite slug of the conflicting CPT and page. 
 * 
 * Author: Zeshan Ahmed @zeshanshani22
 * Author URI: https://zeshanahmed.com/
 */
add_filter('rewrite_rules_array', 'za_kill_blogs_editor_rules');
function za_kill_blogs_editor_rules( $rules ) {
  $cpt_slug = 'editor';
  $rewrite_slug = 'blogs/editor';

  $blog_editor_rules = [
    // Fix page archives
    "{$rewrite_slug}/page/?([0-9]{1,})/?$" => "index.php?pagename={$rewrite_slug}&paged=$matches[1]", // My custom rule. Added first so it takes precedence
    "{$rewrite_slug}/([^/]+)(?:/([0-9]+))?/?$" => "index.php?$cpt_slug=$matches[1]&page=$matches[2]" // Original rule that we need to kill
  ];

  foreach ( $rules as $rule => $rewrite ) {
    // Killing the original rule here after matching it. 
    if ( false !== strpos( $rule, "{$rewrite_slug}/([^/]+)(?:/([0-9]+))?/?$" )  ) {
      unset( $rules[ $rule ] ); 
    }
  }

  $rules = array_merge( $blog_editor_rules, $rules );

  return $rules;
}