How to get permalinks with category base working with sub-categories

I was able to get this to work pretty easily actually. I am now able to have my category base in my permalinks. This allows me to now have URLs like:

http://www.new1450.dev/industries/ {Main blog post only showing category selection}
http://www.new1450.dev/industries/development/ {a parent category}
http://www.new1450.dev/industries/development/parent-category-i/ {child of parent}
http://www.new1450.dev/industries/development/parent-category-i/child-category-i/ {child of child}
http://www.new1450.dev/industries/development/parent-category-i/child-category-i/some-cool-post/ {actual post}

This should work for any level of category nesting.

My Permalink settings:

Custom Structure: /industries/%category%/%postname%/

Category base: industries/. (/. is required as it prevents 404s for post)

Code:

/**
 * Fix 404 for permalinks using category_base
 */
function permalinkWithCategoryBaseFix() {
    global $wp_query;
    // Only check on 404's
    if ( true === $wp_query->is_404) {
        $currentURI = !empty($_SERVER['REQUEST_URI']) ? trim($_SERVER['REQUEST_URI'], "https://wordpress.stackexchange.com/") : '';
        if ($currentURI) {
            $categoryBaseName = trim(get_option('category_base'), '/.'); // Remove / and . from base
            if ($categoryBaseName) {
                // Perform fixes for category_base matching start of permalink custom structure
                if ( substr($currentURI, 0, strlen($categoryBaseName)) == $categoryBaseName ) {
                    // Find the proper category
                    $childCategoryObject = get_category_by_slug($wp_query->query_vars['name']);
                    // Make sure we have a category
                    if (is_object($childCategoryObject)) {
                        $paged = ($wp_query->query_vars['paged']) ? $wp_query->query_vars['paged']: 1;
                        $wp_query->query(array(
                                              'cat' => $childCategoryObject->term_id,
                                              'paged'=> $paged
                                         )
                        );
                        // Set our accepted header
                        status_header( 200 ); // Prevents 404 status
                    }
                    unset($childCategoryObject);
                }
            }
            unset($categoryBaseName);
        }
        unset($currentURI);
    }
}

add_action('template_redirect', 'permalinkWithCategoryBaseFix');

I originally had:

$childCategoryObject = get_category_by_slug( ((!empty($wp_query->query_vars['page']) && $wp_query->query_vars['page'] > 1) ? $wp_query->query_vars['category_name'] : $wp_query->query_vars['name']) );

in place of:

$childCategoryObject = get_category_by_slug($wp_query->query_vars['name']);

but it seems that check wasn’t necessary. I left this comment in case I had it for a reason I couldn’t remember…

Also, I had issues with my default category pagination… A quick search returns many people with the same issue (won’t go past page 2) so I added this fix too. I found this fix in a WordPress plugin: Category pagination fix. I updated the code and the fix is below:

/**
 * Fix the problem where next/previous of page number buttons are broken of posts in a category when the custom permalink
 * The problem is that with a url like this:
 * /categoryname/page/2
 * the 'page' looks like a post name, not the keyword "page"
 */
function fixCategoryPagination($queryString) {
    if (isset($queryString['name']) && $queryString['name'] == 'page' && isset($queryString['page'])) {
        unset($queryString['name']);
        // 'page' in the query_string looks like '/2', so i'm exploding it
        list($delim, $page_index) = explode("https://wordpress.stackexchange.com/", $queryString['page']);
        $queryString['paged'] = $page_index;
    }
    return $queryString;
}

add_filter('request', 'fixCategoryPagination');

Note: It should be noted, the pagination fix was only necessary on the parent categories. The child categories had no issue with pagination.

Leave a Comment