It seems WordPress breaks other rewrite rules when you use the character %
for rewrite slug of CPTs. Not sure why.
Anyway, I got it to work making the following changes in your code.
- Stop using
%
. It’s not required actually:
$rewrite = array(
'slug' => 'sector/service',
'with_front' => false // It has nothing to due with the solution, but you'd better put false here.
);
- Replace
/sector/
and/service/
instead of%sector%
and%service%
:
function rewrite_location_post_slug( $post_link, $post ) {
if ( $post->post_type == 'location' ) {
$terms_service = wp_get_object_terms( $post->ID, 'service' );
$terms_sector = wp_get_object_terms( $post->ID, 'sector' );
if ( $terms_service && $terms_sector ) {
$sector_replaced = str_replace( '/sector/', "/{$terms_sector[0]->slug}/", $post_link );
return str_replace( '/service/', "/{$terms_service[0]->slug}/", $sector_replaced );
}
}
return $post_link;
}
add_filter( 'post_type_link', 'rewrite_location_post_slug', 1, 2 );
So far so good. Now, if you flush your permalinks you’ll see that your contact page is back, but your site_url/sector/service/location/
is gone. That relates to the missing %
, so we have to add that custom rewrite rule we talked about in the comments, which is actually dangerous as it’s kind of a “fake pattern”:
function rewrite_sector_service_location_url() {
add_rewrite_rule( '^([^/]+)/([^/]+)/([^/]+)/?', 'index.php?location=$matches[3]', 'top' );
}
add_action( 'init', 'rewrite_sector_service_location_url' );
Flush your rewrite rules and you’ll see that now everything works.
It should work for you, but I’d recommend you to use a prefix for your sectors and/or services, so we could add a standard to our rewrite pattern.
[EDIT]
I’ll try to explain the solution if you chose adding prefixes to your terms.
Assume you chose the prefix sector to be given to all terms from the taxonomy sector
.
So if you had 2 terms: Chemical and Construction, their slugs by default would be chemical
and construction
. But following that prefix rule their slugs should be changed to sector-chemical
and sector-construction
, respectively. Btw, WordPress has a filter (https://developer.wordpress.org/reference/hooks/pre_insert_term/) which you could use to add the prefix automatically.
Using that prefix standard our rewrite rule should be changed to:
function rewrite_sector_service_location_url() {
add_rewrite_rule( '^(sector-[^/]+)/([^/]+)/([^/]+)/?', 'index.php?location=$matches[3]', 'top' );
}
add_action( 'init', 'rewrite_sector_service_location_url' );
The rule above makes sure we would match something like
http://example.com/sector-chemical/service/post-slug
and would never match other URLs like:
http://example.com/blog/page/2
.