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.
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'], "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.