admin管理员组文章数量:1393584
I had a site with a url structure like
example/news/story-1
example/news/local/story-2
example/food/tacos/story-3
Now it's been moves to a multisite, with /news/ and /food/ as the site subfolders.
Within those sub-sites, the top level category is News or Food, respectively. So if the permalink is set to /%category%/%postname%/
, the permalink come out as
example/news/news/local/story-title
example/food/food/tacos/story-title
In order to remove the category that's a duplicate of the site subfolder, I added this to functions.php:
add_filter( 'post_link', 'remove_parent_category', 10, 3 );
function remove_parent_category( $permalink, $post, $leavename ) {
$permalink_array = explode("/", $permalink);
$clean_permalink = array_unique($permalink_array);
$new_permalink = implode("/", $clean_permalink);
return $new_permalink;
}
This works, giving me back
example/news/local/story-2
example/food/tacos/story-3
and the ability to navigate to
example/news/
example/news/local
etc.
However posts that are in the top level category now 404 (which I suppose is to be expected) because their url is now
example/news/story-1
(which is what I want).
From what I'm gathering I think I need to use either pre_post_link or a rewrite rule to treat those top level posts as if my permalink structure is just %postname%/
, but that's where I'm stuck.
UPDATE: Solved (I think?)
T.Todua's answer below got me started:
- posts in child categories work
- category and sub-category archives work
- pages work
but posts that had their last category stripped (posts in the top-most category) were still 404ing.
After much poking around with WP Rewrite and discovering that the way I thought I'd be able to solve this would not work, it did lead me down another path.
It turns out these "naked" posts with no category were hitting the category rule in WP Rewrite — so the query ended up being category_name = this-is-the-slug-for-a-post
. There was no way (at least that I could figure out) to prevent this in WP Rewrite, since there's no way to tell the difference between a category slug and a post slug using RegEx.
(Though I am wondering how, if your permalink structure is just %postname%/
, Wordpress differentiates between a page and a post. If anyone knows, I'd be interested.)
From there I found this post and modified it to my needs. It catches category requests and checks if there's a real category with that name. If not, it converts it to a post query.
The whole thing is below: please let me know if you see any major red flags or problems down the road with this approach.
add_filter('post_link','remove_parent_category', 10, 3 );
add_filter('post_type_link','remove_parent_category', 10, 3 );
add_filter('category_link','remove_parent_category', 10, 2);
function remove_parent_category($termlink, $term_id )
{
return implode("/", array_unique(explode("/", $termlink)));
}
add_filter('request', function(array $query_vars) {
// do nothing in wp-admin
if(is_admin()) {
return $query_vars;
}
// if the query is for a category
if(isset($query_vars['category_name'])) {
$query_cat = $query_vars['category_name'];
// if it's a real category do nothing
if(term_exists($query_cat, "category")) {
return $query_vars;
};
// save the slug
$postname = $query_vars['category_name'];
// completely replace the query with a post query
$query_vars = array('name' => "$postname");
}
return $query_vars;
});
I had a site with a url structure like
example/news/story-1
example/news/local/story-2
example/food/tacos/story-3
Now it's been moves to a multisite, with /news/ and /food/ as the site subfolders.
Within those sub-sites, the top level category is News or Food, respectively. So if the permalink is set to /%category%/%postname%/
, the permalink come out as
example/news/news/local/story-title
example/food/food/tacos/story-title
In order to remove the category that's a duplicate of the site subfolder, I added this to functions.php:
add_filter( 'post_link', 'remove_parent_category', 10, 3 );
function remove_parent_category( $permalink, $post, $leavename ) {
$permalink_array = explode("/", $permalink);
$clean_permalink = array_unique($permalink_array);
$new_permalink = implode("/", $clean_permalink);
return $new_permalink;
}
This works, giving me back
example/news/local/story-2
example/food/tacos/story-3
and the ability to navigate to
example/news/
example/news/local
etc.
However posts that are in the top level category now 404 (which I suppose is to be expected) because their url is now
example/news/story-1
(which is what I want).
From what I'm gathering I think I need to use either pre_post_link or a rewrite rule to treat those top level posts as if my permalink structure is just %postname%/
, but that's where I'm stuck.
UPDATE: Solved (I think?)
T.Todua's answer below got me started:
- posts in child categories work
- category and sub-category archives work
- pages work
but posts that had their last category stripped (posts in the top-most category) were still 404ing.
After much poking around with WP Rewrite and discovering that the way I thought I'd be able to solve this would not work, it did lead me down another path.
It turns out these "naked" posts with no category were hitting the category rule in WP Rewrite — so the query ended up being category_name = this-is-the-slug-for-a-post
. There was no way (at least that I could figure out) to prevent this in WP Rewrite, since there's no way to tell the difference between a category slug and a post slug using RegEx.
(Though I am wondering how, if your permalink structure is just %postname%/
, Wordpress differentiates between a page and a post. If anyone knows, I'd be interested.)
From there I found this post and modified it to my needs. It catches category requests and checks if there's a real category with that name. If not, it converts it to a post query.
The whole thing is below: please let me know if you see any major red flags or problems down the road with this approach.
add_filter('post_link','remove_parent_category', 10, 3 );
add_filter('post_type_link','remove_parent_category', 10, 3 );
add_filter('category_link','remove_parent_category', 10, 2);
function remove_parent_category($termlink, $term_id )
{
return implode("/", array_unique(explode("/", $termlink)));
}
add_filter('request', function(array $query_vars) {
// do nothing in wp-admin
if(is_admin()) {
return $query_vars;
}
// if the query is for a category
if(isset($query_vars['category_name'])) {
$query_cat = $query_vars['category_name'];
// if it's a real category do nothing
if(term_exists($query_cat, "category")) {
return $query_vars;
};
// save the slug
$postname = $query_vars['category_name'];
// completely replace the query with a post query
$query_vars = array('name' => "$postname");
}
return $query_vars;
});
Share
Improve this question
edited Jul 8, 2019 at 7:09
Dennis
asked Jun 26, 2019 at 8:57
DennisDennis
731 silver badge6 bronze badges
5
- What I've tried: among other things I tried a variation on this but the post links without a category still 404 wordpress.stackexchange/a/133587/170714 – Dennis Commented Jun 27, 2019 at 0:13
- I'm sure there's a way to do this, but maybe it would worth considering just removing those top-level categories and moving the posts into the sub-categories? if "News" is already in the URL path, and presumably all the posts in that multisite sub-site are News related, why keep it as a category at all? You could move posts by briefly using a plugin like this: wordpress/plugins/bulk-move – Michelle Commented Jul 1, 2019 at 20:40
- I'd considered that but some things are too broad or don't fit neatly into a sub-category — I've set the top-level category ("News") as the default category (replacing "uncategorized"), which is why I've been looking for parallel questions related to removing "/uncategorized/" from the permalink, but none of those solutions seem to work. – Dennis Commented Jul 1, 2019 at 20:58
- I've played around and I think the problem is the /%postname%/ type permalink you're wanting for the News category (ie no category slug included) is what's used for WordPress "Pages", so WP isn't finding the single Post correctly. I'm not sure how to get around that. Another workaround (not what you want I know) would be to change just the slug of the News category to be something like 'general' or 'all' or 'stories'... not ideal based on your question but probably more future-proof than messing with WP core behavior. – Michelle Commented Jul 1, 2019 at 23:57
- I think that's what's happening too, but if you have your permalink structure set to just /%postname%/, it doesn't differentiate, site/page-1 and site/post-1 both work. I get what you're saying about changing the category slugs, and I can do that as a last-ish resort / temporary fix but the site's been around for a long time with the category structure I'd mentioned. – Dennis Commented Jul 2, 2019 at 4:35
1 Answer
Reset to default 2I think, there are two things to be resolved:
1) You need that posts (and other post types) also followed that command, so use both:
add_filter( 'post_link', 'remove_parent_category', 10, 3 );
add_filter( 'post_type_link', 'remove_parent_category', 10, 3 );
2) but then categories also need to have changed url, so use:
add_filter( 'category_link', 'remove_parent_category_2', 10, 2);
function remove_parent_category_2($termlink, $term_id )
{
return implode("/", array_unique(explode("/", $termlink)));
}
after that, go to SETTINGS > PERMALINKS > SAVE and see if it works.
btw, what I suggest, is (after backup of database) just to remove those categories from categories at all (from WP dashboard > categories), and WP will do everything itself, without need for custom codes.
本文标签: filtersRemove the Parent category from the permalink but leave the child category
版权声明:本文标题:filters - Remove the Parent category from the permalink but leave the child category 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744764590a2623961.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论