I have created a custom post type called 'reports' to provide an easy method for providing monthly reports to specific people. I don't want users to have to login to view the reports and I also don't want any user to find reports intended for another user.

So I have created a custom taxonomy so I can create a term for each user. The term slug will be a random set of letters and numbers. I can manually create a 'random' slug, but I thought it would be better if the slug was programmatically created when adding the term. In this case the user would have to know their random term slug to view their reports, but they would never be able to guess another users slug.

Example slugs would be: /c8etv35n/john-doe-report-january-2018 /c8etv35n/john-doe-report-february-2018 /76w8o9ev/jane-doe-report-january-2018

With this type of arrangement, John Doe could view all of his reports in the taxonomy archive based on his random slug, but Jane Doe would not be able to guess how and where to find his reports and vice versa.

I have search high and low for help on this, but I have not found a clear explanation for how to do it. I have looked into the edit_terms hook and others like wp_update_term.

What I am hoping for is something like the save_post hook, then some way to affect the slug. I can handle the random string generation and everything else. If this is all possible, I would then just hide the 'slug' field from the Add Term screen and let the slug be generated randomly.

  • why not just make the actual page slug be random? ie.../c8etv35n-january-2018 /c8etv35n-report-february-2018 /76w8o9ev-report-january-2018
    – rudtek
    Feb 15, 2018 at 2:10
  • You can't simply make random slugs and then expect the report's to not show up to anyone who doesn't know it. are you aware of xml feeds? sitemaps? wp rest api? you cannot make this taxonomy OR this post type public when you register them, or they will show up in many places. if you want users to be able to view reports at a url, do something like /reports?list=123abc...random..5e543f, where reports is a special page template and the template employs it's own logic based on $_GET['list']. This is still not super secure but definitely a pretty big step in the right direction.
    – Joel M
    Feb 15, 2018 at 6:20

2 Answers 2


You can use wp_insert_term_data:

add_filter( 'wp_insert_term_data', function ( $data, $taxonomy, $args ) {
    $data['slug'] = 'c8etv35n-c8etv35n-c8etv35n-c8etv35n'; // generate slug however you wish.
    return $data;

I found it in wp_insert_term function here.

But you should really implement ACL and not rely on random slugs to hide the content.


I think that showing monthly reports (which are personalised, as I understand it) should not be shown in the open, but always behind a login. I think this also shows a bit more professional towards the people reading these reports plus you can do a lot more when you can 'connect' a user to certain actions.

I understand my suggestion might not the exact answer you're looking for, but in my opinion it's a better and more safe approach. What if your reports are expanded with 'sensitive' information, then you want a login anyway.

I would use pre_get_posts on the custom taxonomy page. First check the user ID and which term he/she is matched to (you could set this in term meta). Something like this (from the top of my head, so untested but it gives you a pretty good idea).

You do need to (find a way to) store the term meta in your user id on which to query.

function wpse294132_override_tax_archive( $query ) {
    if ( ! is_admin() && $query->is_main_query() && is_tax( 'your_custom_taxonomy' ) ) {
        $user_term_meta = get_user_meta( get_current_user_id(), 'custom_field_key', true );

        $query->set( 'tax_query', array(
                'taxonomy' => 'your_custom_taxonomy',
                'field'    => 'term_id',
                'terms'    => $user_term_meta,
                'compare'  => '='
        ) );
add_action( 'pre_get_posts', 'wpse294132_override_tax_archive' );

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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