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 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.

share|improve this question
add comment

1 Answer 1

up vote 1 down vote accepted

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.

share|improve this answer
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.