We’re building a directory of automotive-related businesses in 3 countries – USA, Canada and Mexico.
I created a custom post type ‘Listings’ and tried to move on with the following.
For various SEO purposes we need specific URL structures as follows:
1) Individual listing page
Nothing too fancy – domain.com/usa/listing-slug
2) Per-state archives
Nothing too fancy as well – domain.com/usa/texas
3) Per-city archives
This one is more interesting, we need the following structure:
- domain.com/usa/cleveland/oh
- domain.com/usa/cleveland/nd
Where the 1st one is archive for Cleveland, Ohio and the other one for Cleveland, Nevada.
4) Per-ZIP archives
Pretty usual – domain.com/usa/05657
5) Mixed location-category archives
- domain.com/usa/cleveland/oh/car-parts
- domain.com/usa/ohio/car-parts
- domain.com/usa/05657/car-parts
6) Custom content (templates) for all above archive pages, except maybe ZIP
We’re trying to somewhat mimic this website.
If you check, let’s say, the same examples for Cleveland, Ohio and Cleveland, Nevada: http://www.familydaysout.com/kids-things-to-do-usa/cleveland/oh and http://www.familydaysout.com/kids-things-to-do-usa/cleveland/nd you’ll see what I mean – these pages have custom content (descriptions) in the beginning.
Above are per-city custom content examples. The same exists for per-state http://www.familydaysout.com/kids-things-to-do-usa/ohio and mixed:
http://www.familydaysout.com/kids-things-to-do-usa/ohio/major-theme-parks
http://www.familydaysout.com/kids-things-to-do-usa/cleveland/oh/major-theme-parks
http://www.familydaysout.com/kids-things-to-do-usa/5601/major-theme-parks
I got to the point where I can auto-populate location data when adding a new listing, so when I paste a full address, e.g. “21200 Saint Clair Avenue Euclid, Ohio 44117” and save I get this:
As you can see, country, state, city and ZIP are all there. Category (Car Parts) is also there as a listing category.
Now how can I use these values to construct URLs and pages/templates for archives? Should I automatically convert custom field values to custom taxonomies and go from there? I know I can do this with https://codex.wordpress.org/Plugin_API/Action_Reference/save_post and https://codex.wordpress.org/Function_Reference/wp_set_object_terms
I know custom taxonomies can have descriptions and I know how to output these descriptions. Besides that, taxonomies can be hierarchical, so I can add Ohio and Nevada as parents and each Cleveland as a child for them.
So I’m at the point where I managed to collect and store all the info bits, but not sure how to start manipulating them to achieve the above model.
Q1: Where should I store location data (country, state, city, zip) to be able to use it in URLs as described above? Custom fields or taxonomy terms?
Q2: How do I build archive pages/templates as described above in a way that I can customize templates for them?
Any other helpful tips will be highly appreciated.
After searching around, I think I can help you now.
1. Register
location
taxonomy to create base archive slug:We have to change the terms’ slugs which are automatically generated by WordPress to sanitized terms’ names so that the URLs’ structure look as you wished for:
Caution: Do not enter terms’ slugs manually when adding new terms, let WordPress generate it for us or we will not be able to query terms’ posts contents correctly. The reason is the two URLs:
location/usa/ohio/cleveland
andlocation/usa/idaho/cleveland
give us the same posts because WordPress only usescleveland
as term for querying posts’ contents without caring about the parent term.2. Register
listing
post type like this:We’re not sure whether the listing has state|city|zip or not, so we have to use substitutes (
%country%/%state%/%city%/%zip%
). Then replace it with each listing meta data (From my experience with WordPress, you should store location data in each listing):Note: If your use uppercase short names, you must convert it to lowercase when modifying URLs’ structure.
3. Add rewrite rules to make our custom URLs work correctly.
4. Return back the correct terms’ slugs:
As I said, by changing
usa/idaho/cleveland-idaho
tousa/idaho/cleveland
in permalinks, queried posts forusa/idaho/cleveland
are same asusa/ohio/cleveland
. So we must help WordPress know what is the correct term slug to use for querying posts’ contents:Thanks to @Jevuska for suggesting to use
parse_request
.5. Create a custom template for each archive location:
Thanks to WordPress Template Hierarchy, we can do it easily.
Example:
For
location/usa/ohio
, the template will betaxonomy-location-ohio.php
.But remember that we must use the actual terms’ slugs which generated by WordPress, not what we modified in URLs.
Example:
If Cleveland in Ohio was added before Cleveland in Idaho, the term slug of the first is
cleveland
and the second will becleveland-idaho
.Then, template for the first is
taxonomy-location-cleveland.php
and the second istaxonomy-location-cleveland-idaho.php
.That’s all! All code you can put directly inside
functions.php
file. Remember to flush the permalink settings too.As per you requirements , you can achieve this by creation of categories as described below :
So create a parent category as “USA” and then child category as “Cleveland” and under that one more child category as “Ohio” and its slug as “oh”.
So hierarchy should be
USA->Cleveland->Ohio
and in slugs it should beusa->cleveland->oh
Similarly,
USA->Cleveland->Nevada
and slugs asusa->cleveland->nd
Now , For the posts to be displayed at URL :
category
category
Now you only need to remove the
category
from URL . So for that write the below code in the.htaccess
file located in the root folder.I think there are 2 ways to solve your problem
First one is to use mod_rewrite to transfer you suggested formatted URLs to associate template php file and handle your request there the way you want.
For this following link might help. Google for more https://www.addedbytes.com/articles/for-beginners/url-rewriting-for-beginners/
The 2nd approach would be follow the wordpress page template hierarchy and create template pages accordingly and handle similar requests in template php. For details explanation refer to https://www.smashingmagazine.com/2015/06/wordpress-custom-page-templates/
and a quick page template hierarchy to understand which page template will execute for particular url refer to https://media-mediatemple.netdna-ssl.com/wp-content/uploads/2015/05/01-wp-template-hierarchy-opt.jpg