Summary
Every listing returned by mam_geodirectory_content::get_data_for_app() (alias local_app_geodirectory) is an associative array with the fields below. Some are pulled directly from the GD detail table, some are renamed for the mobile contract, and some are derived during the per-listing finalisers.
These keys are part of the frozen mobile contract. Renaming them will break deployed apps.
Where it appears
In every response from a GeoDirectory* content type:
- The directory list and map content types return arrays of these objects.
- The off-directory content type returns the same shape.
- The calendar content type returns the same shape filtered to
gd_eventposts. - The detail screen for a single listing returns one of these objects (selected by the
single_listingparameter).
The listing array is also fed back into:
mam_tab_manager(mam-main) — adds the tab bar action button list.mam_add_chat_to_detail(mam-chat-manager) — adds the chat tab info, when allowed.mam_geodirectory_final_listings(this plugin) — gives external code one last look at the full array. See Hook: mam_geodirectory_final_listings.
Core identifiers (renamed from GD fields)
| Key | Type | Source | Notes |
|---|---|---|---|
id |
int | post_id |
Renamed for the mobile contract. |
lat |
string/float | latitude |
Renamed. |
lon |
string/float | longitude |
Renamed. |
title |
string | post_title after stripslashes() and get_the_title() |
Used for sort and search index. |
post_type |
string | get_post_type($post_id) |
One of the registered GD post types (e.g., gd_place, gd_event). |
modified |
string | post_modified |
Renamed. |
rating |
string | constant '0' |
The plugin does not produce real ratings; it pins this to 0. |
raw_business_hours |
array | business_hours |
Stored before the formatted-string version is built. |
After renaming, the original keys (post_id, latitude, longitude, post_modified) are unset.
Derived strings
| Key | Type | Built in | Notes |
|---|---|---|---|
url |
string | finalize_listing_base_data() |
get_permalink($post_id), escaped. |
website |
string | Same | esc_url_raw() of the listing’s website field. For events with ticket_url, replaced with the ticket URL (forced HTTPS). |
region |
string | Same | Two-letter US/Canada abbreviation via convert_state(). District of Columbia → DC. |
state |
string | Same | Mirrors region when non-empty. |
city_state_zip |
string | Same | '{city}, {region} {zip}'. |
zip |
string | Same | ' ' (single space) when empty, to make detail rendering predictable. |
post_date |
int | Same | UTC Unix timestamp via get_post_time('U', true, $id). |
hours_one_line |
string | Same | business_hours_for_app from GD, or two spaces when empty. |
searchIndex |
string | finalize_listing_content() |
'{title} - {post_content}' — the app’s full-text search index. |
subcategories |
string[] | finalize_listing_categories() |
Names of every term and parent term assigned, plus 'My Venues' for owner/manager/staff. HTML entities are decoded. |
content |
string | finalize_listing_content() |
post_content after mam_localize_content and shortcode stripping. Set to ' ' when too short. |
post_content, post_excerpt |
string | Same | Raw equivalents. |
Owner-aware fields
| Key | Type | Notes |
|---|---|---|
can_delete |
'yes' / absent |
Set to 'yes' for admin viewers. |
can_delete_from_server |
'yes' / absent |
Same. |
contact_name |
string | Pulled from contact_name post meta when present. |
claim_status |
'claimed' / 'unclaimed' / absent |
Set when the GeoDir Claim plugin is active and the listing supports claiming. |
can_claim |
'yes' / 'no' / absent |
Inverse of claim_status. |
Marker / map fields
Built in finalize_marker_info():
| Key | Type | Notes |
|---|---|---|
marker_pin |
URL | Custom marker JSON’s icon, or the term’s ct_cat_icon, or the GD default marker. SVGs are converted to a stub PNG (images/default.png). |
marker_pin_aspect |
string | height/width of the marker image, computed from attachment metadata. |
marker_category |
'100' (constant) |
Used by the app to group markers. |
market_extension |
string | File extension of the marker image (note the spelling — frozen). |
category_icon_url |
URL | Term-level icon. |
ct_cat_icon |
URL | Category icon used in lists; SVG-converted. |
When marker_pin is shorter than 10 characters (i.e., empty/garbage), the marker keys are unset entirely so the app falls back to its default pin.
Image fields
Built in finalize_listing_images() (and seeded by migrate_images()):
| Key | Type | Notes |
|---|---|---|
image |
string | Sanitized filename. |
imageurl |
URL | Featured image URL. Narrow no-break space ( ) characters are URL-encoded to %E2%80%AF. |
image_id |
int | Attachment post ID, or ' ' when not resolvable. |
extension |
string | File extension. |
img_width, img_height |
string | Pixel dimensions from attachment metadata. |
imageSizeFactor, imageurl_aspect |
string | Aspect ratios. |
featuredRespectAspectRatio |
'yes' |
When set, the app uses the natural aspect. |
photo_array |
array | Additional images; suppressed when mam_gd_hide_photo_array === 'yes'. Each entry is {src, aspect}. |
When the listing has no featured image, the entries from static_placeholder (built from the local-app-images-placeholder option) are merged in.
Social platform fields
Each registered social platform key (from mam_social_platform_ids filter on mam-main) is added to the listing only when:
- The listing’s GD detail table actually has a column with that key (cached via
gd_custom_field_exists). geodir_get_post_meta($id, $key)returns a non-empty value.
See Listing detail content sections — social_media for how these are rendered. Hook: mam_gd_social_icons_only lets you suppress text labels per listing.
Event-only extensions
When post_type === 'gd_event', finalize_event_listing() populates:
| Key | Type | Notes |
|---|---|---|
event_data |
array | Set during processing then unset before the listing is returned. |
event_records, activities |
array | Always seeded with sentinel values. |
event_registration |
mixed | Pulled from geodir_eventregistration. |
start_end_dates |
string | 'Date: Aug 12' or 'Dates: Aug 12 - Aug 14 9:00am to 5:00pm'. |
start_end_times |
string | 'Time: All Day' or 'Time: 9:00am to 5:00pm' for recurring events. |
start_date, sort_date |
string | Used to sort events. |
end_date |
int | Unix timestamp of {end_date} 23:59:59. |
event_start_stamp, event_end_stamp |
int | Same as start_date/end_date, exposed for UI use. |
dateList |
string[] | Dates the event recurs on. |
venue |
string | The linked venue’s title (when present in cp_link_posts). |
venue_id |
int | The venue’s post ID. |
event_ids |
int[] | (For non-event venue listings) the IDs of events linked to this listing. |
content_type |
'web' |
Set when mam_gd_open_web_on_event_card option is 'yes', telling the app to open the ticket URL in a web view. |
Past events (end date in the past) are dropped at this stage.
Sort fields
| Key | Type | Notes |
|---|---|---|
distance |
float | Haversine miles from the request’s lat/lon to the listing. Only populated when geofiltering is active. |
Cache marker
| Key | Type | Notes |
|---|---|---|
is_cached |
'yes' / absent |
Set transiently when populating the per-request cache; unset before the listing is returned to the app. |
Tab/finalise fields (transient)
These exist only between the per-listing finaliser and the final return. Don’t depend on them in mam_geodirectory_final_listings:
tab_type,tab_location— set somam_tab_managercan decide which tab bar to attach. Unset after.isCached— used during cache-hit replay.
Common recipes
- Add a custom field to every listing. Hook Hook: mam_geodirectory_final_listings and walk the array, or add a post-meta key on save that the GD detail table picks up. Anything in the detail table is exposed automatically (under its column name).
- Override coordinates. Currently only available via the special-offers integration (
mam_specials_get_post_lat/_lon); for the directory itself, write tolat/lonpost meta and the GD save pipeline updates the detail table. - Drop one listing. Use Hook: mam_geodirectory_skip_record — the listing array is short-circuited before any finalisers run.
- Replace the whole list. Use Hook: mam_geodirectory_explcit_listings (note the typo in the name).
Gotchas
- Empty strings are stripped.
clean_empty_strings()removes anystringkey whose value is''. Booleans and arrays are untouched. If your code relies on a key always being present, set it to a single space or a default array value. marker_pinSVGs are replaced with a default PNG. The plugin’ssvg_to_png()does not currently render SVG → PNG; it returns a stub default image. SVG markers will not appear in the app.regionmay already be a 2-letter abbreviation. Theconvert_statehelper falls through tostrtoupper($state)for two-character inputs. If your data is mixed, the value is normalised either way.- Narrow no-break space in image URLs. The unicode
(NARROW NO-BREAK SPACE) sometimes appears in WordPress image filenames. The plugin pre-encodes it to%E2%80%AF. Don’t double-encode downstream. gd_custom_field_existscaches per request. Adding a column at runtime won’t be picked up until the next request.
Verification
This article was last verified against:
- Plugin:
mam-geodirectoryv2.1.5 - Source:
content-classes/local-app-geodirectory-v2-class.php—get_data_for_app()and helpers
Re-verify whenever the per-listing finaliser methods (finalize_listing_*) are renamed or restructured, the field-renaming step in get_directory_data() changes, the SVG-to-PNG conversion is implemented for real, or new content types are added that bypass these finalisers.
Related articles
- Plugin: mam-geodirectory
- Content type: GeoDirectory list and map
- Listing detail content sections
- Listing tab bar buttons
- Hook: mam_geodirectory_final_listings
- Hook: mam_geodirectory_skip_record
- Hook: mam_geodirectory_explcit_listings
- Hook: mam_gd_date_format
- Hook: mam_gd_social_icons_only
- Hook: mam_gd_events_exclude_from_map
Metadata
| Field | Value |
|---|---|
| Article type | JSON Key Reference |
| Plugin slug | mam-geodirectory |
| Applies to plugin version | 2.1.5+ |
| Category | App Settings Reference |
| Audience | PHP developer |
| Last verified | 2026-05-01 |
