I want to create a directory structure for my WordPress links and for the final page to be based on the taxonomy of the page.

So I have a business that belongs to a city (meta) and country (taxonomy). I would like the final URL to be


Is this at all possible? I have tried add_rewrite_rule() but either it can't do what I want or I'm doing it wrong (I got rid of the code so I can't show it, apologies).

1 Answer 1


Demonstrated here:


Here's the final code to autogenerate the necessary rules:

It’s quite likely you will at some stage want to programmatically generate rewrite rules for multiple custom post types with various taxonomies. You could do it manually, but that’s no fun. Let’s use an automatic rewrite rule generator.

The function below takes a post type as the first parameter and creates a series of rewrite rules for each of its taxonomies. The function also includes an optional second parameter, $query_vars, which is an array of any non-taxonomy query variables you may want to add rewrite rules for. It’s ideal for adding query vars for advanced metadata queries. For example, our event post type could use a date query variable.

 * Generates all the rewrite rules for a given post type.
 * The rewrite rules allow a post type to be filtered by all possible combinations & permutations
 * of taxonomies that apply to the specified post type and additional query_vars specified with
 * the $query_vars parameter.
 * Must be called from a function hooked to the 'generate_rewrite_rules' action so that the global
 * $wp_rewrite->preg_index function returns the correct value.
 * @param string|object $post_type The post type for which you wish to create the rewrite rules
 * @param array $query_vars optional Non-taxonomy query vars you wish to create rewrite rules for. Rules will be created to capture any single string for the query_var, that is, a rule of the form '/query_var/(.+)/'
 * @author Brent Shepherd <[email protected]>
 * @since 1.0
function eg_generate_rewrite_rules( $post_type, $query_vars = array() ) {
    global $wp_rewrite;

    if( ! is_object( $post_type ) )
        $post_type = get_post_type_object( $post_type );

    $new_rewrite_rules = array();

    $taxonomies = get_object_taxonomies( $post_type->name, 'objects' );

    // Add taxonomy filters to the query vars array
    foreach( $taxonomies as $taxonomy )
        $query_vars[] = $taxonomy->query_var;

    // Loop over all the possible combinations of the query vars
    for( $i = 1; $i <= count( $query_vars );  $i++ ) {

        $new_rewrite_rule =  $post_type->rewrite['slug'] . '/';
        $new_query_string = 'index.php?post_type=' . $post_type->name;

        // Prepend the rewrites & queries
        for( $n = 1; $n <= $i; $n++ ) {
            $new_rewrite_rule .= '(' . implode( '|', $query_vars ) . ')/(.+?)/';
            $new_query_string .= '&' . $wp_rewrite->preg_index( $n * 2 - 1 ) . '=' . $wp_rewrite->preg_index( $n * 2 );

        // Allow paging of filtered post type - WordPress expects 'page' in the URL but uses 'paged' in the query string so paging doesn't fit into our regex
        $new_paged_rewrite_rule = $new_rewrite_rule . 'page/([0-9]{1,})/';
        $new_paged_query_string = $new_query_string . '&paged=' . $wp_rewrite->preg_index( $i * 2 + 1 );

        // Make the trailing backslash optional
        $new_paged_rewrite_rule = $new_paged_rewrite_rule . '?$';
        $new_rewrite_rule = $new_rewrite_rule . '?$';

        // Add the new rewrites
        $new_rewrite_rules = array( $new_paged_rewrite_rule => $new_paged_query_string,
                                    $new_rewrite_rule       => $new_query_string )
                             + $new_rewrite_rules;

    return $new_rewrite_rules;

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.