I have 3 custom post types:

  • development
  • house_type
  • room

I have used ACF to build some relationships between these custom post types so development sits at the top and can have many house_types underneath it. Then a house_type can have many rooms beneath it.

I want to modify the url structure so that it is hierarchical also so that the user can go to /{development} which will display the single development page listing all the house_types at the development. Then if they click a housetype the url will be /{development}/{house_type} and will display the single house_type page which will list all of the rooms within that house type. Then finally if they click a room the url will be /{development}/{house_type}/{room} and will display the single room page with information about that room.

I have tried quite a few things but not managed to achieve this yet. The following works to a certain extent but not perfectly as it performs redirects. Like if I go to /{development}/{house_type} it redirects to /house-types/{house-type} which is the right page but I don't want the URL to change. Also if I go to /{development}/{house_type}/{room} the URL is correct but it displays the single development page instead of the single room page.

function my_rewrite_rules() {


    add_rewrite_tag( '%development%', '([^&]+)' );
    add_rewrite_tag( '%room%', '([^&]+)' );
    add_rewrite_tag( '%house-type%', '([^&]+)' );

    add_rewrite_rule( '^%development%/%room%/([^/]*)?', 'index.php?room=$matches[1]' );
    add_rewrite_rule( '^%development%/([^/]*)?', 'index.php?house_type=$matches[1]' );
    add_rewrite_rule( '^([^/]*)/?', 'index.php?post_type=development&development=$matches[1]' );
add_action( 'init', 'my_rewrite_rules' );

What am I doing wrong?

  • You can’t use rewrite tags in rules like that, they don’t belong in the first argument at all. Also adding rewrite tags is redundant, as registering a post type adds them as part of generating its own rules. – Milo Jan 26 '18 at 13:31

Sorted in the end. As Milo suggested I didn't need the calls to add_rewrite_tag. The following code works:

* Custom rewrite rules
function my_rewrite_rules() {
    add_rewrite_rule( '^([^/]*)/([^/]*)/([^/]*)?', 'index.php?post_type=room&room=$matches[3]', 'top' );
    add_rewrite_rule( '^([^/]*)/([^/]*)?', 'index.php?post_type=house_type&house_type=$matches[2]', 'top' );
    add_rewrite_rule( '^([^/]*)/?', 'index.php?post_type=development&development=$matches[1]', 'top' );
add_action( 'init', 'my_rewrite_rules' );

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.