Roles and audiences: how per-role settings shape what each user sees

Why MAM is role-aware

A MAM app isn’t really one app — it’s a different app for every kind of person who opens it.

Think about who might open it: an anonymous visitor browsing the storefront, a logged-in member, a business owner managing their own listing, an administrator checking the whole thing over. Each of them needs something different. The anonymous visitor should see a “Sign in” prompt where the member sees their account; the owner should see an “Edit my listing” button that nobody else does; and the admin should be able to look at exactly what any of them sees, without logging in and out four times.

MAM handles this by making roles a first-class dimension of every setting. Most settings — button visibility, layout, login requirements, theme details, the contents of the tab bar — can be stored once globally or overridden per role. When the app asks the server “what should I show?”, the server answers through the lens of who is asking. The upshot: the same WordPress site produces a tailored app for each audience, with no separate builds and no per-user code.

This is the no-code version of something every mobile product needs — audience segmentation. In MAM, it isn’t a feature you bolt on; it’s baked into how the settings system works.

Roles vs. audiences

Two ideas get conflated here, so it’s worth pulling them apart.

A role is the precise, technical piece: a WordPress role slug such as subscriber, administrator, or a custom role contributed by a sibling plugin (a listing-owner role from the directory plugin, for example). Every app user resolves to exactly one MAM role per request.

An audience is the human-facing grouping you actually design for. In practice MAM apps tend to think in four audiences:

  • Anonymous — someone using the app without signing in.
  • Member — a signed-in everyday user (most commonly the subscriber role).
  • Owner — a signed-in user with elevated, content-specific privileges (a business owner, a listing manager, a contributor), usually backed by a custom role.
  • Admin — someone with site-management privileges, who also gets the ability to preview the app as any of the above.

Audiences are how you talk about your design intent; roles are how MAM actually implements it. So when you “set this up per role,” what you’re really doing is giving each audience its own version of the app.

How a setting resolves: the cascade

Underneath all of this is a single resolution path every setting flows through. When code needs a value, it never reads an option directly — it asks the settings system, passing along the current role and category. The settings system walks a fixed cascade and hands back the first value it finds:

1. Per-button override   — a value stored on a specific button, if asked in a button context
2. Per-role override     — a value set specifically for the current role
3. Global setting         — the site-wide value
4. Default                — the fallback the caller supplied

The most specific scope always wins. A per-button value beats a per-role value, a per-role value beats the global value, and if nothing’s been set anywhere, the caller’s default kicks in. Picture it like a building: global is the color painted on the whole structure, per-role repaints one floor, and per-button repaints a single door. The door wins on that door, the floor wins everywhere else on that floor, and the building’s original color shows through wherever nobody has repainted.

A few things follow from this design:

  • You only override what differs. Configure the app once globally, then add per-role overrides only for the handful of things a given audience should see differently. Everything you leave alone is simply inherited from global — which keeps role configuration small and easy to maintain.
  • The cascade lives in one place. Fallback resolution happens centrally rather than being re-implemented wherever it’s needed, so any part of the suite that reads a setting gets the same role-aware behavior for free.
  • The same key resolves to different stored rows. Per-role and global values aren’t separately-named options — they’re rows in one settings table, told apart by a role column. A per-role override is just the row tagged with that role; the global value is the row tagged with the built-in mam-all sentinel, meaning “applies to everyone, no specific role.” The settings system writes and matches the right row for you, so you can think in terms of “set this for the subscriber role” and never worry about the storage underneath.

Per-button settings are the most specific layer, and they work a little differently: they live inside the button’s own record rather than in a standalone option. That’s why “per-button” sits at the top of the cascade — it’s the narrowest possible scope, a value attached to one button rather than to a whole role.

How MAM decides which role you are

None of this works unless MAM knows who’s asking, so that gets figured out early in every app-data request:

  1. The app identifies itself with a token. Each request from the app carries an identifier that maps to a specific WordPress user, and if a matching user turns up, that user becomes the app user for the request.
  2. No token, no user — you’re anonymous. With no signed-in user, the request is treated as the anonymous audience and resolves against anonymous/global settings.
  3. The user’s role is matched against the app’s allowed roles. MAM doesn’t automatically trust every WordPress role — an administrator decides which roles are managed by the app at all, in Mobile App Manager → User Roles, where each WordPress role has a “manage this role” toggle. The request looks through the user’s WordPress roles and picks the first one the app is configured to manage; that becomes the MAM role used for the rest of the request. Turning a role on is also what makes it eligible to carry its own buttons and per-role overrides — the managed-roles list and per-role configuration are really two sides of the same idea.
  4. Unmanaged roles are turned away. If a user has no role the app is set up to handle, they don’t get an app session — login is refused, with a message that their role isn’t set up on the app. This is the gate that keeps an unrelated WordPress role from accidentally getting an app experience, and it means an administrator who was never added to the managed roles can’t simply log into the app.

New accounts created through the app get a default role (typically subscriber) unless you’ve configured otherwise, so a fresh sign-up lands in the member audience by default.

The four audience views in practice

With the cascade and role resolution in mind, here’s what each audience actually experiences in the app.

Anonymous. No token resolves to a user, so the request runs against the anonymous/global configuration. This view typically leads with sign-in or sign-up prompts and hides anything that assumes an account. It’s the “front door” of the app — what an app-store reviewer or a curious first-time visitor sees.

Member. A signed-in everyday user, most often subscriber. Their app is the global configuration plus whatever overrides you’ve set for their role — usually an account area, personalized content, and member-only buttons the anonymous view doesn’t include.

Owner. A signed-in user on a more privileged, content-specific role (commonly a custom role from a sibling plugin). Owners inherit everything a member sees, then add capabilities tied to their content — management buttons for a listing or business they control, for example. The cascade makes this clean: you don’t rebuild the member app for owners, you just layer the extra owner-only overrides on top.

Admin. A site administrator gets their own role-scoped view, but the more useful power is preview, or “cloning.” An admin can tell the app to render as a different role, and the system flags the request as a cloning request, resolving settings for the role being previewed rather than for the admin’s own role. This is how you check the anonymous, member, or owner experience without juggling a stack of test accounts. One thing worth knowing: while previewing, the resolved role is the target role, so anything that needs the admin’s real identity has to check the cloning flag explicitly rather than assume the role string.

Administrators get a related convenience too: content built for one role can be copied to another role as a starting point, so you can stand up a new audience by cloning an existing one and adjusting the overrides from there.

How this connects to the rest of MAM

Role-awareness isn’t a standalone feature — it’s the foundation the rest of the builder sits on:

  • Buttons and layout are role-scoped, which is how the same tab bar or menu can show different entries to different audiences. Per-button settings ride at the top of the cascade.
  • Login and access settings (whether a screen or action requires sign-in) are role-aware too, which is what lets the anonymous view fall back to a sign-in prompt where a member sees the real thing.
  • Sibling plugins plug their own settings — and sometimes their own roles — into the same cascade, so a directory, store, or membership add-on inherits role-awareness automatically instead of having to invent its own segmentation.

In short: you design audiences, MAM implements them as roles, and the cascade resolves every setting through the role of whoever is asking. Configure once globally, override only what each audience needs differently, and preview the result as any role before you ship.

  • Settings cascade overview — the read/write path and the exact resolution order.
  • Per-button and per-role settings — where each scope is stored and the gotchas around per-button (blob-shaped) storage and cloning admins.
  • Button array storage — how role-scoped button definitions are kept.
  • App Setup recipes — where you actually toggle per-role overrides in the admin.

What’s next

  • To configure a specific audience, set its per-role overrides in the relevant App Setup section, leaving everything else to inherit from global.
  • To check your work, use admin preview (“cloning”) to render the app as the anonymous, member, or owner role.
  • To stand up a brand-new audience quickly, copy an existing role’s content and adjust only what differs.
Was this article helpful?
Contents

    Need Support?

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