0

I'm fairly new to posting here and I'll try to keep it as clear as possible! Any guidance is greatly appreciated!

The Goal:


I am trying to create a Custom Post Type and a Taxonomy where I can upload posts inside the Taxonomy and have a URL structure like this: site-name.com/cpt-slug/taxonomy-slug/post-slu.

I also need to be able to have pagination on both site-name.com/cpt-slug/ and site-name.com/cpt-slug/taxonomy-slug

Currently:


I have studied a few other posts that have gotten me 99% of the way there! I just can't quite figure out how to finish it at this point. I have done most of what this answer has suggested and i will show my code below for clarity.

CPT registration

register_post_type( 'knowledge_base',
        array(
            'labels' => array(
                'name' => __( 'Knowledge Base' ),
                'singular_name' => __( 'Knowledge Base Post' )
            ),
            'public' => true,
            'has_archive' => true,
            'menu_position' => 25,
            'menu_icon' => 'dashicons-book',
            'hierarchical' => true,
            'supports' => array(
                'title',
                'editor',
                'excerpt',
                'page-attributes',
                'thumbnail'
            ),
            'taxonomies' => array('kb_topics'),
            'rewrite' => array(
                'slug' => 'kb/%taxonomy_name%',
                'with_front' => false
            ),
        )
    );

Custom taxonomy registration

register_taxonomy(
        'kb_topics',
        'knowledge_base',
        array(
            'label' => 'Categories',
            'hierarchical' => true,
            'rewrite' => array(
                'slug' => 'kb',
                'with_front' => false
            ),
        )
    );

Tell WordPress how to interpret my knowledge base URL structure:

function add_rewrite_rules( $rules ) {
  $new = array();
  $new['kb/([^/]+)/(.+)/?$'] = 'index.php?knowledge_base=$matches[2]';
  $new['kb/(.+)/?$'] = 'index.php?kb_topics=$matches[1]';

  return array_merge( $new, $rules ); // Ensure our rules come first
}
add_filter( 'rewrite_rules_array', 'add_rewrite_rules' );

Handle the %taxonomy_name% URL placeholder

function filter_post_type_link( $link, $post ) {
  if ( $post->post_type == 'knowledge_base' ) {
    if ( $cats = get_the_terms( $post->ID, 'kb_topics' ) ) {
      $link = str_replace( '%taxonomy_name%', current( $cats )->slug, $link );
    }
  }
  return $link;
}
add_filter( 'post_type_link', 'filter_post_type_link', 10, 2 );

The problem:


Overall the post I referenced makes a ton of sense, I feel I understand whats going on here and everything was good until I tried setting up Pagination on the page site-name.com/kb.

This page was working great. I was able to show all the posts per category and I was able to go from here and click any post or Taxonomy and have the URL structure mentioned above. However whenever I try to go to the next page or third page I either get a 404 error or I get redirected to a post in my CPT.

As an example site-name.com/kb/page/2 always goes to the same post that is a post in my CPT and site-name.com/kb/page/3 always goes to 404. After some digging around some more I found another post that seemed to have a very promising answer and I still feel it could be the right answer I just can't get it to work. Admittedly I don't have a lot of experience with rewrites and this may be where the issue is.

Here is my version of this user's suggestion:

function fix_kb_category_pagination( $wp_rewrite ) {
    unset($wp_rewrite->rules['kb/([^/]+)/page/?([0-9]{1,})/?$']);
    $wp_rewrite->rules = array(
        'kb/?$' => $wp_rewrite->index . '?post_type=knowledge_base',
        'kb/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?post_type=knowledge_base&paged=' . $wp_rewrite->preg_index( 1 ),
        'kb/([^/]+)/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?kb_topics=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
    ) + $wp_rewrite->rules;
}
add_action( 'generate_rewrite_rules', 'fix_kb_category_pagination' );

I have tested the pagination and my page template by creating a different page with a slug of /kb-test/ and everything works perfectly. So this only happens on /kb/ for some reason.

From what I understand from the posts I mentioned above, WordPress has created rewrites based on the CPT and Taxonomy I set up and so its not able to go to /kb/page/, but I have tried many times now tweaking the code I have here trying to get it to recognize /kb/page/ but to no avail.

Thank you ahead of time to anyone who takes the time to look through this and respond. I really think I must be super close but just cant quite get the last bit alone. Thanks everyone!

**

UPDATE

**

First off thank you for everyone helping me format my question, much appreciated! I wanted to write a quick update to help answer this question for future viewers if I can.

After working on this more I now realize I was very close with the code above. One thing I had to do was remove the rewrite_rules_array hook. I assume because the rules were conflicting with the rules I have in the generate_rewrite_rules hook.

So that's great! However I still have one remaining issue i'm working on. For some reason when I go to site-name.com/kb/page/2/ it still goes to a post that is in the /kb/ CPT. Every other page seems to work great. site-name.com/kb/page/3/ and so on, all work correctly. I even deleted the post that /page/2/ is going to. It still goes to that same URL but now just shows 404.

I'll keep working on this and update when I figure it out. In the mean time if anyone has any tips to help with this i'd appreciate any help!

**

FINAL UPDATE

**

Turns out the last little issue of /page/2/ was a caching issue and all is good now. I will answer my question so we can close it out. Hopefully this helps anyone in the future with this same issue!

RedBeard
  • 11
  • 2

2 Answers2

0

To anyone running into issues with this I hope my experiences help! Here are the steps I believe you need to follow to get it working correctly:

Custom Post Type Registration - Include rewrite structure like this (kb being whatever slug you want in URL for CPT)

'rewrite' => array(
                'slug' => 'kb/%taxonomy_name%',
                'with_front' => false
            ),

Custom Taxonomy Registration - Include rewrite structure (same as slug above)

'rewrite' => array(
                'slug' => 'kb',
                'with_front' => false
            ),

Include this hook to tell Wordpress how to handle %taxonomy_name% in your CPT registration (for me "knowledge_base" is my CPT name, and "kb_topics" is my taxonomy name. Replace these as necessary throughout)

function filter_post_type_link( $link, $post ) {
  if ( $post->post_type == 'knowledge_base' ) {
    if ( $cats = get_the_terms( $post->ID, 'kb_topics' ) ) {
      $link = str_replace( '%taxonomy_name%', current( $cats )->slug, $link );
    }
  }
  return $link;
}
add_filter( 'post_type_link', 'filter_post_type_link', 10, 2 );

Lastly you need to include some rewrites to fix the pagination

function fix_kb_category_pagination( $wp_rewrite ) {
    unset($wp_rewrite->rules['kb/([^/]+)/page/?([0-9]{1,})/?$']);
    $wp_rewrite->rules = array(
        'kb/?$' => $wp_rewrite->index . '?post_type=knowledge_base',
        'kb/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?post_type=knowledge_base&paged=' . $wp_rewrite->preg_index( 1 ),
        'kb/([^/]+)/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?kb_topics=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
    ) + $wp_rewrite->rules;
}
add_action( 'generate_rewrite_rules', 'fix_kb_category_pagination' );

TIP: One last tip, in order to use a page template for site-name.com/kb/ you need to create a template in the back end with the filename of archive-knowledge_base.php, replacing knowledge_base with your CPT name.

That's it! I hope this helps others in the future maybe not run into the same issues I did. Good luck and happy coding!

RedBeard
  • 11
  • 2
0

Use this code below:

function column_custom_rewrite_basic( $wp_rewrite ) {
    unset($wp_rewrite->rules['column/([^/]+)/page/?([0-9]{1,})/?$']);
    $feed_rules = array(
        'column/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?post_type=column&paged=' . $wp_rewrite->preg_index( 1 ),
        'column/([^/]+)/page/?([0-9]{1,})/?$' => $wp_rewrite->index . '?tax_column_category=' . $wp_rewrite->preg_index( 1 ) . '&paged=' . $wp_rewrite->preg_index( 2 ),
        'column/(.+)/(.+)/?$' => $wp_rewrite->index . '?post_type=column&tax_column_category=' . $wp_rewrite->preg_index( 1 ) . '&name=' . $wp_rewrite->preg_index( 2 ),
        'column/(.+)?/?$' => $wp_rewrite->index . '?post_type=column&tax_column_category=' . $wp_rewrite->preg_index( 1 ),
    );

    $wp_rewrite->rules = $feed_rules + $wp_rewrite->rules;
    return $wp_rewrite->rules;
}

add_filter('generate_rewrite_rules', 'column_custom_rewrite_basic');
Steven
  • 1,996
  • 3
  • 22
  • 33