You could filter 'term_link'
.
just an untested idea, written directly into the answer field
add_filter( 'term_link', 'wpse_55476_categore_ur_filter', 10, 3 );
function wpse_55476_categore_ur_filter( $termlink, $term, $taxonomy )
{
if ( 'category' !== $taxonomy )
{
return $termlink;
}
// separate the URL
$parts = explode( "https://wordpress.stackexchange.com/", $termlink );
// get the term
$term_slug = array_pop( $parts );
$out = array ();
$cat_base = get_option( 'category_base', 'category' );
foreach ( $parts as $part )
{
$out[] = $part;
if ( $part === $cat_base )
{
$out[] = $term_slug;
return implode( "https://wordpress.stackexchange.com/", $out ) . '/;
}
}
}
Something like this should work each time a theme or a plugin calls a WP function that generates a category link, because all these functions delegate their work to get_term_link()
where this filter is called.
So … part one is solved, part two of your question is: What happens if someone calls the long URL? You could hook into 'wp'
and perform the same check (old example). Could be too slow, so the short term link should be stored in a term meta field. Oh, wait … there is no table for that, because … uhm … decisions. 🙂
But we have some solutions for this too. No need to repeat those here.
Alternative: .htaccess and RedirectMatch
If you have just a controlled and limited set of subcategories (and do not want to change the category
part) use Apache’s mod_alias
and a simple redirect in your .htaccess
or .httpd.conf
:
RedirectMatch Permanent ^/category/([^/]*)/(audio|video|smell)/(.*) /category/$2/$3
The (audio|video|smell)
is a list of your child categories. This rule should be above the WordPress rewrite rules.