Listing detail content sections

Primary responsibility

The mobile app’s listing detail screen is composed of “content sections.” Each section is a record with a title, a content payload, a type discriminator, and a show_title flag. mam-geodirectory contributes seven section types via the mam_content_section_* filter family (owned by mam-main). Admins enable, reorder, and rename them per content type in the App Settings → Layouts UI; this article documents what each section contains when it is enabled.

The seven section types are registered in mam_geodirectory_content::default_content_sections() and built by mam_gd_content_blocks in includes/mam_gd_content_blocks.php.


The seven sections

type Default title Built by When it appears
check_in_fav “On Screen Favorite” mam_content_section_check_in_fav Only for users who are not owner/manager/staff of the listing. Renders the favorite/check-in widget.
post_content “Post Content section” mam_content_section_post_content When the listing’s content is longer than 4 characters. Sends the listing’s content field as the section payload.
address_section “Address section” mam_content_section_address_section Always (unconditionally). Section type main_address — the app renders the listing’s address from the listing-row fields.
business_hours “Business Hours” mam_content_section_business_hours When business_hours is non-empty. Renders an HTML table of opening hours, deduplicating closed days.
social_media “Social Media” mam_content_section_social_media When at least one social-platform key is populated on the listing.
events “Events or Event Venue” mam_content_section_events For listings with linked events (via cp_link_posts) when not in events-only mode. Each linked event becomes a card.
event_details “Event Details” mam_content_section_event_details For gd_event posts only. Contains start_end_dates, start_end_times, and (when present) the venue name.

Each filter receives $sections, $data_array, $show_title, $title and returns a (possibly extended) $sections array. None of them mutate the listing’s fields — they only append to the section list.


Section payloads

check_in_fav

[
    'title'      => $title,            // default 'Main address' (intentionally — the section is title-shadowed by the address block)
    'content'    => '',
    'type'       => 'check_in_fav',
    'show_title' => $show_title,
]

The section is suppressed for owners/managers/staff because they have admin-style buttons instead (the favorite widget would conflict with management UI).

post_content

[
    'title'      => $title,            // default 'Description'
    'content'    => $data_array['content'],
    'type'       => 'main_desc',
    'show_title' => $show_title,
]

content is the post’s post_content after mam_localize_content (translation hook from mam-main) and shortcode stripping (a regex that removes [ ... ] blocks; apply_filters('the_content', ...) is then run). If the result is shorter than 4 characters the section is omitted entirely.

address_section

[
    'title'      => $title,
    'content'    => '',
    'type'       => 'main_address',
    'show_title' => $show_title,
]

The app renders the address from the listing’s street, city, state, region, zip, lat, lon fields. The section payload itself is empty.

business_hours

[
    'title'      => $title,
    'content'    => '<table style="width:100%">...</table>',
    'type'       => 'html',
    'show_title' => $show_title,
]

The HTML is built from geodir_schema_to_array() of the listing’s business_hours field, formatted as Mon | 9:00am - 5:00pm rows. Days where opens === closes are dropped.

social_media

[
    'title'      => $title,
    'content'    => [
        ['key' => 'facebook',  'label' => 'Facebook',  'icon' => 'facebook',  'value' => '...'],
        ...
    ],
    'type'       => 'social',
    'show_title' => $show_title,
]

Only platforms with a populated value on the listing are included. Hook: mam_gd_social_icons_only per-listing toggles whether labels are hidden in favor of just the icon.

events

For listings (non-event), this enumerates the events linked to the listing via cp_link_posts (where post_id is an event and linked_id is this listing). Each event becomes a card object:

[
    'id'    => $event_id,
    'title' => 'Live Music Friday',
    'image' => '...',
    'date'  => 'Aug 12, 2026',
    ...
]

Cards are run through Hook: mam_geodirectory_event_card before being added to the section.

event_details

For gd_event posts:

[
    'title'      => $title,
    'content'    => 'Aug 12 — 9:00am to 5:00pm @ Joe's Coffee',
    'type'       => 'event_details',
    'show_title' => $show_title,
]

The string is composed from start_end_dates, start_end_times, and the linked venue’s title (if any).


How the sections appear on screen

Order is admin-controlled — go to App Settings → Layouts → {Content type} → Detail. The default ordering is the order the sections are registered (check_in_fav, post_content, address_section, business_hours, social_media, events, event_details). Each section can be enabled/disabled and given a custom display title.

Admins can also add non-mam-geodirectory-owned sections — a chat section (from mam-chat-manager), a special-offers section (from mam-special-offers), and so on. Those are documented in their owning plugin.


Permissions awareness

mam_gd_content_blocks uses the shared mam_gd_user_roles trait to resolve, for each request, whether the current user is the listing’s owner, a manager, staff, or admin. Two sections currently use that information:

  • check_in_fav is hidden for owner/manager/staff.
  • (Several non-section behaviors elsewhere in the plugin also flow from this — see Listing tab bar buttons and Integration: Chat Manager.)

The trait reads is_admin from $this->allow_admin_to_do_stuff, but the content-blocks class does not currently set that property in its constructor (mam_gd_tab_bar_buttons does). The PLUGIN_AUDIT.md flagged this; in practice it means admins are not specially treated by the content-block sections — they’re treated as “not owner / not manager / not staff” and see the same sections as a regular subscriber. This is generally desirable on the detail screen.


Gotchas

  • Section list is determined per request. A change to the user (logging in/out, gaining/losing manager access) changes which sections appear immediately on the next data fetch.
  • address_section is always included even when no address fields are populated. The app handles empty addresses gracefully; if you need to suppress it conditionally, drop the section in a downstream filter.
  • business_hours HTML uses inline styles. Don’t rely on app-side CSS overrides to restyle it without checking the rendered HTML; the font-family: Roboto is hard-coded.
  • Events section is suppressed in events-only mode. The calendar content type doesn’t render this section.

Verification

This article was last verified against:

  • Plugin: mam-geodirectory v2.1.5
  • Source: includes/mam_gd_content_blocks.php
  • Source: content-classes/local-app-geodirectory-v2-class.phpdefault_content_sections()

Re-verify whenever a section type is added or removed in default_content_sections(), the mam_content_section_* filter signatures change in mam-main, or the role-trait wiring in mam_gd_content_blocks is changed.


  • Plugin: mam-geodirectory
  • Content type: GeoDirectory list and map
  • Listing tab bar buttons
  • Mobile listing data shape
  • Hook: mam_geodirectory_event_card
  • Hook: mam_gd_social_icons_only
  • Hook: mam_gd_date_format

Metadata

Field Value
Article type Screen Reference
Plugin slug mam-geodirectory
Applies to plugin version 2.1.5+
Category App Settings Reference
Audience WordPress admin
Last verified 2026-05-01
Contents

    Need Support?

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