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

I ran into an issue with a site that needs the category base also included in the custom permalink structure. I know this is an issue and I have read many posts like this that gave me some insight…

I need to get the permalinks to work like this:

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}

My permalink settings are:
Custom Structure:

/industries/%category%/%postname%/

Category Base:

industries/.

This gets me working with:

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-category-i/some-cool-post/ {actual post}

So it appears it’s just the child categories that pose a problem..

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}

I am able to get the category ID by intercepting the 404 but I cannot see how to load the categories page with the proper category ID.

So my question is: Is there a way to load the categories page by calling some internal command or will I have to write my own way of loading the categories page? I was hoping that I could use a WP function as this would be ideal. if this is the latter, is there anything special I need to be aware of? I do know I have to set: status_header(200); but wanted to know if there are any other headers or important steps that need to be taken.

Also, a redirect will not work for my purpose. I need to load the categories page with the new ID. If it helps, the hook I am using in WP to catch the 404 is: template_redirect

Thanks for any information you can provide on this subject.

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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'], '/') : '';
        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('/', $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.


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x