How can I place a meta value in rewrite rule for custom post type?
Asked Answered
B

1

6

I've completely re-written this question as it got a bit long, and I was worried people skipped it without reading it completely.

I have a custom post type (procedure) that features a custom meta key/value with a page ID that I want to use as the slug.

I'm using this function (below) to create the permalinks in the admin area, but when viewing these, the pages are 404 errors. How can I create rewrite rules to use this same format?

function bv_procedure_parent_slug( $url, $post ) {

    if( get_post_type( $post ) == 'procedure' && get_post_meta( $post->ID, 'procedure_parent', true ) ) {
        $procedure_parent = get_post( get_post_meta( $post->ID, 'procedure_parent', true))->post_name;
        if( $procedure_parent ) {
            $url = str_replace( 'procedure', $procedure_parent, $url );
        }
    }
    return $url;
}
add_filter( 'post_type_link', 'bv_procedure_parent_slug', 1, 3 );

The goal here is that I'll have lots of posts here, that will contain a meta key/value of procedure_parent => 31 (where 31 is a page ID, and the post name is 'face'). When viewing the single post, rather than the URL being /procedure/facelift/ I would like it to be /face/facelift/.

For this, I believe I need to be able to get access to $post when creating the rewrite rule so I can get use get_post_meta().

But how?

Briggs answered 11/1, 2018 at 14:11 Comment(10)
Anyone able to help with this?Briggs
Could you please edit your question with the default permalink, the permalink you want and the permalink you get?Cinder
Updated @JamesJonesBriggs
Can anyone else please help here? I haven't gotten anywhere with this, and it's got to be a very simple thing to want to do!Briggs
@JamesJones I have re-written the question which may help a bit moreBriggs
@Briggs you perfectly know the problem so i don't need to explain that. This is extensive work which can't be summarised in an answer. And i am sorry to say this but it will not work the way you are trying.Logjam
I have worked on a related problem and had no luck. But, since you are willing to edit each post to add a post meta value. Why don't you write custom permalink for each post ?Logjam
Sorry, I've seen posts by others saying they're able to get this working, with more than one meta value in the slug, I don't understand why my simplified version won't work? I Don't think I perfectly know what the problem is. Why isn't this possible then?Briggs
In your example, you say the meta value "31" would be a page ID. A page ID of... what? A different page? I might be getting confused between page and post. I agree with James Jones that add_permastruct() feels like the right kind of thing for this.Controller
31 is the ID of a page that I have created (originally all of these posts were also pages, but I am moving them into a plugin, using a custom post type so I can disable/enable them as needed, and export/import them easily, without touching other posts or pages). so the 31 is the ID of a page called 'Face', which I want to use as the parent of a particular post (or procedure in my case).Briggs
C
0

It seems like you've over complicated your problem a little. Would it work if you did the following?

  • Install the Custom Post Type Permalinks plugin and
  • Change the default permalink to http://example.com/custompostname/%category%/%postname%/.
  • Then instead of creating some pages with categories with them, use WordPress' inbuilt archive functionality and make a custom archive template for your custom post.

Otherwise I think add_permastruct() is the function you're missing. I'm theorising this looking at the solution at https://wordpress.stackexchange.com/a/253325/58884 for a similar problem. Some code like this:

function my_custom_rewrite() {
    add_permastruct('procedure', '/%parent%/', false);
}
add_action('init', 'my_custom_rewrite'); 

rather than 'rewrite' => array( 'slug' => '%parent%', 'with_front' => false ) in the post type declaration. The 'slug' => '%parent%' part of that declaration is an optional substitution for the name of the custom post type ($post_type in the register_post_type() codex entry). So if you had 'rewrite' => array( 'slug' => 'wibblewobble', 'with_front' => true) your url would change from http://example.com/procedure/%postname%/ to http://example.com/wibblewobble/%postname%/. With 'with_front' => false I don't think it does anything. When you've entered 'slug' => '%parent%' I think WordPress is taking that as a string and not doing anything with it dynamically.

Also be sure to use flush_rewrite_rules();. You can use it in the init hooked function while testing and then move it to theme/plugin activation hooked function once it works.

Good luck!

Cinder answered 15/1, 2018 at 14:40 Comment(13)
The function I mentioned in my post does the conversion from the %parent% placeholder to get the post_name of the ID entered as the meta value. It works in the Admin area, and the permalinks all show the correct slug, but when visiting the page, it shows a 404. So the permalinks are not updating, even with the flushing rewrite rules.Briggs
@Briggs that's because you're manipulating strings to get the address that looks correct but WordPress is unable to interpret it because it doesn't know that %parent% is an address variable like %category%, %date% or %postname%. You need to use add_permastruct to tell WordPress to interpret it as a variable. Don't use 'rewrite' => array( 'slug' => '%parent%' ). Make sense?Cinder
Yes that makes sense, I will try this and get back to you tomorrow, thanks for the help.Briggs
Hi James, just trying this and have noticed that with the new function you've mentioned, the permalinks displayed in WP Admin strip out the post name, leaving just the parent? IS there an arg missing in add_permastruct ?Briggs
I'm not entirely sure what functions to remove, and where to place this new one. Anything I'm trying doesn't seem to make any difference to the single post view being displayed (always a 404)Briggs
I think I know what I want to do, I can use add_rewrite_rule but I need to use the custom value of the meta key in the first argument (the regex section). I've been able to perform this fine with just procedure_parent as the first part of the slug, but ca't get the value from the custom key. If that makes sense?Briggs
Also, I can't remove the rewrite param from the register post type as this now adds the permalink structure to the URL, which is not what I want. Maybe it would be more useful if you were to see my entire plugin code that I'm placing all of this? with_front is vital here, as I have added /blog/ at the start of my sites permalink structure (for normal posts). with_front removes this for the custom posts.Briggs
Are you sure this is possible? I've been doing this for days now, and haven't gotten close to what I want to do, which I thought would or should be quite simple and trivial. Perhaps I need to ask the question another way.Briggs
@Lee. Sorry for the radio silence. I've been sick. I'm sure it's possible as anything is possible :), I'm not sure if my code is the fix as I haven't tested it. I'll give it a try on my own dev machine as soon as I get time. Hopefully today, but may be up to 2 days.Cinder
Hi JAmes, sorry to hear that. I've gotten a bit closer, I'm going to update my question soon as I have a slightly different one now.Briggs
Made a new question: #48319863Briggs
Deleted it, as I found out the rewrite rule I added was completely wrong, and was allowing the pages to be accessed by using ANYTHING for the slug. :( so I'm back to square one.Briggs
Updated question again to try and get more interest. I just need to get access to $post when creating a rewrite rule (and understanding how regex works)Briggs

© 2022 - 2024 — McMap. All rights reserved.