Build a city-scoped app with geofilters

Metadata

Field Value
Article type Tutorial (Admin)
Plugin slug mam-geofilters
Applies to plugin version 2.1.1+
Category Building Your App
Audience WordPress admin
Estimated time 30–40 minutes
Last verified 2026-06-03

What you’ll build

By the end of this tutorial you’ll have a working city-scoped app: one where the content a user sees is filtered to a city they pick (or to wherever they are standing). The app opens on a sensible default city, shows a location picker the user can change, and returns only the listings, offers, or posts within a search radius of the active city.

This is the natural shape for any app whose content is tied to places — a local business directory, an events app, a “what’s near me” guide. Instead of every user seeing the same flat list, each user sees the slice of your content that’s relevant to where they are.

We’ll go end to end:

  1. Enable the geofilter picker for a role.
  2. Curate the list of cities users can choose from.
  3. Set the default city, radius, and Near Me behavior the app opens on.
  4. (Optional) Drive the city list from your actual directory listings instead of the built-in list.
  5. Verify the whole experience in the app.

Each step links to a focused recipe if you want more detail on that one piece. This tutorial stitches them into a single build.

What’s powering this. The mam-geofilters plugin does the work behind the scenes: it adds the picker’s data to your app’s mobile payload — the bundle of data your app downloads from your site — and sends the active city’s coordinates plus a search radius along with every content request, so MAM Suite knows to hand back only what’s nearby. You configure all of it from WP Admin — no code required for the path in this tutorial.


Before you start

You’ll need:

  • WordPress admin access.
  • MAM Suite installed, with mam-main and mam-geofilters activated under Mobile App Manager → Software. If mam-geofilters isn’t listed, see Plugin overview: mam-geofilters for installation.
  • At least one configured user role (most apps start with mam-all).
  • The latitude and longitude of the city you want the app to open on. You can read these off most map services — the two decimal numbers in a place’s URL or its “share location” panel. Use plain decimal degrees (e.g. 37.3382, -121.8863); western longitudes and southern latitudes are negative.

A note on roles before we begin: almost every geofilter setting is stored per role. That’s a feature — different roles can open on different cities or reach different distances inside the same app — but it means you apply this tutorial once per role you want to scope. We’ll configure mam-all and call out where to repeat.


Step 1 — Enable the geofilter picker

First, turn the picker on for your role. Until you do, none of the later settings have any visible effect.

  1. Go to Mobile App Manager → App Settings and pick the role you’re configuring (start with mam-all).
  2. Open the General Settings tab.
  3. Set Use Geofilters (tsl-use_geofilters) to yes for an inline picker in the home view.
    • Alternatively, set Use Geofilters Navbar Icon Only (tsl-geofilters_show_as_icon) to yes to render the picker as a compact icon in the navigation chrome.
    • The picker appears if either setting is yes. If you turn on both, the app uses the icon presentation.
  4. Save the role.

That’s the whole on/off decision. Behind the scenes, the plugin checks these two role settings for each user and shows the picker the moment either one is yes. (Developers can override this in code — see Hook: mam_force_geofilters — though you won’t need that for this build.)

For the focused version of this step, see Recipe: Enable geofilters.


Step 2 — Curate the city list

Out of the box the picker ships with a built-in list of 57 US cities (San Jose, Oakland, New York, Los Angeles, Chicago, Miami, Dallas, …). For a city-scoped app you almost never want all 57 — you want the cities you actually serve. There are two admin surfaces for this, and they do different things.

Hide cities you don’t serve (Geofilters tab)

The fastest way to trim the picker without deleting anything:

  1. Go to Mobile App Manager → Geofilters.
  2. You’ll see a table with a Show checkbox next to every city. Checked = visible in the app.
  3. Uncheck the cities you don’t serve.
  4. Click Save Changes.

On the next request the app receives only the cities you left checked. Hidden cities aren’t lost — re-check them anytime. (Hidden cities are stored in the mam_geofilters_hidden option.)

Edit or add cities (Manage Cities page)

When you need to change what a city is — its display name, its exact coordinates, or whether it exists at all — use the Manage Cities page:

  1. Go to Mobile App Manager → Manage Cities.
  2. You’ll see an editable table with one row per city: Name, Latitude, Longitude, Active?.
  3. Edit any field. Toggling Active? off has the same effect as hiding — the entry stays in the database but is filtered out before the picker reaches the app.
  4. To add a city, fill in the empty trailing row at the bottom of the table (the page always renders one extra empty row). Repeat to add several.
  5. Click Save Changes.

Two things to watch:

  • The display name is a city’s identity across the admin UI. Don’t reuse a name that already exists — the show/hide checkboxes rely on it.
  • Coordinates must be non-zero. Entries with a latitude or longitude of 0 are silently dropped from the mobile payload. If you added a city and it’s not appearing, check the coordinates first.

A city has to be both active (Manage Cities) and not hidden (Geofilters tab) to appear in the app. For the focused version of this step, see Recipe: Manage the city list.


Step 3 — Set the default city, radius, and Near Me behavior

Now decide what the home screen opens on before anyone touches the picker, and how far its search should reach. Like everything else in this tutorial, these settings live on the role you’re editing.

3a. Default city

Set the three “default” fields so the picker has somewhere to start before the user picks a city or grants location access. Keep them in sync — the name is what the user reads, the latitude/longitude pair is what actually filters the content:

Setting Key What to enter
GeoFilter Default City Name geofilter_default_name Display name, e.g. San Jose
GeoFilter Default Latitude geofilter_default_lat Latitude, e.g. 37.3382
GeoFilter Default Longitude geofilter_default_lon Longitude, e.g. -121.8863

A mismatched name and coordinates is the most common cause of “the label says one city but the listings are from another.” Set all three to the same place.

3b. Default radius

Set GeoFilter Radius (Miles) (geofilter_radius / tsl-setting-geofilter_radius) to how far the home screen should search on first load, in miles. Match it to how spread out your content is:

  • Tight regional app: 2550
  • Statewide app: 100250
  • National app: 500+

If you leave it empty, geofilters fall back to 25 miles. Whatever you set, the resolved radius is capped at 3000 miles. (The mobile app can also send a per-request radius, which wins for that request — still under the same cap.)

3c. Bound and present the radius selector (optional)

The picker can include a radius selector the user adjusts. Constrain it so users can’t pick a distance that returns nothing or floods the screen:

Setting Key Purpose
GeoFilter Select Min Radius gf_min_radius Smallest distance a user can choose
GeoFilter Select Max Radius gf_max_radius Largest distance a user can choose

Bracket your default from step 3b — e.g. a regional app might use min 5, max 100, default 25. If you don’t want users changing the radius at all, set Hide GeoFilters radius selector (geofilters_hide_radius) to yes; the default still applies, the user just can’t move it.

3d. Near Me behavior

The picker shows a Near Me option that recenters the search on the user’s current location instead of the default city. It’s on by default and recommended — users with location access immediately see what’s around them.

To remove it (for an app organized strictly by city), set Hide Near Me button on Home screen (geofilters_hide_near_me) to yes.

Near Me depends on the device sharing its location. If a user denies location access, the app falls back to the default city from step 3a — which is exactly why setting a sensible default matters even when Near Me is on. When GPS is available, the app can prepend a Current Location entry above your cities so the user’s real position takes priority.

Save the role. For the focused version of this step, see Set up location filtering (geofilters) on your home screen.


Step 4 (optional) — Drive the city list from your directory

Everything above uses the curated list from step 2. If your app is a GeoDirectory app, there’s a better option: let the picker show the cities your listings are actually in, automatically.

When mam-geodirectory is also active, it takes over the city list entirely. It swaps out the built-in/curated list for the cities your real GeoDirectory listings actually sit in, deduplicated automatically — so the picker shows wherever you have listings, with no manual curation needed.

To use this path:

  1. Activate mam-geodirectory alongside mam-geofilters.
  2. Keep geofilters enabled for the role (step 1).

That’s it — the integration handles itself. Just know that turning it on short-circuits the curated list from step 2: once the directory takes over, it bypasses the built-in/hidden-cities path entirely. So pick one approach per app:

  • Curated cities (steps 2–3) for an app where you hand-pick the locations, or where content isn’t GeoDirectory-backed.
  • Directory-derived cities (this step) for a GeoDirectory app where the cities should track your listings.

For details and caveats (empty-region labels, query cost, excluding post types), see Integration: GeoFilters in the mam-geodirectory docs.


Step 5 — Verify the whole experience

Open the mobile app, signed in as a user in the role you configured, and walk the flow:

  1. The picker appears — inline or as the navbar icon, per step 1. If it doesn’t, recheck that Use Geofilters (or Use Geofilters Navbar Icon Only) is yes for this role and that you’re signed in as a user in it.
  2. The home screen opens on your default city — the name from step 3a, showing content within your default radius. If the listings don’t match the city name, recheck the latitude/longitude in step 3a (and 3b).
  3. The city list matches what you curated — only the cities you left visible (step 2), or your directory’s cities (step 4). Renamed cities show the new name; added cities select correctly.
  4. Switching cities refreshes the home view — picking a different city re-scopes the content to that city.
  5. Near Me recenters on the device (unless you hid it) — and the radius selector is limited to your min/max (unless you hid it), starting at your default.

If a city is missing, confirm it’s both active (Manage Cities) and not hidden (Geofilters tab), and that its coordinates are non-zero.


Step 6 — Repeat per role (if needed)

Everything you just did is stored on the role you edited. If your app serves multiple roles that should scope differently — say, members reach 100 miles and guests reach 25, or a partner role opens on a different city — repeat steps 1, 3 (and 4 if applicable) for each role. The city list curation in step 2 (Geofilters tab + Manage Cities) is app-wide, not per-role.

Going further: per-neighborhood lists. If a single city needs its own sub-list of locations — choosing a neighborhood scopes the app to that neighborhood’s venues and distance — that’s an advanced setup beyond this tutorial. See Recipe: Per-neighborhood city lists.


Recap

You now have a city-scoped app:

  • The geofilter picker is enabled for your role.
  • The picker shows only the cities you serve (curated, or derived from your directory).
  • The home screen opens on a default city with a default radius, and recenters on the user via Near Me.
  • Switching cities re-scopes the content the user sees.

From here you can layer the rest of your app on top — a city-scoped directory, offers, or events all ride on the same active-city signal you just configured.


Notes and gotchas

  • Per-role vs. app-wide. Enabling, default city, radius, and Near Me are per-role. City-list curation (Geofilters tab + Manage Cities) is app-wide.
  • Active AND not hidden. A city must be both to show. Two surfaces, both have to agree.
  • Non-zero coordinates. Entries with a 0 latitude or longitude are dropped silently.
  • Curated vs. directory-derived, not both. Activating mam-geodirectory short-circuits the curated list. Pick one per app.
  • Decimal degrees only. Use 37.3382, not degrees-minutes-seconds. Western longitudes and southern latitudes are negative.
  • Radius defaults. Empty radius → 25 miles. Hard cap → 3000 miles. The app may send a per-request radius that wins for that request.

  • Recipe: Enable geofilters — the focused version of Step 1.
  • Recipe: Manage the city list — the focused version of Step 2.
  • Set up location filtering (geofilters) on your home screen — the focused version of Step 3.
  • Recipe: Per-neighborhood city lists — advanced sub-city scoping.
  • Integration: GeoFilters (mam-geodirectory) — the directory-derived city list in Step 4.
  • Plugin overview: mam-geofilters — how the feature fits together end to end.
  • Hook: mam_force_geofilters — override the on/off decision in code.
  • Hook: mam_geofilter_radius — override the resolved radius in code.

Verification

This article was last verified against:

  • Plugin: mam-geofilters v2.1.1 (Version 26.29.1)
  • Source: mam-geofilters/mam-geofilters.phpmam_use_geofilters(), mam_geofilter_radius()
  • mam-main (provides the App Settings UI and settings cascade)
  • mam-geodirectory (optional, Step 4)
  • Geofilters user docs: Enable geofilters, Manage the city list, Per-neighborhood city lists
  • App-setting docs for geofilter_default_lat, geofilter_default_lon, geofilter_default_name, geofilter_radius, gf_min_radius, gf_max_radius, geofilters_hide_near_me, geofilters_hide_radius

Re-verify whenever the on/off settings (tsl-use_geofilters, tsl-geofilters_show_as_icon) or radius setting (tsl-setting-geofilter_radius) change, the default radius (25) or hard cap (3000) changes, the Manage Cities / Geofilters tab admin surfaces are reorganized, or the mam-geodirectory takeover of mam_geofilter_list changes.

Was this article helpful?
Contents

    Need Support?

    Can't find the answer you're looking for? Don't worry we're here to help!