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.