Summary
The notification-type registry is a filter-driven array. Every notification type — bundled or sibling-plugin — registers its definition by hooking mam_notification_list. The dispatcher looks up $message['message_type'] against this registry to:
- Resolve which channels to send through (per-channel opt-in option keys + the type’s
default_on) - Apply the type’s templates (subject, body) with replacement tokens
- Surface the type in Mobile App Manager → Notifications → Settings
Registration shape
add_filter( 'mam_notification_list', function ( array $data ): array {
$data[] = array(
'source' => 'mam-my-plugin',
'title' => 'Order Shipped',
'slug' => 'mam-my-plugin-order_shipped',
'replacements' => array( 'order_id', 'tracking_number', 'user_login' ),
'default_content' => 'Your order [order_id] has shipped. Track: [tracking_number]',
'default_on' => array( 'email', 'push' ),
'description' => 'Sent when an order is fulfilled.',
);
return $data;
} );
Field reference
| Field | Type | Purpose |
|---|---|---|
source |
string | Plugin slug — used for grouping in the admin UI |
title |
string | Human-readable title shown in the admin |
slug |
string | Unique identifier. Becomes the message_type value when firing the notification. Convention: <plugin-slug>-<event-name> |
replacements |
array | List of replacement-token names available in the template (without brackets) |
default_content |
string (optional) | Default body template |
default_on |
array (optional) | Channels enabled by default — any of email, sms, push |
description |
string | Admin-facing explanation |
Bundled core types
Registered by mam_notifications_list::mam_notification_list():
| Slug | Title | Replacements | Default channels |
|---|---|---|---|
mam-user-roles-welcome_email |
User Roles – Welcome Email | ID, user_login, user_nicename, user_email, user_url, user_registered, display_name, first_name, last_name, nickname, description |
(none) |
mam-user-roles-lost_password |
User Roles – Lost Password | passwordcode |
|
mam-user-roles-login-with-email |
User Roles – Signup Email Verification | passwordcode |
|
mam-push-notification |
General Push Notification | title, content |
(none) |
Per-channel opt-in option keys
For each registered slug <slug>, the dispatcher checks:
tsl_notification_email_status_<slug>— email enabled?tsl_notification_text_status_<slug>— SMS enabled?tsl_notification_pn_status_<slug>— push enabled?
⚠️ The dispatcher reads the legacy tsl_* prefix even though Phase 3 documented these as renamed to mam_*. The migration framework’s option aliases handle both names — reading either returns the same value. The code uses the legacy prefix.
If neither the option nor the type’s default_on includes a channel, the dispatcher skips it.
Per-channel template option keys
For each registered slug:
tsl_notification_subject_<slug>— email subject (and SMS preview)tsl_notification_email_text_<slug>— email bodytsl_notification_pn_text_<slug>— push bodytsl_notification_text_text_<slug>— SMS body
The admin UI writes these.
Common recipes
Register a type with both email and push enabled by default:
add_filter( 'mam_notification_list', function ( $data ) {
$data[] = array(
'source' => 'mam-my-plugin',
'title' => 'New Reservation',
'slug' => 'mam-my-plugin-new_reservation',
'replacements' => array( 'reservation_date', 'reservation_time', 'user_login' ),
'default_on' => array( 'email', 'push' ),
'description' => 'Sent when a new reservation is created.',
);
return $data;
} );
Fire a registered type:
do_action( 'mam_notification_send_message', array(
'message_type' => 'mam-my-plugin-new_reservation',
'recipient_id' => $owner_id,
'replacements' => array(
'reservation_date' => '2026-05-15',
'reservation_time' => '7:30 PM',
'user_login' => $user->user_login,
),
) );
Gotchas
- Slug collisions are silently catastrophic — if two plugins register the same slug, the dispatcher uses whichever wins the filter ordering, and the other plugin’s templates are ignored. Always prefix with your plugin slug.
- Replacements without brackets in the registry; with brackets in templates (
[user_login]). default_onis a default, not a force-on. Admins can toggle it off in the UI.- The 4 bundled types can’t be unregistered safely — they’re load-bearing for the bundled login/registration/lost-password flows.
- 68+ subscribers — adding a type means it appears in the admin UI immediately; removing one mid-cycle leaves the per-channel option keys orphaned (but not harmful).
Related articles
- Notifications overview
- Notification channels: email, SMS, push
- Notification template replacements
- Recipe: Register a notification type
- Hook: mam_notification_list
- Hook: mam_notification_send_message
Metadata
| Field | Value |
|---|---|
| Article type | JSON Key Reference |
| Plugin slug | mam-main |
| Applies to plugin version | 2.1.11+ |
| Category | App Settings Reference |
| Audience | PHP developer |
| Last verified | 2026-05-02 |
