5

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?

Krupal Panchal
  • 1,553
  • 2
  • 13
  • 26
Lee
  • 4,187
  • 6
  • 25
  • 71
  • Anyone able to help with this? – Lee Jan 15 '18 at 10:37
  • Could you please edit your question with the default permalink, the permalink you want and the permalink you get? – James Jones Jan 15 '18 at 15:44
  • Updated @JamesJones – Lee Jan 16 '18 at 10:56
  • 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! – Lee Jan 16 '18 at 16:58
  • @JamesJones I have re-written the question which may help a bit more – Lee Jan 16 '18 at 17:03
  • @Lee 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. – Shahbaz A. Jan 17 '18 at 13:37
  • 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 ? – Shahbaz A. Jan 17 '18 at 13:39
  • 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? – Lee Jan 17 '18 at 13:48
  • 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. – Will Hines Jan 21 '18 at 11:31
  • 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). – Lee Jan 21 '18 at 21:31

1 Answers1

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!

James Jones
  • 3,850
  • 5
  • 25
  • 44
  • 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. – Lee Jan 15 '18 at 14:53
  • @Lee 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? – James Jones Jan 15 '18 at 15:10
  • Yes that makes sense, I will try this and get back to you tomorrow, thanks for the help. – Lee Jan 15 '18 at 17:34
  • 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` ? – Lee Jan 16 '18 at 10:37
  • 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) – Lee Jan 16 '18 at 10:44
  • 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? – Lee Jan 16 '18 at 11:39
  • 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. – Lee Jan 16 '18 at 11:47
  • 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. – Lee Jan 16 '18 at 16:47
  • @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. – James Jones Jan 18 '18 at 03:06
  • 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. – Lee Jan 18 '18 at 09:54
  • Made a new question: https://stackoverflow.com/questions/48319363/how-can-i-delete-a-specific-rewrite-rule-in-wordpress – Lee Jan 18 '18 at 10:44
  • 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. – Lee Jan 18 '18 at 11:17
  • 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) – Lee Jan 18 '18 at 11:23