Sửa lỗi remove slug from custom post type năm 2024
I recently had a need to rewrite the URLs of all parent and child pages in a custom post type so that they appeared to live at the website root, but in reality, continued to live in a custom post type within their hierarchy. PrefaceThe situation:
The goal:
The reason:
SetupI have a custom post type setup like so:
SolutionRemove “services” from the custom post type URLWe’re going to use the
0 filter to do this. Update 1/19/14: Tweaked function to work with WordPress installed in a subdirectory.
All of this will essentially give us URLs like this:
But neither of those will work – you’ll get a 404 error – because WordPress can no longer identify those posts as
4 posts and therefore attempts to find pages called
8 and
1, which don’t exist, hence the 404 error. If you take a look at WordPress’ rewrite rules:
You’ll see something similar to this:
As you can see, using the
7 slug, WordPress knows to take whatever comes after it (
9 value (
0), which translates to something like:
1 Since the first rewrite rule no longer applies (slug removed), it now passes
2 in as the
9 without specifying the post type, and since this page doesn’t exist, WordPress can’t return the page. Add post type back to the post queryNow that WordPress doesn’t know that it’s dealing with a custom post type, we need to provide it with this information. For that we’re going to use the pre_get_posts hook.
Update 9/20/13: Changed
6 to
7 Update: 12/23/14: As of WordPress 4.0, the code above doesn’t work. The following changes need to be made:
ResultYou’ve met all your goals. In addition, if you try to create a page with the same name as one of your services, you’ll notice that the
8 (i.e.
9,
9, etc.) will now increment, avoiding a possible collision. Here are a couple of things to keep in mind:
If you have questions or suggestions, leave them in the comments below. Featured image by Eilis Garvey. Previously posted in WordPress and transferred to Ghost. Tristan C May 29, 2013 at 9:15 am Thanks for the post! Unfortunately I can’t get it to work… I keep on getting 404s. Have tried updating the permalinks,
Ryan Sechrest May 29, 2013 at 12:50 pm First, I would output the current WordPress rewrite rules (example in post), just to make sure the ones you added are indeed active. Second, I would print out the Marco Panichi July 7, 2013 at 8:34 am Hi Ryanm thank you very much for this article. I’m going mad with this slug!!! I’ve tried your solution but it doesn’t work. Maybe you can help me – I have this situation: Ryan Sechrest July 11, 2013 at 8:36 am When you go to the permalink that it’s supposed to be, what do you get? A page not found? GG July 8, 2013 at 3:34 am Man… as much as I want this to work its just not happening. Ryan Sechrest July 11, 2013 at 8:48 am Let’s systematically troubleshoot this. For step David July 14, 2013 at 11:43 pm To get this to work I had to change: AJ Clarke July 21, 2013 at 5:24 pm Works great, thanks man! kevin July 30, 2013 at 8:16 pm What are your thoughts about getting things running with WPMU, as of right now it would default the URL back to Ryan Sechrest July 31, 2013 at 9:30 pm You have a couple options. Tomas August 7, 2013 at 8:36 am Will this work with WPML, too? I’ve tried this plugin http://wordpress.org/plugins/remove-slug-from-custom-post-type/ but it only removes the slug for the main language… Ryan Sechrest August 7, 2013 at 8:55 am I do have MU enabled on the site that I did this on, however, I’m only applying this code on the main site and not child sites, since don’t need it (yet). Looking at the code above, there is nothing to suggest that it wouldn’t work, except for, as Kevin pointed out, you may have to adjust the Stefan September 19, 2013 at 2:38 am Ryan, your tutorial was very useful. My case was similar to yours and I was able to remove the slug. But I made a few modifications for this to work as you can see here https://gist.github.com/stefanbc/6620151. First of all, this line
should be something like this
because according to the WordPress codex there is no filter pre_get_posts And another thing I modified was this
to this
This was my case. Thanks for the awesome tutorial. Ryan Sechrest September 20, 2013 at 10:03 pm Thanks for the feedback, Stefan. You are right about it being an action and not a filter. I’ve updated my post above. With regard to Dennis October 13, 2016 at 11:49 am @stefan Your github code worked except that it was throwing a php error regarding variables. I changed:
0 to
1 and it worked beautifully. Thanks chụp ảnh cưới October 12, 2013 at 4:25 am I using
2 with htaccess? Ryan Sechrest October 12, 2013 at 3:58 pm The rewrite rules I showed were only a subset of those in the system to explain that particular point. What you have works just as well. Sam October 30, 2013 at 8:21 am Sorry for asking – I couldn’t get where do I make the changes :$ Help? O:-) Ryan Sechrest October 30, 2013 at 8:38 am You could put this in your theme’s
efix December 11, 2013 at 4:30 pm Hi, Ryan Sechrest December 12, 2013 at 2:40 am This code will not work on native post types, only custom post types. Victor December 30, 2013 at 3:59 pm here is how i did: Ryan Sechrest December 30, 2013 at 9:27 pm Thanks for sharing, Victor. I’ll try that out next time I’m working with that code! Bill January 12, 2014 at 10:55 am Great article. THis seems to work for me on my sandbox site except one thing…. Ryan Sechrest January 13, 2014 at 2:38 pm Bill, I revised the function to be a little more flexible and it should also now work with WordPress installed in a subdirectory. Take another look at the code in step 1. Bill January 18, 2014 at 7:02 pm Thanks for the reply Ryan. I must be doing something wrong, because I cant get it to work. First, in step 1, you forgot the word
3
4 Ryan Sechrest January 19, 2014 at 5:36 am You’re right, I didn’t test my quick update and it contained an error. Please take another look, this time tested, and it should now work for you. Bill January 19, 2014 at 6:43 am Hi Ryan…
5
6 Ryan Sechrest January 19, 2014 at 6:34 pm Here is the code I used for testing https://gist.github.com/ryansechrest/03b3caa9f12c2d70f7bc. Throw this code in bill January 21, 2014 at 8:05 am thanks Ryan. I followed your instructions…I still get a 404 for both service posts I create (one parent and one child) Ryan Sechrest January 21, 2014 at 12:24 pm Maybe you have a different kind of WordPress configuration or a plugin that is preventing this from working? I downloaded WordPress 3.8, installed it in a subdirectory as a single site, and then only installed that plugin I referenced above, and that worked for me.
7 Bill January 21, 2014 at 1:05 pm Thanks for your help Ryan! Each of the three folders has its own WordPress install. Then a year or so ago, I deleted the main wordpress install from the server because I dont use that site anymore…. but I kept the three ass-on websites….. so it looks like this Ryan Sechrest January 21, 2014 at 1:33 pm The individual WordPress sites (using add-on domains) should be isolated from each other, so I don’t think that’s the problem. Daniel January 30, 2014 at 9:21 pm Hi Ryan, Ryan Sechrest January 30, 2014 at 10:49 pm You could try something like this. It assumes you are using the
8
9 Yumna March 11, 2014 at 12:43 am Hi Ryan, I am trying to change my cpt urls using your code. I could remove slug from parent post urls, but it fails on child post urls. My cpt is hierarchical. I modified the post_type_link hooked function as below and now it changes link for child pages as well
0 Now the permalinks are created correctly, but the problem is that i get a 404 on child posts. I have dumped the query on both parent and child posts and i have noticed that on child post, the query_var attachment is set and no other query_vars are set. Please help if possible. Thanks. Ryan Sechrest March 12, 2014 at 9:47 am OK, first you’ll want to change
1 Second, and this is the main problem, the post name being used to find your child page in the database contains the parent slug, in other words,
2 Let me know if this works. Irvin April 29, 2014 at 2:50 am Hi Ryan, Ryan Sechrest April 29, 2014 at 9:12 am I don’t think you followed my tutorial very closely, because your code looks completely different. At first glance, though, I believe you’re coming up empty here:
3 Try swapping Yana January 13, 2015 at 6:51 am Hello Ryan, Ryan Sechrest January 13, 2015 at 9:55 am Looking back at Tomas’ post, I didn’t even realize that he was talking about WPML the plugin and not WPMU… I skipped right over that! "I use your function for a site which is published in two languages (German source and English using WPML plugin)." So your main site is "I have different custom post types (on of them is members, not hierarchical)" So member pages look something like this, right? "which are first filled in an overview page (simple loop) including an link to the detail page of the member" When you say overview and detail page, do you mean something like: "The overview works as expected but when I try to get the detail page it only works in the German version, the English version throws an error 404." So, this works: Yana January 13, 2015 at 2:04 pm Hello Ryan, thank you for your response. "ple.org/?lang=en, right?" No it is
4 and for the english version:
5 I have an if statement in the function to get the current language code and use to two different path for the german and english version. Ryan Sechrest January 13, 2015 at 2:52 pm You have
6 But this does not work:
7 Did I get that right? If so, it seems part 1, building the URL, is working fine for you, but you’re having trouble with part 2, which is rebuilding the query to then display the resulting data. Yana January 14, 2015 at 4:47 am Hello Ryan, yes, exactly. This is working
6 This is not working
7 Thank you Yana Ryan Sechrest January 14, 2015 at 9:05 am OK, can you post the code you’re using for part 2 with the modifications you made? Yana January 14, 2015 at 9:33 am Here is the code I am using:
0 And the
1 It seems that the first function causes also an error in the backend, all page, post and cpt linstings disappeared this morning. By removing the function everthing works again. Ryan Sechrest January 14, 2015 at 2:21 pm @Yana
70 "It seems that the first function causes also an error in the backend, all page, post and cpt linstings disappeared this morning. By removing the function everthing works again." Do you know what the error was? Yana January 15, 2015 at 8:05 am I was wrong, it is not the first function, it is the
2 Ryan Sechrest January 16, 2015 at 9:00 am Give the original code a try for
Trieu To February 2, 2015 at 6:46 am Hi Ryan
3 Trieu To February 2, 2015 at 8:01 am Dear Ryan I want to few character to url example:
4 But step 2 not work. How can i fix it? and How can i add any character to my custom post type slug? Ryan Sechrest February 3, 2015 at 9:01 am Let’s say your post name is “foobar” and let’s say you build a URL as follows:
5 When the query is performed to look up the post, there is no post in your database called “examplefoobar,” which is why step 2 is not working. If you are adding “example” in the post name, you must remove it again prior to making the query. So, on line 8 in your first post, you could try something like this:
6 Note that in this case, regardless of where “example” occurs in the string, it will be removed, so depending on your rules, you may want to refine it.
7 Teilmann February 16, 2015 at 2:24 am Hello Ryan, I have implemented your solution on my local environment, and it works like a charm. However, when i do the same on the online solution, some links break, and i cannot save stuff in the administration panel. (posts, permalinks and more). Any thoughts? Teilmann February 16, 2015 at 3:00 am Nevermind Ryan, i seemed to fix the problem. The former programmer on the site im working on, made a bunch of whitespaces in the online version of the functions.php file, which caused the white screen of death. thanks for the awesome solution Ryan Sechrest February 16, 2015 at 9:56 am Good deal– glad it’s working for you! Thomas Teilmann February 17, 2015 at 2:13 am Hello again, it seems i have found yet another problem :/ Pierre May 28, 2015 at 4:48 am Hi ryan, Trying to use your solution to remove “product” from slug in woocommerce But the query in get is quite empty (at least for name and pagename) , and i got 404.
8 This is the code, in case you spot any issue… khubbaib August 29, 2015 at 3:17 pm You are rock ryan… Its help me alot,,, In first try it was not working but now it working… Thank you so much… Colir November 12, 2015 at 9:57 am Hi. Colir November 13, 2015 at 7:06 am Hi. Thanks for this solution. Ryan Sechrest November 13, 2015 at 12:30 pm Hi Colir, Take a look at this Gist I put together– it should do the trick. colir November 16, 2015 at 4:24 am i think i‘ve found a first probleme
Colir November 16, 2015 at 4:10 am Thnaks a lot for your answer. Colir November 16, 2015 at 7:36 am Yo Ryan
9 note: i also test the Ryan Sechrest November 16, 2015 at 9:02 am Hi Colir,
0 And let me know what the result is. Colir November 17, 2015 at 7:18 am Here is the result. For info, my child post name is CEP. As you can see the query let appear it as an attachment, but i didn’t know why (this is not the case if didnt filter the permalink). My WP version is 4.3.1
1 Ryan Sechrest November 18, 2015 at 1:22 am Hi Colir, Colir November 18, 2015 at 9:11 am Ok. Thanks a lot for your help. I will try to setup a news WP and see Colir November 18, 2015 at 9:25 am Ryan, i‘ve just setup a new clean install of the last version of WP,
2 Colir November 18, 2015 at 9:38 am I’ve made a new test : Ryan Sechrest November 20, 2015 at 12:07 am Hi Colir, Can you confirm where you placed the statement in the code and which page you were trying to load when it printed that out? Colir November 20, 2015 at 7:20 am I place it in the “pre_get_post” and i try to load a child page of my cpt
3 Ryan Sechrest November 20, 2015 at 8:27 am Hi Colir, Try putting it right before:
4 Also, when I was testing, I was using the Twenty Fifteen theme– which one were you using? Colir November 24, 2015 at 1:39 am Hi Ryan. Colir November 24, 2015 at 1:45 am Here the modified git i use
5 Ash Bryant April 6, 2016 at 7:15 am Hi Ryan,
6 Ryan Sechrest April 6, 2016 at 9:29 am Hi Ash, Does my code work for you on the first site in a multisite environment and just not on the other sites, or does it not work at all? Ash Bryant April 7, 2016 at 2:55 am Hi Ryan, Ryan Sechrest April 7, 2016 at 10:30 am Just to be sure, can you visit the Permalinks page to flush your rewrite rules and then see if you still get a 404? Ash Bryant April 8, 2016 at 7:30 am Yep already done that :/ Ash Bryant April 8, 2016 at 8:58 am If it helps these are my CPT & Taxonomies
7 Ash Bryant April 8, 2016 at 9:28 am I’ve tried adding
89 but it doesn’t show anything, but if I change your code to match Colir’s version here …
8 it returns as banner, so is it the query here that is the issue? Ryan Sechrest April 8, 2016 at 4:18 pm Hi Ash, I took your code, with a minor tweak in labels:
90 You’re missing a comma after the
9 I pasted it into a functions.php file on a multisite I’m running, and added multiple tours to two different sites. Each permalink had the post type removed and I saw each tour page render (using the default template). There must be something else you have tweaked or installed that is interfering with the code above, but based on what you posted, I can confirm that it works. Ash Bryant April 15, 2016 at 10:42 am Odd. Could domain mapping be causing the issue do you think? Ryan Sechrest April 15, 2016 at 11:10 am Is that a plugin or are you doing it manually? The site network I tested it on actually uses a top-level domains for each site (as apposed to subdomain or subdirectory), so that does work as well. Ash Bryant April 15, 2016 at 11:30 am Bugger. Ryan Sechrest April 15, 2016 at 2:17 pm I could definitely see WPML causing issues, since it manipulates database queries. I run a network of sites with WPML, but I don’t remove post type slugs on any of those sites. You might deactivate both the domain mapping and WPML plugin to see if that resolves the issue. If so, then at least you know where to look to find a workaround. Alex April 26, 2016 at 9:50 am Hi, Ryan.
0 No relevant information. What it can be? It looks like the function is executed after construction of the post. I would be grateful for any advice Ryan Sechrest April 26, 2016 at 11:38 am Hi Alex! I don’t use WooCommerce, so I don’t have any information that would be helpful here. I will say that my tutorial is for changing the URL for post types that you register. Changing the URLs in post types registered by a third-party plugin might have unintended consequences. Ajay January 19, 2017 at 1:47 pm Awesome. One of the few solutions that work to get the URL’s right !!!! Thank you Leo February 11, 2018 at 8:54 am Hi Ryan, Viktor Ormanow April 3, 2020 at 1:18 am Yeah, same issue on WP. Plug-ins do help but slow down the page speed. Forbes Robertson February 23, 2021 at 9:02 am Greetings! |