1

Note: this question also appears on https://stackoverflow.com/questions/44060613/update-permalinks-when-new-category-added-to-custom-post-type-taxonomy (but is not getting much love).

Have created a collection of Custom Post Types (CPT) for a WordPress theme I am working on (along with their own taxonomies and tags). For the purpose of this question I will just focus on the 'projects' CPT.

When a new project category is added, and then linked to in the navigation menu - the user will see a 404 error until permalinks are saved, clearing WordPress' route caching.

I was thinking the best way to achieve this would be to use flush_rewrite_rules();

Although, saying that - I don't take it lightly as best practice strongly recommends only using this function when activating/deactivating a plugin. https://codex.wordpress.org/Function_Reference/flush_rewrite_rules#Usage

What I want to do is hook into the action that fires when a new CPT category is created (either via the post or admin screen) and then run the flush rewrite upon that action so that the WP admin doesn't have to concern themselves with forcing Wordpress route caching via update on permalinks.

I looked at this Hook onto Add New Category for a possible solution and attempted to use this code:

function custom_created_term( $term_id, $tt_id, $taxonomy )
{
    $project_cpt = 'CPT_PROJECT';  // Edit this to your needs
    $project_tax = 'TAX_PROJECT_CATS';  // Edit this to your needs

    if( DOING_AJAX && $project_tax === $taxonomy )
    {
        // Try to get the post type from the post id in the referred page url
        // Example: /wp-admin/post.php?post=2122&action=edit&message=1

        parse_str( parse_url( wp_get_referer(), PHP_URL_QUERY ) , $params );

        if( isset( $params['post'] ) )
        {
            $post_id = intval( $params['post'] );
            if( $post_id > 0 && $project_cpt === get_post_type( $post_id ) )
            {
                flush_rewrite_rules(true);

            }
        }
    }
}

But it is not really working out for me. Not sure if I am using the right tool here or if I am doing something wrong. Have searched quite a bit to the solution but I haven't come up with a good solution to my problem here (can't find the hook for creating new CPT categories).

  • You don't have to flush permalinks every time you add a term to a taxonomy, only when you try to change what custom taxonomies you have, e.g. add a new taxonomy for colour, or remove one. In fact calling flush_rewrite_rules can slow down your site and if you call it before you register taxonomies it can break them – Tom J Nowell May 22 '17 at 0:35
  • So we've established flush_rewrite_rules to NOT be a popular option. To make it simpler, I'd just prefer to hook into the action that is performed when a dashboard user saves changes on permalink settings. How would I do that? – Ryan Coolwebs May 23 '17 at 0:15
  • You don't need to hook into permalink settings when you create a new term, no 'flushing' is required – Tom J Nowell May 23 '17 at 13:00
  • @RyanCoolwebs It's not clear what process you're following to get these 404s. If you register the taxonomy and immediately flush rules, and then subsequent additions of new terms results in 404s, something is very wrong and broken. Without seeing your registration code it's difficult to say what that issue may be. – Milo May 27 '17 at 15:59
1

That's not how custom taxonomies and post types work

This is what you do:

  • On the init hook, call register_custom_taxonomy or register_post_type
  • If you change your calls to register_custom_taxonomy or register_post_type, or add new ones in your code, regenerate permalinks by visiting the permalinks settings page and clicking save
  • You're done

So if I follow the above steps and create a new taxonomy named colour, I do not need to flush permalinks to create red or blue terms. If I created a brand new taxonomy named shape I would flush the permalinks, but only once, this is so that I don't get 404's when I visit shape terms on the frontend. The same is true of custom post types

Keep in mind that flush_rewrite_rules is a very expensive function, and you should never need to call it. An example of when it might be called is in a plugins activation hook after it's first installed, or a WP CLI command.

How To Avoid The 404's

Use register_activation_hook to flush rewrite rules. This will get called when your plugin is activated ( and only the time it's activated, not every page load ).

https://codex.wordpress.org/Function_Reference/register_activation_hook

Flushing on the creation of every term is both unnecessary, and damaging

What If I Registered My CPT/CT In A Theme?

You can use the after_theme_switch hook to flush rewrite rules, however, registering post types and taxonomies in a theme is bad practice. It causes issues with data portability, e.g. if a user changes themes they loose their data.

Themes determine how a site looks, and functionality, especially data, should be defined in plugins.

  • Thanks for your answer Tom but I'm trying to automate this process and save users the trouble to update permalinks manually as some users will not be the most technical minded if you know what I mean (the ones who dive in and fail to read instructions). – Ryan Coolwebs May 23 '17 at 21:52
  • Use an activation hook for when your plugin is first installed, flushing rewrite rules every time a new term is created is an awful idea, and completely unnecessary. Nobody else does it – Tom J Nowell May 24 '17 at 9:58
  • Ok thanks for pointing out flush rewrite rules are bad again. I'm pretty sure I get it now. This is a theme plugin so it gets activated along with theme. When a user creates a new project category for the 'projects' cpt and then they go to insert that category straight into Appearance > Menu it returns an error 404. Perhaps I am missing something here but I can't really see how an activation hook that fires when first installing the plugin which actually help me. – Ryan Coolwebs May 26 '17 at 1:59
  • @RyanCoolwebs other people who come here might only read the answers, and I try to write self contained answers where possible so it's easier to read all in one place. With regards to themes, there are theme activation hooks too, but I would strongly advise against putting taxonomy post type registration code inside a theme as it causes data portability problems and product lock-in – Tom J Nowell May 27 '17 at 13:42
  • I'm developing a customised solution for a very specific project, rather than a commercial theme (for use by others). It is supposed to have 'lock-in' as is heavily customised. Just want to know how to hook into the 'save permalinks' function - that's all – Ryan Coolwebs May 30 '17 at 0:36
0

Ok, pretty simple solution I came up with. Just put this code below into my includes within function.php:

add_action('wp_update_nav_menu_item', function ()
{
    flush_rewrite_rules(true);
}, 10, 2);

This just hooks into the nav menu update function, so it fires every time menu is updated by admin user.

I know flush rewrite is an "expensive" function but it will only be called when the navigation menu is updated which will not be all that often.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.