How to Make WordPress Sites Different by Geography

An Approach to Geolocal WordPress Sites

In order to launch an inexpensive global network of sites run by volunteers that would provide shoppers categorized directories to local stores, I needed to leverage the power of WordPress with some unusual customizations and workarounds. There are a number of approaches to providing local experiences with WordPress. In this tutorial, I’m going to show you why and how we decided to make a customized solution.

In July, I launched a global guide to Internet-based alternatives to shopping at Amazon called FleetheJungle.com and the response was excellent. We received a lot of media coverage and subsequent traffic. It’s not a database-driven app; instead we leveraged the outstanding KnowHow knowledge base theme:

The Flee the Jungle Global Home Page - Amazon Alternatives

But to grow the site, we needed to offer geolocal versions for individual cities. Certainly the global site helps visitors cancel their prime memberships or find alternatives to Kindle books but there was nothing to encourage people to support small businesses in their communities.

To begin, we’d build a guide for local shoppers in nearby Portland, a city with a proud heritage of quirky, independent small businesses.

Fun Portland Map from Edward Juan
Credit: Forest and Waves Portland Map by Edward Juan.

The Technical Challenge

Certainly, I’ve written enough about quickly launching a plethora of WordPress websites using pre-configured, pre-optimized recipes, but maintaining related requirements for a network can be extremely time-consuming—things like managing SEO, WordPress and plugin upgrades, etc.

I also considered WordPress Multisite but even though I know she’s grown a lot, we had a number of awkward difficult pairings and were probably never meant to be together. Once you get involved with “her”, it’s very hard to break up.

I needed a simpler solution.

In this tutorial, I’ll guide you through customizations and tricks I used with WordPress and my knowledge base theme to launch our Portland shopping guide and make it easy to launch any number of other cities—while avoiding the overhead of managing dozens or hundreds of sites.

The Geolocal Network Requirements

Here are some of the basic requirements for launching more sites:

1. Maintain a worldwide site. I wanted to keep the global, fleethejungle.com primary domain intact, free of local articles but instead a guide to our available cities.

2. Localize by sub-domain. I wanted content localized by sub-domain. For example, a visit to http://portland.fleethejungle.com would promote local content on the site while re-using some specific national site categories related to shopping on the broader Internet, e.g. video streaming (there’s no Portland-based alternative to HBO Now). CraigsList provides a good model for this.

3. Integration between local and worldwide. I wanted to provide local visitors an explanation of the differences between their local site and the global site while encouraging them to participate in helping improve the listings in their city.

4. Volunteer-managed. I wanted to make it easy to regularly add cities to the site in a way that would only require volunteers with basic blogging skills to launch and maintain. There are too many requirements to launching new WordPress sites for each individual city to easily do this with volunteers.

5. Minimal maintenance. Finally, I wanted to keep the maintenance of the site network as simple as running a single site.

Let’s explore some of the technical approaches that are often used to address these kinds of requirements.

Technical Approaches

For content management, there are three basic approaches I thought of:

  1. Run different installations of WordPress.
  2. Use WordPress Multisite to run various sites.
  3. Customize WordPress to dynamically filter content for geography.

As I said earlier, I’m not a fan of Multisite and I wanted to avoid the complexity of launching and maintaining a variety of WordPress sites. A site like Flee the Jungle would have so much central content that would need to be re-used across city pages (such as how to terminate your Prime membership), and I didn’t want to have to maintain this content across different WordPress installations—or write code to do so.

I decided to filter the content depending on the domain or subdomain used by the visitor in the browser.

If you’ve read my tutorial How to Use Zillow Neighborhood Maps and HTML5 Geolocation, you know how to use HTML5 browser-based geolocation for determining where a user is. However, I wanted the user to have more control.

I wanted the user to use a sub-domain like the one that’s worked for years with CraigsList to guide them to their city.

The Craigslist Global Network by Sub-domain

But WordPress’s dominion over absolute URLs makes this difficult. When I first began experimenting with tracking the inbound sub-domain for a city and mapping it to links on the page, I ran into WordPress’s habit of creating absolute links nearly everywhere. A colleague I spoke to about it laughed immediately when I asked him about it—it’s a common foe of WordPress developers.

In this tutorial, I’ll share the customizations within our theme’s PHP-based queries to build our city-based sites and how we ultimately worked around the absolute URL problem. 

Customizing WordPress for Geolocal

Here’s how I decided to implement city-based sites for Flee the Jungle that could be easily maintained and authored by local bloggers without additional technical skills.

Leveraging Tagging With Sub-Domains

Articles written for cities would be tagged by city name, e.g. “portland”. Articles for the global site would be tagged “worldwide”. I wanted the ability to include worldwide articles about Internet-based stores for some categories where there was less effective local support such as video streaming. Other categories are certainly appropriate to focus exclusively on local stores such as Groceries, Auto Stores and Toy Stores.

A City Site’s Geolocal Home Page

For geolocal sites, we keep the worldwide categories in place and only show different articles for the locally appropriate categories. In the future, we’ll append worldwide articles to the local choices within a category when appropriate.

When visitors view category pages and search, we also filter and customize the results based on these design choices.

Defined Variables

To do this, we define arrays within the theme by their IDs:

  • list of categories for worldwide
  • list of categories for local cities
  • list of active cities and their subdomain prefixes

Here are a few examples. First, here’s my array of worldwide (nonlocal) category IDs:

You can retrieve those from peeking at the category ID in the dashboard category list (by hovering with the mouse over the category name as shown further below with tags):

Flee the Jungle Category List

Or, edit the category and grab the ID from the edit URL (Getting Started is 29):

Flee the Jungle Category Editing to Get ID

Here are the tag IDs for Seattle and Portland:

Seattle is 49. You can see the tag id by hovering over the city and letting the status bar reveal it:

Flee the Jungle Reveal City Tag ID

Using the Sub-Domain to Geotarget

To obtain the domain or sub-domain, I used Trevor Scott’s WordPress tip and placed it within my theme’s functions.php.

Here’s the WordPress Dashboard Theme Editor:

WordPress Theme Editing

And, here’s Trevor’s code:

Global Home Page

When visitors arrive at the global home page, the domain will be fleethejungle.com rather than a sub-domain. I’ve created another function, configure_geolocal(), which is called at the beginning of the template header.php file. Here’s the first part of the function:

Here’s how it’s called by get_header() within the theme’s header.php:

When the domain is global, $domain_locale will be false. Under these circumstances, I will exclude articles tagged locally by cities. And I will do this on the home page and the category page. When the domain refers to a local city, $domain_locale will represent the prefix, e.g. seattle or portland.

In the theme’s home page, if the visitor is on the worldwide site (root domain), I exclude articles tagged with cities from the $st_cat_post_args array. However, if the visitor is on a city page and the sub-domain is known, we only display local articles in most categories except those identified for nonlocal_category_ids—those are the ones more appropriate for non-local content such as video streaming:

Here’s the code within the context of more of the function:

Customizing the Behavior of Category Listing Pages

With the KnowHow theme, visitors may also click on the category headings, taking them to an article list within the category.

If they are on the global site, I want to show only global articles. I chose to tag all global articles as ‘worldwide’ to facilitate this.

So for the global site, I show only articles tagged ‘worldwide’ and for local city sites, I show only articles tagged for that city. If the category is an exceptional case for both, we include articles from both the current city and worldwide.

Here’s the code within the theme’s category.php:

I’m not customizing the query here because performance is currently not a major issue. I’m just skipping results out of context and not displaying them.

In the future, I may customize this further for city sites by displaying worldwide results at the bottom of the category page in a distinct section.

Customizing Search

It’s also important to perform these sorts of customizations for search. The KnowHow theme provides an AJAX search result or a generated page of results. We need to provide code to customize each option.

Live AJAX Search

For live search, there is no get_header() call so we need to configure our location dynamically:

Then we integrate the same logic used on category pages within live search results:

Dynamic Search Results Page

If it’s not AJAX, then get_header() is called for us and it’s a bit simpler:

As I mentioned above for Categories, I may decide to customize search results to display a second section of results for global articles on city sites.

Approaches to Content

To provide local visitors an explanation of the differences between their local site and the global site while encouraging them to participate in helping improve the listings in their city, I used a plugin I wrote about in January 2015 for Envato Tuts+: The Benefits of Using the Free Shortcoder Plugin. It’s a plugin that lets you use macros essentially to expand re-usable HTML content in place. For each city article, we’re using it to customize what local visitors see when they arrive from Portland.

Once the plugin was installed, I created a shortcode for each city such as [sc:pdx] which provides a simple blurb at the top of local article pages:

Flee the Jungle Shortcode editor

Then, whenever we added a local article, we included the shortcode [sc:pdx] at the top:

Flee the Jungle Shortcode In the Article Editing Page

Here’s what the article looks like when visitors arrive:

Flee the Jungle Articles with City Intro via Shortcode

Overcoming Absolute Links

I’m a long-time user of Digital Ocean but I’m becoming a more enthusiastic fan of WP Engine as well; well-managed hosting provides advantages in some circumstances. It turned out WP Engine offered a solution to the WordPress absolute URL problem which was better than alternatives.

WP Engine offers a post-processing filter in which you can use regular expressions to modify code. After considering other approaches to modifying WordPress and using its own APIs for this, I decided that it would be simplest to simply replace absolute links to FleeTheJungle.com with relative addresses. This allowed users visiting a city-based sub-domain to remain within the geolocal site:

WPEngine HTML Post-Processing

Prior to configuring this, visits to Portland Flee the Jungle sub-domain had outbound links to the global fleethejungle.com scattered across pages. After configuring it, outbound links remained consistent with the inbound domain or sub-domain.

Essentially, I used the post-processing filter to eliminate absolute URLs and allow the browser’s URL and relative addresses to drive navigation.

City Listings

To provide a directory of the cities where Flee the Jungle is and would become available, I built a page listing cities where global users could jump into. I also use it to attract volunteers to launch sites for their cities.

Flee the Jungle City Navigation

The Completed Configure_Geolocal() Function

Here’s the final code we used within WordPress for configure_geolocal():

Miscellaneous Requirements

Customizing the Logo

Of course, I wanted to implement basic customization of the logo depending on the sub-domain. The KnowHow theme doesn’t support this natively.

Flee the Jungle Customizing the Logo within WordPress by Subdomain

If you notice in the final configure_geolocal() code, I set a media library URL for the logos for each city.

Then, the code within header.php customizes the theme logo URL based on the domain here:

Hosting Domains and Sub-Domains

WP Engine’s domain mapping can be a bit confusing for the uninitiated. You have to add domains for your site and map them to WP Engine’s internal addressing system. If you want sub-domains to operate properly, you have to individually configure each sub-domain from within the WP Engine domains dashboard.

This took me a little while to figure out. Here I am adding a placeholder arrival page for San Francisco, which can be reached by sanfrancisco.fleethejungle.com or sfbay.fleethejungle.com. WP Engine makes it easy to set up these redirects:

WPEngine Adding a New City Domain

Here’s a preliminary view of domains configured for global and local Flee the Jungle:

WPEngine Domain List for Your Website

Unfortunately, cities that you don’t explicitly add redirect to a 404 error at WP Engine. There are other ways to work around this, but for the moment, I’m just adding larger cities to the configuration there. People will generally be directed to the global home page or a pre-existing city—from there, they can volunteer to start their own city.

Other Issues

Google’s internal search engine optimization is well known for being quite secret, yet much of the referral traffic your site receives depends on it.

Some of our content will appear across multiple domains, but much of it will be distinct depending on which city we’re browsing. Google doesn’t like seeing the same content on multiple sites, but it’s also good at indexing sub-domains separately.

Frankly, I have no idea how the Flee the Jungle geolocal network model will be received and ranked within its great supercomputing megaplex. This is a lower priority for me at the moment. The foundation of Flee the Jungle’s traffic is grassroots support and social sharing.

In Closing

Please compare the differences in content between worldwide Flee the Jungle and Portland’s local city site:

Flee the Jungle Portland - Home Page Example

Certainly, there are a number of ways I could have approached the challenge of creating geolocal sites. However, Flee the Jungle remains a volunteer effort—I needed a solution that would be simple and fast while making it easy to add cities, leveraging bloggers as volunteers. The approach I’ve described has accomplished these goals quickly.

The result of all this customization is that we have a single WordPress installation that can run hundreds of geo-local variations of our site, with worldwide and local content appropriately filtered and organized. Most importantly, volunteers can build and launch cities with only the basic skills of a WordPress blogger. This is so much simpler and faster than my “friend” WordPress multisite or running separate installations. The future is relatively unbounded.

I hope you’ve enjoyed this tutorial and would enjoy hearing how you might have approached this challenge. If you’d like to launch a shopping guide for your own city, contact us. If you’re intrigued about building a site like this, I’ve written a detailed, step by step tutorial for building your own knowledge base website on WordPress. Let’s say you want to launch your own Harry Potter fan site—it’s an easy guide to getting started.

Related Links

Leave a comment

Your email address will not be published.