Creating a dynamic URL structure

Demonstrated here:

http://thereforei.am/2011/10/28/advanced-taxonomy-queries-with-pretty-urls/

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'] . "https://wordpress.stackexchange.com/";
        $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;
}