Goal
Attach a special offer to a listing so it shows up in the mobile app’s home-screen feed, in the listing’s “Special Offers” detail section, and (for nearby users) in the location-aware offers list.
By the end of this recipe you’ll know how to fill in any of the four offer slots a listing carries, set start/end dates or mark an offer as always available, and replace or remove an offer later.
Prerequisites
- WordPress admin access with permission to edit the parent post type (a GeoDirectory listing, a WooCommerce
product, or another opted-in post) - MAM Suite installed, with
mam-mainandmam-special-offersactivated under Mobile App Manager → Software - The parent listing already created. Offers are children of a listing — there’s no standalone “create an offer” UI.
If mam-special-offers is not activated, see Plugin: mam-special-offers for installation steps.
How offer slots work
Every parent post that supports the meta box (any GeoDirectory post type, product, and the special_offers CPT itself) gets a Special Offers meta box with four numbered tabs — Offer 1, Offer 2, Offer 3, Offer 4.
Each tab is one offer slot. Filling in a previously empty tab and saving the listing creates a new special_offers post linked back to the listing via the special-offer-parent meta. Editing fields in a tab that already has an offer updates that offer in place.
A listing can have at most four concurrent offers from the meta box. To replace an existing offer with a different one, edit the tab in place — the system reuses the same special_offers post.
The four-slot cap is the meta-box UI limit, not a database limit. The Edit Deals tab bar button (used by the in-app form path) accepts up to 20 by default — see Hook: mam_special_offers_deals_allowed. The home-screen feed and the nearby-offers feed both query all published offers regardless of slot count.
Steps
1. Open the parent listing
Go to the parent post’s edit screen — for a GeoDirectory venue this is GeoDirectory → All Listings → {listing}, for a WooCommerce product it’s Products → All Products → {product}.
Scroll to the Special Offers meta box. You’ll see four tabs across the top, with Offer 1 selected by default.
2. Pick a slot and fill it in
Click the tab you want to use (any empty tab will do — the order doesn’t matter).
Fill in:
- Offer Title — required. Stored as the offer’s
post_title. - Subtitle — required to create a new offer. A short tagline shown beneath the title in the app card.
- Details — rich text body shown on the offer detail screen.
- Offer Image — optional. Paste an image URL; on save the plugin resolves it to an attachment ID and sets it as the offer’s featured image. If you leave this blank the offer falls back to the parent listing’s featured image.
- URL — optional. If set, the offer’s
content_typebecomesweband the front-end shortcode links to this URL instead of the parent permalink.
3. Set the offer window
You have two options:
Always Available. Tick the Always Available checkbox. Start Date and End Date will be ignored, and the offer’s exp_label in the app shows “Available now”. Use this for evergreen offers like “10% off everything”.
Date range. Leave Always Available unchecked and fill in Start Date and End Date. Both fields accept any string strtotime() understands, but the meta box defaults to today in YYYY-MM-DD. The app shows the range as Mon D, YY - Mon D, YY.
The end date is end-of-day inclusive. The plugin only drops the offer from the listing-detail section once
end_date + 1 dayis in the past. An offer withend_date = 2026-06-30is still served on the morning of July 1.
4. Save the listing
Click the parent post’s standard Update button. The offer’s special_offers post is created (or updated) on save, and meta keys are written under standard WordPress sanitization (sanitize_text_field for most, esc_url_raw for the URL, wp_kses_post for the details body).
Two parent-post defaults are applied at this point if they aren’t already set:
offer-typedefaults tonon-eventspecial-offer-featured-listingdefaults toyes(so new offers appear in the home feed)
5. Verify in the app
Open the mobile app and check three places:
- Home screen. The new offer should appear in the featured-offers feed (since
special-offer-featured-listingdefaults toyes). - Listing detail screen. The listing’s Special Offers section should include a card for the new offer with the dates you set.
- Nearby offers list. If your test device’s GPS is within 5 miles of the listing’s coordinates, the offer should show up in the nearby-offers feed.
If the offer doesn’t appear, check that the listing has valid lat / lon meta — offers without resolvable parent coordinates are excluded from the nearby feed (see Hook: mam_specials_get_post_lat if you need to override that).
Variations
Hide an offer from the home-screen feed
If you want an offer that only appears on the listing’s detail page (not on every user’s home screen), you currently need to clear the special-offer-featured-listing meta directly:
delete_post_meta( $offer_id, 'special-offer-featured-listing' );
The save handler defaults this to yes and the meta box doesn’t expose a UI for it.
Replace an offer
Don’t try to “delete then add” in two slots. Edit the existing offer tab in place — change Offer Title, Subtitle, Details, and dates as needed, then save. The same special_offers post is reused, which preserves any RSVPs already attached to it (see Recipe: Enable RSVP for a special offer).
Remove an offer
Tick the Delete Offer checkbox on the offer’s tab and save. The offer’s post_status flips to draft. It will disappear from the app immediately. The slot becomes available for a new offer.
Verification
This article was last verified against:
- Plugin:
mam-special-offersv2.1 - Source:
mam-special-offers/includes/special-offers-cpt.php(save_special_offer_meta_box_data) - Source:
mam-special-offers/includes/manage-phone-data.php
Re-verify whenever the four-tab meta box layout changes, the meta keys named in Default offer fields (in Plugin: mam-special-offers) change, the offer-type / special-offer-featured-listing save defaults change, or the end-date drop logic in mam_content_section_special_offers() changes.
Related articles
- Plugin: mam-special-offers
- Recipe: Enable RSVP for a special offer
- Recipe: Let venue owners manage offers from the app
- Hook: mam_specials_get_post_radius
- Hook: mam_specials_get_post_lat
Metadata
| Field | Value |
|---|---|
| Article type | Recipe (Admin) |
| Plugin slug | mam-special-offers |
| Applies to plugin version | 2.1+ |
| Category | Building Your App |
| Audience | WordPress admin |
| Estimated time | 5 minutes |
| Last verified | 2026-05-01 |
