Summary
A content class represents one type of mobile UI element — a Login button, a Map, a Web URL viewer, a Favorites list, a Phone Call button, etc. There are 21 content classes in mam-main/includes/content-classes/. Adding a new content class is how you give customers a new building block to assemble screens with in the no-code builder.
Each class lives in a single file. The file:
- Registers itself in the global
$local_app_content[]array withcontent_type,class, andvc_typemetadata. - Defines a class implementing the duck-typed interface below.
Class names like local_app_login_button are frozen because they appear in customer button arrays serialized into local-app-button-array*. Renaming would orphan every site’s saved instance of that button type.
The 21 content classes
| Article | Content type | Purpose |
|---|---|---|
| Content class: Login button | Login Button | App login button + auth settings |
| Content class: Logout button | Logout Button | App logout button |
| Content class: Favorites | Favorites | User’s saved items list |
| Content class: Map | Map | Geo map with markers |
| Content class: Web URL | Web URL | In-app browser to a URL |
| Content class: WP Content | WP Content | Render a single WP page/post |
| Content class: WP Post Content | WP Post Content | Detail view for a post |
| Content class: WP Post Category | WP Post Category | List view of a category |
| Content class: WP Post Category URL | WP Post Category URL | URL-driven category list |
| Content class: Onboarding | Onboarding | First-launch onboarding screens |
| Content class: Open Notifications | Notifications | Notification center button |
| Content class: Phone Call | Phone Call | Tap-to-call button |
| Content class: Share App | Share App | Share-this-app button |
| Content class: Social Media | Social Media | Social media link buttons |
| Content class: Enable Location | Enable Location | Location-permission prompt |
| Content class: Placeholder | Placeholder | Decorative spacer button |
| Content class: Home for tab bar | Home (tab bar) | Tab-bar home shortcut |
| Content class: Punch Out | Punch Out | Punch-in/out button |
| Content class: Settings Menu | Settings Menu | Settings drawer button |
| Content class: Left Menu Separator | (separator) | Left-menu visual divider |
| Content class: Manager (registry) | (registry) | Loader; require_onces every class file |
The duck-typed interface
There is no formal interface declaration yet — it’s tracked as a known refactor target. Every content class is expected to implement:
| Method | Returns | Purpose |
|---|---|---|
__construct() |
— | Often empty; some classes wire hooks here |
app_settings_categories() |
array of {title, slug} |
Tabs to show in the per-button settings UI |
app_settings() |
array of setting definitions | Field schemas for those tabs |
get_blank_content_html() |
string | HTML rendered when admin clicks “add new” |
get_content_type_form($id, $content_source) |
string | Edit-form HTML for an existing button |
create_initial_buttons($this_array) |
array | Default button rows seeded for new sites |
get_data_for_app($category) |
array | Mobile-app payload — the data the app actually receives |
A content class that omits get_data_for_app will appear in the admin UI but render nothing on the device.
Settings schema (app_settings())
Each entry describes one settings field:
array(
'category' => 'login', // matches a slug from app_settings_categories()
'title' => __( 'Require Login?', 'mam-suite' ),
'variable' => 'require_login', // option-key suffix
'type' => 'yes-no', // input widget
'id' => 'tsl-require_login', // DOM id
'environment' => 'global', // 'global' = site-wide; 'per-button' = per-instance
)
Common type values: yes-no, text, textarea, select, image, color, number. The settings UI infrastructure lives in app-settings/.
How a content class fits into the pipeline
mobile request → mam_get_phone_data() → MAM_Phone_Data_Pipeline::run()
│
▼
phase_content
│
For each button in the role's button array:
▼
resolve content_class from $local_app_content
▼
call $class->get_data_for_app($category)
▼
merge into the response
Content classes don’t typically subscribe to mam_get_phone_data_before_send directly — they’re invoked by the button-rendering loop based on button-config metadata.
Adding a new content class
- Create
includes/content-classes/local-app-<kind>-class.php. - Append your file to the
require_oncechain incontent-class-manager.php. - Register the class in the global registry:
$local_app_content['Your Type'] = array(
'content_type' => 'Your Button',
'class' => 'local_app_your_button',
'vc_type' => 'your_button',
);
- Implement the 7 interface methods.
- Optionally seed an initial instance in
create_initial_buttons()so new sites get one by default.
See Recipe: Register a content class.
Frozen surface callouts
- Class names for any content class that appears in customer button arrays are frozen. Renaming
local_app_login_buttonorphans every customer site’s saved login button. Frozen contract — do not rename without a coordinated migration of every site’slocal-app-button-array*. content_typekeys are user-facing labels in the admin UI; changing them changes what admins see.- *`local-app-button-array`** option is itself a frozen public contract.
Gotchas
- No interface enforcement. A class can ship with a missing method and break only when that method is called.
$local_app_contentis a global populated at file-include time. Any code that reads it must run aftercontent-class-manager.phphas loaded.vc_typeis a Visual Composer integration leftover and is mostly inert today, but downstream code still reads it — keep it set.
Related articles
- Recipe: Register a content class
- Recipe: Add a button
- Hook: mam_app_settings_get_buttons
- Hook: mam_get_phone_data_before_send
- Frozen public contracts reference
- One article per content class (see the table above)
Metadata
| Field | Value |
|---|---|
| Article type | Plugin Overview |
| Plugin slug | mam-main |
| Applies to plugin version | 2.1.11+ |
| Category | App Settings Reference |
| Audience | PHP developer |
| Last verified | 2026-05-02 |
