Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I have a website that lists businesses in different cities (this is a niche site, so all businesses have the same "classification").

For starters I created a CPT for locations and a taxonomy called "Cities," which 150 or so cities as terms.

All 300+ locations have been tagged with a city.

I was able to modify the CPT links so that they appear like so: example.com/cityname/business-name

What I'd love to have (and not been able to accomplish yet) are urls like example.com/cityname which would list all businesses from that city.

My understanding is that by default WP attempts to find a page with "cityname" as the name.

What would be the easiest way to reroute this request to use a taxonomy template? Or as an alternative, what would the easiest way be to have the page template detect the city name and pull posts tagged with that taxonomy term?

I suppose I could create rewrite rules in htaccess for all cities, but I'd prefer where the redirects were automatically added when a new city name is added to the taxonomy.

share|improve this question
3  
you might get an idea of how to do this by looking at the no category base plugin. it works by adding a new rewrite rule for each term when the term is added to the database. –  Milo Mar 28 '13 at 16:29
add comment

1 Answer

Here is some code that should do the trick:

//Creates special permastruct that turns all terms of cities into slugs
add_action( 'init', 'set_rewrite' );

function set_rewrite() {
    //Get terms
    $terms = get_terms( 'cities', array( 'hide_empty' => false ) );
    //return if no terms
    if( count( $terms ) < 1 ) return;
    $slugs = wp_list_pluck( $terms, 'slug' );
    //create term regex
    $termregex = '(' . implode( '|', $slugs) . ')';
    //New query var
    add_rewrite_tag( '%cityname%', $termregex );
    //Add permastruct
    add_permastruct( 'cities_struct', '%cityname%/' );
    //refresh if new term added
    if( get_option( 'update_cities_struct' ) ) {
        global $wp_rewrite;
        $wp_rewrite -> flush_rules();
        update_option( 'update_cities_struct', 0 );
    }
}

//action to refresh rewrite rules when a new term is saved
add_action( 'created_cities', 'refresh_cities' );
add_action( 'edited_cities', 'refresh_cities' );
add_action( 'delete_cities', 'refresh_cities' );


function refresh_cities() {
    update_option( 'update_cities_struct', 1 );
}

//set city name to the taxonomy cities
add_filter( 'parse_query', 'parse_cities_query' );

function parse_cities_query( $query ) {
    if( !empty( $query->query_vars['cityname'] ) ) $query->set( 'cities', $query->query_vars['cityname'] )
}   

Basically this creates a special permastruct that uses the slugs of the taxonomy cities as its base. It creates a query variable called cityname, which only accepts the slugs of the taxonomy and then sends the result to the proper taxonomy query variable.

share|improve this answer
add comment

Your Answer

 
discard

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.