WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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).

share|improve this question

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 <me@brentshepherd.com>
 * @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;
share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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