template can name, the keys each one reads, the values it accepts, the item types and containers they
produce, and how a template value is translated into what the member sees. Every key, value, type and default in the
tables is checked against the app's code by automated tests, apart from the points listed under
How far to trust this page. For worked examples and the reasoning behind individual keys, see the
Item Template JSON — Admin Reference.
containerType chooses its layout
(section 7) and holds an ordered list of items.template is static: it is shown as written. A bare page key in its
link or ctaLink is expanded into the in-app route.template is resolved in this order:
contentType in the template: the item is dropped.hidden, visibleMecs,
hiddenMecs, hiddenUserTypes; section 3). An item that fails
any of them is removed.contentType
(section 2). If there is one, it fetches the data, applies the template's keys and
builds rows. The rows it builds take the template's renderType as their itemType. The two
sectioned content types are the exception for their headings: the hotel directory's filter bar and airport headers, and
the multi-roster's committee headings, have fixed item types, and only the hotel and person rows take
renderType. If the adapter needs a renderType and none is given, or a required key is
missing or malformed, or nothing comes back, the item produces no rows. The page still renders.{placeholders} are filled in for the signed-in member, and route fields are
expanded (section 5).itemType chooses the component that draws it (section 6).itemType or
containerType removes that one item or container, and never breaks the page. An unknown
contentType is a content type with no adapter, so by step 3d the item is dropped unless it has something to
show; if it does, it still appears as a plain card.contentType, itemType, containerType and renderType
must match exactly, including case: documentitem is not DocumentItem and finds no adapter. Values
such as filterType, parentFilterType and hiddenUserTypes are matched ignoring case.The value of template.contentType. Produces is what it turns into on the page. renderType shows whether the key is required, the default used when it is left out, and the item types it is authored with today.
| Content type | Status | Produces | renderType | What it does |
|---|---|---|---|---|
ButtonCard | Styling only (no fetch) | Nothing new: restyles the item it is on | optional | No fetch. Attach it to a plain Button item to draw it as the branded stripe button. The item keeps its own itemType unless renderType is set. It is kept only if the item has a title, text, label, image or link of its own, or the template has a title, description, eyebrow or image (a link or action in the template alone does not count). |
Committee | Live | A row per record | optional; default CardSmall; authored with CardSmall | The MEC's committees, one row each. Only parent committees are listed: the per-station LEC variants are removed. Sorted alphabetically by name unless featuredCommittees sets the order. |
ContactItem | Live | A row per record | required; authored with ContactCard | People as contact rows: one committee's volunteers, or the signed-in pilot's own LEC reps or MEC officers. A grouping key is accepted in existing content but nothing reads it. |
DocumentItem | Live | A row per record | required; authored with HeroCard, CardSmall, CardText | Documents from the document library, filtered by category or grouping. One row per document, and a document filed under several categories still shows once. |
DynamicList | Not registered: do not use | A row per record | required | A server-driven list read from the items query. The adapter exists and is tested but is not registered in the app, so this content type has no adapter. An item that uses it is dropped unless it has something to show of its own (a title, text, label, image or link on the item, or a title, description, eyebrow or image in the template), in which case it shows as a plain card with no list rows. Do not author it. |
HeroCard | Styling only (no fetch) | Nothing new: restyles the item it is on | optional | No fetch. Attach it to a HeroCard item to type the title, image and action into the template instead of on the item. The item keeps its own itemType unless renderType is set. It is kept only if the item has a title, text, label, image or link of its own, or the template has a title, description, eyebrow or image (a link or action in the template alone does not count). |
LecLink | Live | One row | optional; default CardSmall; authored with CardSmall | One link row to the signed-in pilot's own LEC page, titled with their station code. Nothing in the template chooses the LEC: it is always the pilot's own. |
MecHotelDirectory | Live | Headers and rows in sections | optional; default MecHotelRow; authored with MecHotelRow | The signed-in pilot's MEC crew-hotel directory: a search field, then for each airport a header followed by that airport's hotel rows. It reads no template keys, and it ignores isFavoritable; the pilot's MEC decides what shows. |
PilotCard | Live | One row | optional; default PilotCard; authored with PilotCard | The signed-in pilot's greeting card: a station header and a contract link. It fetches nothing; it reads the pilot's own sign-in. A signed-out visitor gets a plain welcome, and a French page gets the French greeting. |
PodcastEpisode | Live | A row per record | required; authored with HeroCard, CardSmall | Episodes from an RSS podcast feed, newest first. Episodes carry no artwork of their own, so the card draws its placeholder art. |
RosterItem | Live | Headers and rows in sections | optional; default ContactCard; authored with ContactCard | Several committees' rosters at once: a heading per committee followed by that committee's people, in the order the codes are listed. The app picks the roster by this content type, so attach it to an item whose itemType is MultiCommitteeRoster. |
No fetch. Attach it to a plain Button item to draw it as the branded stripe button. The item keeps its own itemType unless renderType is set. It is kept only if the item has a title, text, label, image or link of its own, or the template has a title, description, eyebrow or image (a link or action in the template alone does not count).
| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
variant | string | no | alpa, alpa-diagonal | The button look: alpa and alpa-diagonal draw the pointed full-width treatments. Leave it out for the standard icon button. This is how most live Button items get their look. It applies to an item whose type is Button. |
The MEC's committees, one row each. Only parent committees are listed: the per-station LEC variants are removed. Sorted alphabetically by name unless featuredCommittees sets the order.
CardSmall; authored with CardSmall| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
action | string | no | any | The route each committee row opens, filled in per row. {Id} is the committee's code and {Title} its name, as well as {mec} and {lec}. Without action a row opens the committee's own link. |
searchFilter | string | no | any | Sort and limit, written like a query string. The list is ascending by name by default. The only way to reverse it is sort_by=name together with order=desc; order alone does nothing. limit caps the count. Example: ?sort_by=name&order=desc&limit=10. |
featuredCommittees | object of strings | no | any | A curated subset in exactly the order listed. Each key is a committee code or name and each value is that row's icon URL. When present it replaces searchFilter and the alphabetical order. A key that matches nothing is skipped. An empty icon is allowed: the committee is listed with no image, and a map whose icons are all empty is still the curated list. |
featuredCommitteePages | object of strings | no | any | Each key is a committee code or name and each value is the content page key for that committee's page. It takes effect only when action is also set, because the page key is added to the action route as ?pageKey=. A committee with no entry falls back to a page key guessed from its name, which is wrong whenever the short name differs. |
People as contact rows: one committee's volunteers, or the signed-in pilot's own LEC reps or MEC officers. A grouping key is accepted in existing content but nothing reads it.
ContactCard| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
filterType | string | yes | RosterCode, LecReps, MecReps | What to list. RosterCode lists one committee's volunteers. LecReps lists the pilot's own LEC reps. MecReps lists the pilot's own MEC officers. Any other value, or none, skips the item. |
filterValue | string | when filterType is RosterCode | any | For RosterCode, the committee's code (comm_cd); with a blank value nothing shows. It is ignored for LecReps and MecReps. The codes live content uses follow a convention (seen in 994 live codes): the page's MEC code, then 2 to 4 letters, digits or &, then 5 digits. That is a habit of the content, not a rule the app checks. |
grouping (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
Documents from the document library, filtered by category or grouping. One row per document, and a document filed under several categories still shows once.
HeroCard, CardSmall, CardText| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
filterType | string | yes | Category, Grouping | Category filters by one category name. Grouping filters by a grouping name, which spans categories. Any other value, or none, skips the item. |
filterValue | string | when filterValues is not given | any | The category name, or the grouping name (for example LOA or MOU). With neither this nor filterValues the item shows nothing. |
filterValues | array of strings | when filterValue is not given | any | Several categories or groupings in place of filterValue. Their documents are merged before docType and searchFilter apply, so a limit counts across all of them. |
category | string | no | any | With filterType Grouping, an explicit category to read. Without it the grouping is filtered across all categories. |
parentFilterType | string | no | MEC, LEC | Reads the signed-in member's own MEC or LEC documents instead of the national ones. It applies only when parentFilterValue is also given; with one but not the other, the national documents are read, with no error. |
parentFilterValue | string | when parentFilterType is set | any | Any non-blank value, for example ual. It switches parentFilterType on. It is not sent as the document scope: the app reads the signed-in member's own MEC or LEC set. |
docType | string | no | any | Narrows the result to documents of one type. Give one value; the comparison ignores case, and the app accepts any string. Live content uses the values in knownValues. |
searchFilter | string | no | any | Sort and limit, written like a query string. Only sort_by=date sorts: with order=desc newest first, otherwise oldest first, and undated documents last. Any other sort_by, or none, keeps the order the documents came in, and order alone does nothing. limit caps the count. Example: ?sort_by=date&order=desc&limit=3. Live content uses limits of 3, 5, 10, 20 and 25. Other spellings, such as by:date-direction:desc-top:20, are not read: the list gets no sort and no limit. |
Not registered. The app has no adapter wired for this content type, so it is treated as one with no adapter (step 3d). Do not author it.
A server-driven list read from the items query. The adapter exists and is tested but is not registered in the app, so this content type has no adapter. An item that uses it is dropped unless it has something to show of its own (a title, text, label, image or link on the item, or a title, description, eyebrow or image in the template), in which case it shows as a plain card with no list rows. Do not author it.
| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
scope | string | no | any | The items scope to read. |
category | string | no | any | The category to read. |
filterValue | string | no | any | The filter value to read. |
searchFilter | string | no | any | Only limit is used. sort_by and order are ignored. |
action | string | no | any | The route each row would open, filled in per row ({Id} and the other row properties, as well as {mec} and {lec}). |
No fetch. Attach it to a HeroCard item to type the title, image and action into the template instead of on the item. The item keeps its own itemType unless renderType is set. It is kept only if the item has a title, text, label, image or link of its own, or the template has a title, description, eyebrow or image (a link or action in the template alone does not count).
No keys of its own beyond the common ones.
One link row to the signed-in pilot's own LEC page, titled with their station code. Nothing in the template chooses the LEC: it is always the pilot's own.
CardSmall; authored with CardSmall| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
image | string | no | any | The seal image path. It may contain only {airport} (the member's base airport, lower-case), {lec} (their LEC code) and {mec} (their MEC, upper-case here, unlike elsewhere), for example .../sb2-{airport}{lec}.jpg. Any other token, such as a property of the row, leaves the item with no image. Most sites use one shared icon, a plain URL with no placeholder (https://shared.alpa.org/Portals/27/alpa-app/icons/lec-icon.svg), which the card draws on its icon tile. |
cornerRadiusToken | string | no | any | Theme token for the card's corner radius. |
parentFilterType (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
parentFilterValue (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
filterType (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
filterValue (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
iconBackgroundToken (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
The signed-in pilot's MEC crew-hotel directory: a search field, then for each airport a header followed by that airport's hotel rows. It reads no template keys, and it ignores isFavoritable; the pilot's MEC decides what shows.
MecHotelRow; authored with MecHotelRowNo keys of its own beyond the common ones.
The signed-in pilot's greeting card: a station header and a contract link. It fetches nothing; it reads the pilot's own sign-in. A signed-out visitor gets a plain welcome, and a French page gets the French greeting.
PilotCard; authored with PilotCard| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
variant | string | no | alpa | alpa draws the ALPA-branded always-pointed card. Leave it out for the standard card. |
action | string | no | any | Where the contract link goes. Used only when the member has a contract link. |
ctaLink | string | no | any | The call-to-action target, under the same condition as action. |
filterType (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
filterValue (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
iconColorToken (ignored) | string | no | any | Sent by live content, but the adapter does not read it. Accepted so existing content stays valid; do not offer it for editing. |
Episodes from an RSS podcast feed, newest first. Episodes carry no artwork of their own, so the card draws its placeholder art.
HeroCard, CardSmall| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
filterType | string | yes | FeedUrl | Must be FeedUrl. Anything else skips the item. |
filterValue | string | yes | any | The feed's URL. |
searchFilter | string | no | any | Only limit is used, to cap the number of episodes. The feed is already newest first, so sort_by and order are ignored. |
Several committees' rosters at once: a heading per committee followed by that committee's people, in the order the codes are listed. The app picks the roster by this content type, so attach it to an item whose itemType is MultiCommitteeRoster.
ContactCard; authored with ContactCard| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
rosterCodes | string | yes | any | Committee roster codes separated by commas, in the order the sections should appear. A repeated code shows once. An unknown code, or a committee with no volunteers, is skipped. The app needs at least one code; asking for two or more is the admin tool's rule, not the app's. The codes live content uses follow a convention (seen in 994 live codes): the page's MEC code, then 2 to 4 letters, digits or &, then 5 digits. That is a habit of the content, not a rule the app checks. |
These apply whatever the content type. The visibility rules run before the adapter does.
| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
hidden | true or false | no | any | true hides the item and shows nothing in its place. A hidden item can still supply its container's heading or View All link (see Container heading keys), because those are read before the visibility rules run. |
visibleMecs | string | no | any | MEC codes separated by commas, case-insensitive; the group tokens USA and CAN also work (template/mec-groups.json lists the MECs in each). The item shows only to members of those MECs. A signed-out member, or one with no MEC, never sees it. |
hiddenMecs | string | no | any | MEC codes separated by commas, or the group tokens USA and CAN (template/mec-groups.json lists the MECs in each). The item is hidden from members of those MECs and shown to everyone else, signed-out members included. Use it for a general option that some MECs replace with their own. |
hiddenUserTypes | array of strings | no | Member, Staff, Guest | Account types the item is hidden from, case-insensitive. When the account type is not known the item stays visible. |
isFavoritable | true or false | no | any | false removes the favorite heart from the item and its rows. MecHotelDirectory ignores it: its hotel rows set their own hearts. DynamicList applies it only when it is set, and otherwise keeps what its source returned. |
An item's template can supply its container's heading and View All link, but only when the container has none of its own. The first item in the container whose template provides one is used. This is read before the visibility rules run, so an item that is hidden, or not shown to this member, can still set the heading.
| Key | Type | Required | Allowed values | What it does |
|---|---|---|---|---|
containerTitle | string | no | any | Text for the container's heading, used only when the container has no title of its own. It wins over title when both are present. Placeholders are allowed and {mec} is upper-case. The first item in the container whose template provides a heading is used, even if that item is hidden or not shown to this member. |
title | string | no | any | Two jobs. On an item it is always the item's own title. It also becomes the container's heading, but only when containerTitle is absent and the container has no title of its own; when both title and containerTitle are present, title belongs to the card alone and containerTitle is the heading. |
viewAllLink | string | no | any | The container's View All route, used only when the container has none of its own. The first item whose template provides one is used, even if that item is hidden. A bare page key is expanded into the in-app route. |
For a styling-only content type, the template's keys are copied onto the item. Route values are filled in and then expanded to an in-app route; text values are filled in; value keys are copied as they are.
| Template key | Treated as | Written to the item's | What it is for |
|---|---|---|---|
renderType | value | itemType | Becomes the item type of the item or rows, which decides the component that draws them. |
title | text | title | The item's title. Placeholders are substituted. |
eyebrow | text | eyebrow | The small label above the title. Placeholders are substituted. |
description | text | description | The item's body text. Placeholders are substituted. |
image | text | image | The image path or URL. Placeholders are substituted. |
action | route | link, ctaLink | Where the item goes. Written to both the card link and the call-to-action link, replacing any ctaLink. |
link | route | link, ctaLink | Same as action. |
ctaLink | route | ctaLink | The call-to-action button's target. If action or link is also given, they set the call-to-action target too and win, because they are applied after it. |
variant | value | variant | Selects a sub-style of the component, for example alpa. |
isFavoritable | value | isFavoritable | Turns the favorite heart off with false. |
clampTitle | value | clampTitle | false shows a hero card's whole title; missing or true keeps the two-line clamp. |
A value can contain a {token}, filled in for the signed-in member when the page is built.
| Token | What it becomes |
|---|---|
{mec} | The signed-in member's MEC. Lower-case in routes and in the image of a styling-only item, upper-case in title, eyebrow and description text. The LecLink image keeps it upper-case. |
{lec} | The member's LEC code, a raw number such as 012. |
{airport} | The member's base airport, lower-case. Only the LecLink image takes it; in any other field it is left as written. Not used by live content. |
{Property} | Any property of the item the value belongs to, by name and ignoring case, for example {Id} or {Title}. Adapters that build rows fill these in per row; for a committee row {Id} is the committee code. Only {mec} and {lec} read the member's profile. |
{{mec}-committees-hotel} | A compound group: the outer braces only group, and the nested token is substituted. With MEC ual this becomes ual-committees-hotel. |
{{mec}-{lec}} | A compound group with two nested tokens: the outer braces only group, and both tokens are substituted. With MEC ual and LEC 012 this becomes ual-012, the page key of that MEC's LEC page. Use it where a field takes a page key; a host that does not know the member (the admin tool) can only show it as a placeholder. |
{page-key} or page-key | In a route field, a value that is not already a path, an http(s) link, tel: or mailto: is taken as a dynamic-feed page key and expanded to /dynamic-feed-orchestrator?page=<key>. A full path or URL passes through unchanged. Braces around a key that contains a hyphen, such as {ual-media}, are dropped; a single word in braces, such as {media}, is read as a token, so leave the braces off a one-word key. |
action, link, ctaLink, viewAllLink) accept
a full path, an http(s) link, tel: or mailto: as written. Anything else is taken to be a
dynamic-feed page key and expanded to /dynamic-feed-orchestrator?page=<key>, so
"ual-media" and "{ual-media}" mean the same page.An item with no template gets placeholders filled in too, in exactly these fields. In any other field a {token} is shown as written.
| Field | How it is filled in | What it is |
|---|---|---|
title | text, {mec} upper-case | The item's title. Placeholders are substituted; {mec} is upper-case here. |
headerText | text, {mec} upper-case | The heading line (a ButtonCard's text). Placeholders are substituted; {mec} is upper-case here. |
description | text, {mec} upper-case | Body text. Placeholders are substituted; {mec} is upper-case here. |
blurb | text, {mec} upper-case | Secondary body text. Placeholders are substituted; {mec} is upper-case here. |
eyebrow | text, {mec} upper-case | The small label above the title. Placeholders are substituted; {mec} is upper-case here. |
label | text, {mec} upper-case | A short label. Placeholders are substituted; {mec} is upper-case here. |
ctaText | text, {mec} upper-case | The button text. Placeholders are substituted; {mec} is upper-case here. |
image | path, {mec} lower-case | The image path or URL. Placeholders are substituted; {mec} is lower-case here, as in a file name. |
icon | path, {mec} lower-case | The icon name or path. Placeholders are substituted; {mec} is lower-case here. |
link | route | Where the item goes. Placeholders are substituted, then a page key is expanded to its route. |
ctaLink | route | The button's target. Placeholders are substituted, then a page key is expanded to its route. |
The value of itemType, which is also what renderType sets on a resolved row. Reads lists the item keys the component uses; the ones marked as theme tokens name a design token from the active theme. Also accepted are older names the app still understands. Ignored keys are ones live content sends that the app does not read: they are accepted so existing content stays valid, and are not offered for editing. Use says whether the app's own content uses the type today, and whether an author places it directly, sets it only as a renderType, or attaches a template to it.
| Item type | Use | What it is | Also accepted | Reads | Theme tokens | Ignored |
|---|---|---|---|---|---|---|
Button | Action; in the app's content | Icon button with a label. The alpa and alpa-diagonal variants draw the pointed full-width treatments. | SingleButton1 | ctaText, title, image, icon, ctaLink, link, variant, tokenOverrides | backgroundToken, ctaTextToken, cornerRadiusToken | isSortable, sortOrder |
ButtonCard | Card; in the app's content | Card with an embedded call-to-action button. Without ctaText the whole card is the tap target. | — | headerText, title, description, blurb, image, link, ctaText, ctaLink, tokenOverrides | backgroundToken, headerTextToken, iconSizeToken, iconColorToken, ctaTextToken, cornerRadiusToken | isSortable, sortOrder |
CardSmall | Card; in the app's content | Compact list row with an icon, title and subtitle. | — | title, image, icon, iconMaskUrl, link, ctaLink, label, description, blurb, tokenOverrides | backgroundToken, titleToken, eyebrowToken, descriptionToken, cornerRadiusToken, iconBackgroundToken, iconSizeToken, iconColorToken | isSortable, sortOrder |
CardText | Card; not in the app's content | Text card: label, title, description and link. | — | label, title, description, blurb, image, link, ctaLink, tokenOverrides | eyebrowToken, titleToken, descriptionToken | — |
ContactCard | Card; in the app's content; set only as a renderType | A person: name, role, email and phone. It draws a committee volunteer, an LEC rep or an MEC officer, and is what the ContactItem and RosterItem content types produce. The role line and the favorite heart come from the member's records, not from the template. | — | title, headerText, email, phone | rosterTitleToken, rosterNameToken, rosterEmailToken, rosterTelToken | isSortable, sortOrder |
EmergencyButton | Action; not in the app's content | Emergency hotline button. | — | ctaText, ctaLink, link, tokenOverrides | backgroundToken, ctaTextToken, cornerRadiusToken | — |
HeroCard | Card; in the app's content | Content card with an eyebrow, title, description and image. | SingleButtonLarge, DocumentHero | title, description, blurb, eyebrow, image, icon, link, ctaLink, useDesignPlaceholder, accentOnLeft, tokenOverrides | backgroundToken, eyebrowToken, titleToken, descriptionToken | cornerRadiusToken, isSortable, sortOrder |
List | Card; in the app's content; a placeholder an adapter replaces | A plain list row, drawn exactly like CardSmall. It is the itemType placeholder on templated items whose rows an adapter builds (ContactItem, DocumentItem, MecHotelDirectory, PodcastEpisode). The adapter replaces the placeholder, so its own fields rarely matter. | — | title, image, icon, iconMaskUrl, link, ctaLink, label, description, blurb, tokenOverrides | backgroundToken, titleToken, eyebrowToken, descriptionToken, cornerRadiusToken, iconBackgroundToken, iconSizeToken, iconColorToken, rosterTitleToken, rosterNameToken, rosterEmailToken, rosterTelToken | isSortable, sortOrder |
MecHotelRow | Card; in the app's content; set only as a renderType | One crew hotel under its airport's header. The MecHotelDirectory content type produces it and sets the airport code (variant) itself; it is not meant to be authored by hand. | — | title, description, blurb, link, ctaLink, variant | titleToken | — |
MultiCommitteeRoster | Card; in the app's content; a placeholder an adapter replaces | Placeholder for several committees' rosters: attach a RosterItem template and the app replaces it with a heading per committee followed by that committee's people. The item draws nothing itself; its roster tokens style the contact rows. | — | rosterTitleToken, rosterNameToken, rosterEmailToken, rosterTelToken | isSortable, sortOrder | |
PilotCard | Card; in the app's content | Welcome card: pilot identity heading and a contract link. The alpa variant draws the always-pointed treatment. | — | headerText, title, linkText, ctaText, link, ctaLink, variant, tokenOverrides | backgroundToken, identityToken, contractLinkToken | isSortable, sortOrder |
The app draws these too, but they are not for authors, so this catalog does not describe their keys. Use the item types in the table above.
MecHotelFilterBar, MecHotelSectionHeader, SectionHeaderButtonGroup, Carousel, Expander, Feed, PromoBanner, SearchSecondaryButton, SingleButton2, SliderImages, SliderNoImages, SliderNoImagesEyebrows, TabGroup, ThreeUpButton, ToggleSwitchThese can appear in live content, but they belong to the app (like its settings and profile pages), so the admin portal never authors them and this catalog defines no item, content type or key for them. Show one read-only; it is not an unknown name.
| Name | Kind | Why it is not authored |
|---|---|---|
PacCard | Item type | App-native item: the app draws it itself. It is not a feed component an author places, so a host shows it read-only. |
PacContributions | Content type | App-native content type: the app's own Advocacy and Profile pages handle the PAC contributions, not a feed adapter, so a host shows it read-only. |
CallToAction | Content type | App-native content type: the app's Advocacy page loads its call-to-action links itself, not through a feed adapter, so a host shows it read-only. |
requiresMenuItem | Template key | App-native template key: the app reads it itself. It is not an authoring option, so a host leaves it as written. |
secondaryLink | Template key | App-native template key: the app reads it itself. It is not an authoring option, so a host leaves it as written. |
Each table lists the fields a component reads, most important first. Required: nearly all live content sets it. Shown: most do. Advanced: some do. Available: the app reads it but no bundled content sets it. Not offered: the app reads it, but authors should not set it. Parity: live content sends it and the app ignores it. A style token takes its allowed values from the active theme, so none are listed here. The tiers rest on a dated count of the app's bundled content (catalog/snapshots/live-usage.json).
Button| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
ctaText | Button text | Required | Text | — | — | The button text. Shown in preference to title. | 862 of 862 |
ctaLink | Button link | Required | Route | — | — | Where the button goes. Read before link. | 861 of 862 |
backgroundToken | Background | Required | Surface | — | Surface/Secondary | — | 859 of 862 |
ctaTextToken | Button text style | Required | Typography | — | ButtonText | — | 859 of 862 |
tokenOverrides | Token overrides | Advanced | — | — | — | — | 35 of 862 |
cornerRadiusToken | Corner radius | Advanced | Radius | — | BorderRadius/M | — | 91 of 862 |
image | Image | Available | Image | — | — | — | 0 of 862 |
title | Title | Not offered | Text | — | — | Shown only when ctaText is blank. | 0 of 862 |
icon | Icon | Not offered | Icon | — | — | — | 0 of 862 |
link | Link | Not offered | Route | — | — | Where the button goes when ctaLink is blank. | 0 of 862 |
variant | Style | Not offered | Enum | alpa, alpa-diagonal | The standard style. | — | 2 of 862 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 862 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 862 |
ButtonCard| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
headerText | Heading | Required | Text | — | — | The card text. Shown in preference to title. | 281 of 281 |
ctaLink | Button link | Required | Route | — | — | Where the button goes, read before link. With no button text (ctaText) there is no button and the whole card goes to link, then this. | 281 of 281 |
headerTextToken | Heading style | Required | Typography | — | ButtonCardTitle | — | 281 of 281 |
image | Image | Shown | Image | — | — | — | 265 of 281 |
backgroundToken | Background | Shown | Surface | — | Surface/Default | — | 266 of 281 |
iconColorToken | Icon colour | Shown | Color | — | Icon/Active | — | 190 of 281 |
iconSizeToken | Icon size | Advanced | IconSize | — | IconSize/M | — | 67 of 281 |
description | Description | Available | Multiline | — | — | — | 0 of 281 |
ctaText | Button text | Available | Text | — | — | The card text is headerText or title; this is not shown as that text. | 0 of 281 |
tokenOverrides | Token overrides | Available | — | — | — | — | 0 of 281 |
ctaTextToken | Button text style | Available | Typography | — | — | — | 0 of 281 |
cornerRadiusToken | Corner radius | Available | Radius | — | — | — | 0 of 281 |
title | Title | Not offered | Text | — | — | Shown only when headerText is blank. | 0 of 281 |
blurb | Blurb | Not offered | Multiline | — | — | — | 0 of 281 |
link | Link | Not offered | Route | — | — | Where the button goes when ctaLink is blank. With no button text (ctaText) the whole card goes here, read before ctaLink. | 0 of 281 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 281 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 281 |
CardSmall| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
title | Title | Required | Text | — | — | — | 1358 of 1360 |
image | Image | Required | Image | — | — | — | 1357 of 1360 |
ctaLink | Button link | Required | Route | — | — | Where the item goes when link is blank. | 1347 of 1360 |
titleToken | Title style | Required | Typography | — | CardSmallTitle | — | 1354 of 1360 |
cornerRadiusToken | Corner radius | Required | Radius | — | BorderRadius/M | — | 1331 of 1360 |
iconBackgroundToken | Icon background | Required | Surface | — | Surface/Secondary | — | 1326 of 1360 |
iconColorToken | Icon colour | Required | Color | — | Icon/OnBrand | — | 1325 of 1360 |
link | Link | Advanced | Route | — | — | Where the item goes. Read before ctaLink. | 11 of 1360 |
tokenOverrides | Token overrides | Advanced | — | — | — | — | 61 of 1360 |
backgroundToken | Background | Advanced | Surface | — | Surface/Brand | — | 61 of 1360 |
iconSizeToken | Icon size | Advanced | IconSize | — | IconSize/L | — | 3 of 1360 |
label | Label | Available | Text | — | — | — | 0 of 1360 |
description | Description | Available | Multiline | — | — | — | 0 of 1360 |
eyebrowToken | Eyebrow style | Available | Typography | — | — | — | 0 of 1360 |
descriptionToken | Description style | Available | Typography | — | — | — | 0 of 1360 |
icon | Icon | Not offered | Icon | — | — | — | 0 of 1360 |
iconMaskUrl | Icon mask | Not offered | Image | — | — | — | 0 of 1360 |
blurb | Blurb | Not offered | Multiline | — | — | — | 0 of 1360 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 1360 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 1360 |
ContactCard| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
rosterTitleToken | Role style | Advanced | Typography | — | RosterTitle | — | — |
rosterNameToken | Name style | Advanced | Typography | — | RosterName | — | — |
rosterEmailToken | Email style | Advanced | Typography | — | RosterEmail | — | — |
rosterTelToken | Phone style | Advanced | Typography | — | RosterTel | — | — |
title | Title | Not offered | Text | — | — | — | — |
headerText | Heading | Not offered | Text | — | — | — | — |
email | Not offered | Text | — | — | — | — | |
phone | Phone | Not offered | Text | — | — | — | — |
isSortable | Sortable | Parity | Boolean | — | — | — | — |
sortOrder | Sort order | Parity | Number | — | — | — | — |
HeroCard| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
title | Title | Required | Text | — | — | — | 198 of 199 |
eyebrowToken | Eyebrow style | Required | Typography | — | HeroEyebrow | — | 197 of 199 |
titleToken | Title style | Required | Typography | — | HeroTitle | — | 197 of 199 |
descriptionToken | Description style | Required | Typography | — | HeroParagraph | — | 197 of 199 |
eyebrow | Eyebrow | Shown | Text | — | — | — | 135 of 199 |
image | Image | Shown | Image | — | — | Optional. Without one the card hides its image area instead of showing a placeholder. | 133 of 199 |
link | Link | Shown | Route | — | — | Where the item goes. Read before ctaLink. | 173 of 199 |
ctaLink | Button link | Shown | Route | — | — | Where the item goes when link is blank. | 116 of 199 |
description | Description | Advanced | Multiline | — | — | — | 50 of 199 |
accentOnLeft | Accent on the left | Advanced | Boolean | — | — | — | 3 of 199 |
useDesignPlaceholder | Design placeholder | Available | Boolean | — | — | — | 0 of 199 |
blurb | Blurb | Not offered | Multiline | — | — | — | 0 of 199 |
icon | Icon | Not offered | Icon | — | — | — | 0 of 199 |
tokenOverrides | Token overrides | Not offered | — | — | — | — | 0 of 199 |
backgroundToken | Background | Not offered | Surface | — | — | — | 0 of 199 |
cornerRadiusToken | Corner radius | Parity | Radius | — | — | — | 1 of 199 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 199 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 199 |
List| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
rosterTitleToken | Role style | Shown | Typography | — | RosterTitle | — | 821 of 1269 |
rosterNameToken | Name style | Shown | Typography | — | RosterName | — | 821 of 1269 |
rosterEmailToken | Email style | Shown | Typography | — | RosterEmail | — | 821 of 1269 |
rosterTelToken | Phone style | Shown | Typography | — | RosterTel | — | 821 of 1269 |
title | Title | Advanced | Text | — | — | — | 23 of 1269 |
titleToken | Title style | Advanced | Typography | — | CarouselListTitle | — | 449 of 1269 |
eyebrowToken | Eyebrow style | Advanced | Typography | — | CarouselListEyebrow | — | 449 of 1269 |
descriptionToken | Description style | Advanced | Typography | — | CarouselListParagraph | — | 449 of 1269 |
image | Image | Available | Image | — | — | — | 0 of 1269 |
link | Link | Available | Route | — | — | Where the item goes. Read before ctaLink. | 0 of 1269 |
ctaLink | Button link | Available | Route | — | — | Where the item goes when link is blank. | 0 of 1269 |
label | Label | Available | Text | — | — | — | 0 of 1269 |
description | Description | Available | Multiline | — | — | — | 0 of 1269 |
tokenOverrides | Token overrides | Available | — | — | — | — | 0 of 1269 |
backgroundToken | Background | Available | Surface | — | — | — | 0 of 1269 |
icon | Icon | Not offered | Icon | — | — | — | 0 of 1269 |
iconMaskUrl | Icon mask | Not offered | Image | — | — | — | 0 of 1269 |
blurb | Blurb | Not offered | Multiline | — | — | — | 0 of 1269 |
cornerRadiusToken | Corner radius | Not offered | Radius | — | — | — | 0 of 1269 |
iconBackgroundToken | Icon background | Not offered | Surface | — | — | — | 0 of 1269 |
iconSizeToken | Icon size | Not offered | IconSize | — | — | — | 0 of 1269 |
iconColorToken | Icon colour | Not offered | Color | — | — | — | 0 of 1269 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 1269 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 1269 |
MultiCommitteeRoster| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
rosterTitleToken | Role style | Required | Typography | — | RosterTitle | — | 22 of 22 |
rosterNameToken | Name style | Required | Typography | — | RosterName | — | 22 of 22 |
rosterEmailToken | Email style | Required | Typography | — | RosterEmail | — | 22 of 22 |
rosterTelToken | Phone style | Required | Typography | — | RosterTel | — | 22 of 22 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 22 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 22 |
PilotCard| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
identityToken | Identity style | Required | Typography | — | PilotCardIdentity | — | 41 of 41 |
contractLinkToken | Contract link style | Required | Typography | — | PilotCardLink | — | 41 of 41 |
backgroundToken | Background | Shown | Surface | — | Surface/Default | — | 38 of 41 |
tokenOverrides | Token overrides | Advanced | — | — | — | — | 1 of 41 |
headerText | Heading | Not offered | Text | — | — | — | 0 of 41 |
title | Title | Not offered | Text | — | — | — | 0 of 41 |
linkText | Link text | Not offered | Text | — | — | — | 0 of 41 |
ctaText | Button text | Not offered | Text | — | — | — | 0 of 41 |
link | Link | Not offered | Route | — | — | Where the item goes. Read before ctaLink. | 0 of 41 |
ctaLink | Button link | Not offered | Route | — | — | Where the item goes when link is blank. | 0 of 41 |
variant | Style | Not offered | Enum | alpa | The standard style. | — | 0 of 41 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 41 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 41 |
The value of containerType. A container with a value the app does not know is skipped.
| Container type | Use | What it is | Reads | Theme tokens | Ignored |
|---|---|---|---|---|---|
ButtonGroup | Layout; not in the app's content | Horizontal row of tile buttons with no section header. Only button items are kept; they render as tiles. | items | backgroundToken | isSortable, sortOrder |
Carousel | Layout; in the app's content | Horizontal scrolling feed: section header plus cards, typically HeroCard. | title, viewAllText, viewAllLink, items | backgroundToken, titleToken, viewAllLinkToken | columns, paddingToken, isSortable, sortOrder |
Grid | Layout; in the app's content | Fixed-column grid of mixed items; columns defaults to 3. Title and View All are optional. | title, viewAllText, viewAllLink, columns, items | backgroundToken, titleToken, viewAllLinkToken | isSortable, sortOrder |
Stack | Layout; in the app's content | Surface-neutral vertical stack: quick-list rows, or a single-item wrapper for a standalone widget. Title and View All are optional. | title, viewAllText, viewAllLink, items | backgroundToken, titleToken, viewAllLinkToken | columns, paddingToken, isSortable, sortOrder |
ButtonGroup| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
items | Items | Required | — | — | — | — | — |
backgroundToken | Background | Available | Surface | — | — | — | — |
isSortable | Sortable | Parity | Boolean | — | — | — | — |
sortOrder | Sort order | Parity | Number | — | — | — | — |
Carousel| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
title | Title | Required | Text | — | — | — | 201 of 207 |
items | Items | Required | — | — | — | — | all |
titleToken | Title style | Required | Typography | — | ContainerHeaderTitle | — | 207 of 207 |
viewAllLinkToken | View All style | Required | Typography | — | ContainerViewAllLink | — | 207 of 207 |
viewAllText | View All text | Shown | Text | — | — | — | 179 of 207 |
viewAllLink | View All link | Shown | Route | — | — | — | 179 of 207 |
backgroundToken | Background | Available | Surface | — | — | — | 0 of 207 |
columns | Columns | Parity | Number | — | — | — | 1 of 207 |
paddingToken | Padding | Parity | — | — | — | — | 108 of 207 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 207 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 207 |
Grid| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
items | Items | Required | — | — | — | — | all |
titleToken | Title style | Required | Typography | — | ContainerHeaderTitle | — | 87 of 87 |
viewAllLinkToken | View All style | Required | Typography | — | ContainerViewAllLink | — | 87 of 87 |
columns | Columns | Shown | Number | 2, 3, 4 | 3 | — | 81 of 87 |
title | Title | Advanced | Text | — | — | — | 10 of 87 |
viewAllText | View All text | Available | Text | — | — | — | 0 of 87 |
viewAllLink | View All link | Available | Route | — | — | — | 0 of 87 |
backgroundToken | Background | Available | Surface | — | — | — | 0 of 87 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 87 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 87 |
Stack| Field | Label | Tier | Control | Allowed values | Default | Reads as | Set in bundled content |
|---|---|---|---|---|---|---|---|
items | Items | Required | — | — | — | — | all |
titleToken | Title style | Required | Typography | — | ContainerHeaderTitle | — | 2309 of 2320 |
viewAllLinkToken | View All style | Required | Typography | — | ContainerViewAllLink | — | 2309 of 2320 |
title | Title | Advanced | Text | — | — | — | 896 of 2320 |
viewAllText | View All text | Advanced | Text | — | — | — | 11 of 2320 |
viewAllLink | View All link | Advanced | Route | — | — | — | 10 of 2320 |
backgroundToken | Background | Available | Surface | — | — | — | 0 of 2320 |
columns | Columns | Parity | Number | — | — | — | 699 of 2320 |
paddingToken | Padding | Parity | — | — | — | — | 1 of 2320 |
isSortable | Sortable | Parity | Boolean | — | — | — | 0 of 2320 |
sortOrder | Sort order | Parity | Number | — | — | — | 0 of 2320 |
The palette lists what an author can add, with the item or container and the template each entry saves as. Entries the live sites use come first. Fill in names the keys the author has to complete; they are saved blank.
| Entry | Group | Use | Saves as | Template | Fill in |
|---|---|---|---|---|---|
| List row A small row with an icon tile, a title and a destination. | Items | in the app's content | item CardSmall | — | — |
| Button An icon button with a label. | Items | in the app's content | item Button | — | — |
| Branded button The pointed full-width button most live pages use: a Button drawn with the ButtonCard look. | Items | in the app's content | item Button | {"contentType":"ButtonCard","variant":"alpa"} | — |
| Button card A tile with a heading and a button. | Items | in the app's content | item ButtonCard | — | — |
| Hero card A content card with an eyebrow, title, description and image. | Items | in the app's content | item HeroCard | — | — |
| Pilot card The signed-in pilot's greeting card with a contract link. | Items | in the app's content | item PilotCard | {"contentType":"PilotCard"} | — |
| Documents A list of documents, filtered by category or grouping. | DataLists | in the app's content | item List | {"contentType":"DocumentItem","renderType":"HeroCard","filterType":"Category","filterValue":""} | filterValue |
| Podcast The episodes of a podcast feed. | DataLists | in the app's content | item List | {"contentType":"PodcastEpisode","renderType":"HeroCard","filterType":"FeedUrl","filterValue":""} | filterValue |
| Hotel directory The MEC hotel directory, grouped by airport. | DataLists | in the app's content | item List | {"contentType":"MecHotelDirectory","renderType":"MecHotelRow"} | — |
| One committee The volunteers of one committee. | Contacts | in the app's content | item List | {"contentType":"ContactItem","renderType":"ContactCard","filterType":"RosterCode","filterValue":""} | filterValue |
| Several committees A heading per committee followed by its volunteers. | Contacts | in the app's content | item MultiCommitteeRoster | {"contentType":"RosterItem","rosterCodes":""} | rosterCodes |
| My LEC reps The signed-in pilot's own LEC representatives. | Contacts | in the app's content | item List | {"contentType":"ContactItem","renderType":"ContactCard","filterType":"LecReps"} | — |
| My MEC officers The signed-in pilot's own MEC officers. | Contacts | in the app's content | item List | {"contentType":"ContactItem","renderType":"ContactCard","filterType":"MecReps"} | — |
| LEC link A row linking to the signed-in pilot's own LEC page, with the shared LEC icon on the card's icon tile. | LecLink | in the app's content | item CardSmall | {"contentType":"LecLink","renderType":"CardSmall","image":"https://shared.alpa.org/Portals/27/alpa-app/icons/lec-icon.svg"} | — |
| Stack A vertical stack of rows, or a wrapper for one widget. | Containers | in the app's content | container Stack | — | — |
| Carousel A horizontal scrolling row of cards. | Containers | in the app's content | container Carousel | — | — |
| Grid A fixed-column grid of tiles. | Containers | in the app's content | container Grid | — | — |
| Text card A card with a label, title and description. | Available | not in the app's content | item CardText | — | — |
| Emergency button The emergency hotline button. | Available | not in the app's content | item EmergencyButton | — | — |
| Button group A row of tile buttons with no section header. | Available | not in the app's content | container ButtonGroup | — | — |
| Committee list The committees list, with featured committees. | Available | not in the app's content | item List | {"contentType":"Committee"} | — |
| Hero card with styling A hero card restyled by a template instead of by its own fields. | Available | not in the app's content | item HeroCard | {"contentType":"HeroCard"} | — |
Some fields are never set by an author: the app fills them in from the signed-in member. The editor cannot read the member, so these are the worked examples it previews with. A test runs the real adapter for every example below.
LecLinktitle: The row's title is the member's own LEC, built from their base airport and LEC code (for example "ORD 012"). It differs for every member, and the admin tool never knows a member's LEC, so the editor shows one generic label instead of an example. The app fills in the title and the link to the member's own LEC page when it draws the row.
Previewed as the label Link to your LEC; no examples.
PilotCardheaderText: The greeting. English: "Welcome {rank} {last name}", or "Welcome {first name} {last name}" when the member record has no rank. A French page: "Bienvenue, {rank} {last name}" (a comma; the rank stays in English). A visitor who is not signed in gets just "Welcome", on English and French pages alike.
| Sample member | Page | Template assumes | Shows |
|---|---|---|---|
| Captain, short name | English | — | Welcome Captain Ng |
| Captain, short name | French | — | Bienvenue, Captain Ng |
| First Officer, short name | English | — | Welcome First Officer Li |
| First Officer, short name | French | — | Bienvenue, First Officer Li |
| Captain, long name | English | — | Welcome Captain Vandersteenhoven-Kowalczyk |
| Captain, long name | French | — | Bienvenue, Captain Vandersteenhoven-Kowalczyk |
| First Officer, long name, no contract | English | — | Welcome First Officer Lefèvre-Desrosiers |
| First Officer, long name, no contract | French | — | Bienvenue, First Officer Lefèvre-Desrosiers |
| No rank on record | English | — | Welcome Jordan O'Brien |
| No rank on record | French | — | Bienvenue, Jordan O'Brien |
| No rank, accented name, no contract | English | — | Welcome Élodie Lefèvre-Desrosiers |
| No rank, accented name, no contract | French | — | Bienvenue, Élodie Lefèvre-Desrosiers |
| First Officer at DAL (a second US MEC) | English | — | Welcome First Officer Okafor |
| First Officer at DAL (a second US MEC) | French | — | Bienvenue, First Officer Okafor |
| Captain at ACA (Canadian MEC) | English | — | Welcome Captain Tremblay |
| Captain at ACA (Canadian MEC) | French | — | Bienvenue, Captain Tremblay |
| Signed out | either | — | Welcome |
linkText: The contract link: "View Contract", or "Convention collective" on a French page. It shows only when a contract document exists for the member's MEC; otherwise there is no link.
| Sample member | Page | Template assumes | Shows |
|---|---|---|---|
| Captain, short name | English | — | View Contract |
| Captain, short name | French | — | Convention collective |
| First Officer, short name | English | — | View Contract |
| First Officer, short name | French | — | Convention collective |
| Captain, long name | English | — | View Contract |
| Captain, long name | French | — | Convention collective |
| First Officer, long name, no contract | English | — | nothing |
| First Officer, long name, no contract | French | — | nothing |
| No rank on record | English | — | View Contract |
| No rank on record | French | — | Convention collective |
| No rank, accented name, no contract | English | — | nothing |
| No rank, accented name, no contract | French | — | nothing |
| First Officer at DAL (a second US MEC) | English | — | View Contract |
| First Officer at DAL (a second US MEC) | French | — | Convention collective |
| Captain at ACA (Canadian MEC) | English | — | View Contract |
| Captain at ACA (Canadian MEC) | French | — | Convention collective |
| Signed out | either | — | nothing |
Contacts, documents and podcast episodes come from data, not from the page. Each example is a template an author could save and the rows the app shows for it against the sample contacts, documents and episodes below. A test runs the real adapter against those samples for every example. Dates are written in the language of the member's device; the examples show English.
ContactItemOne committee. The volunteers of the Safety committee, one card each.
{
"contentType": "ContactItem",
"renderType": "ContactCard",
"filterType": "RosterCode",
"filterValue": "UALSAFE00001"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | — | Wei Ng | Chair | — | wei.ng@example.org | 5555550101 |
| card | — | Mei Li | Vice Chair | — | mei.li@example.org | 5555550102 |
| card | — | Bob O'Brien | Secretary | — | bob.obrien@example.org | 5555550104 |
| card | — | Claire Lefèvre-Desrosiers | Member | — | claire.lefevre@example.org | — |
My LEC reps. The signed-in member's own LEC representatives.
{
"contentType": "ContactItem",
"renderType": "ContactCard",
"filterType": "LecReps"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | — | Pat Moreau | Chair | — | pat.moreau@example.org | 5555550106 |
| card | — | Sam Okafor | Vice Chair | — | sam.okafor@example.org | — |
My MEC officers. The signed-in member's own MEC officers.
{
"contentType": "ContactItem",
"renderType": "ContactCard",
"filterType": "MecReps"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | — | Pat Moreau | Chair | — | pat.moreau@example.org | 5555550106 |
| card | — | Dana Whitfield | Secretary-Treasurer | — | dana.whitfield@example.org | 5555550108 |
A code no committee has. A well-formed code that no committee uses shows nothing, with no message.
{
"contentType": "ContactItem",
"renderType": "ContactCard",
"filterType": "RosterCode",
"filterValue": "UALNONE00000"
}
Shows nothing.
DocumentItemNewest three in a category. The three most recent documents filed under Communications, newest first. A document has no image, so each HeroCard row draws without its picture area.
{
"contentType": "DocumentItem",
"renderType": "HeroCard",
"filterType": "Category",
"filterValue": "Communications",
"searchFilter": "sort_by=date&order=desc&limit=3"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | 10/02/2026 | Negotiating committee report | — | A summary of this month's sessions. | — | — |
| card | 09/30/2026 | LEC officer elections open | — | How to stand for office and when ballots are due. | — | — |
| card | 09/14/2026 | Scheduling update for October | — | What changes in the October bid and when it takes effect. | — | — |
Only PDFs. Every Communications document that is a PDF, in the order the library returns them. A document has no image, so each HeroCard row draws without its picture area.
{
"contentType": "DocumentItem",
"renderType": "HeroCard",
"filterType": "Category",
"filterValue": "Communications",
"docType": "pdf"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | 10/02/2026 | Negotiating committee report | — | A summary of this month's sessions. | — | — |
| card | — | Annual member survey results, including participation by domicile and a comparison with the previous three years | — | The full results, with the questions as asked and the number of members who answered each. | — | — |
A grouping. The documents in one grouping, across categories, newest first. A document has no image, so each HeroCard row draws without its picture area.
{
"contentType": "DocumentItem",
"renderType": "HeroCard",
"filterType": "Grouping",
"filterValue": "MEC Communications",
"searchFilter": "sort_by=date&order=desc"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | 10/02/2026 | Negotiating committee report | — | A summary of this month's sessions. | — | — |
| card | 09/14/2026 | Scheduling update for October | — | What changes in the October bid and when it takes effect. | — | — |
| card | 08/21/2026 | Recognizing our retiring members | — | — | — | — |
| card | — | Annual member survey results, including participation by domicile and a comparison with the previous three years | — | The full results, with the questions as asked and the number of members who answered each. | — | — |
UAL MEC updates. The three newest MEC updates in UAL's own document set, newest first. UAL's documents have no description, so each HeroCard row shows its date and title only.
{
"contentType": "DocumentItem",
"renderType": "HeroCard",
"parentFilterType": "MEC",
"parentFilterValue": "ual",
"filterType": "Category",
"filterValue": "MEC Updates and Weekly",
"searchFilter": "sort_by=date&order=desc&limit=3"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | 10/23/2026 | MEC Weekly Update: October 23 | — | — | — | — |
| card | 10/16/2026 | MEC Weekly Update: October 16 | — | — | — | — |
| card | 10/09/2026 | MEC Weekly Update: October 9 | — | — | — | — |
PodcastEpisodeLatest three episodes. The three most recent episodes of a feed. The feed is already newest first, so only limit is used. An episode has no image or description, so a HeroCard row shows its date and title only.
{
"contentType": "PodcastEpisode",
"renderType": "HeroCard",
"filterType": "FeedUrl",
"filterValue": "https://podcast.example.org/feed/",
"searchFilter": "sort_by=date&order=desc&limit=3"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | October 6, 2026 | Contract talks: what happens next | — | — | — | — |
| card | September 22, 2026 | Safety at the table: a conversation with the committee chair | — | — | — | — |
| card | September 8, 2026 | Understanding your October bid, with a walkthrough of preferential bidding, reserve rules and how seniority affects each round of awards | — | — | — | — |
The whole feed. With no limit, every episode the feed lists, in the feed order. An episode with no publish date has no date line.
{
"contentType": "PodcastEpisode",
"renderType": "HeroCard",
"filterType": "FeedUrl",
"filterValue": "https://podcast.example.org/feed/"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| card | October 6, 2026 | Contract talks: what happens next | — | — | — | — |
| card | September 22, 2026 | Safety at the table: a conversation with the committee chair | — | — | — | — |
| card | September 8, 2026 | Understanding your October bid, with a walkthrough of preferential bidding, reserve rules and how seniority affects each round of awards | — | — | — | — |
| card | August 25, 2026 | Member question: reserve availability | — | — | — | — |
| card | — | Welcome to the pilot podcast | — | — | — | — |
A feed that cannot be read. A feed address the app cannot read shows nothing, with no message.
{
"contentType": "PodcastEpisode",
"renderType": "HeroCard",
"filterType": "FeedUrl",
"filterValue": "https://podcast.example.org/missing/"
}
Shows nothing.
RosterItemTwo committees. A heading per committee, in the order the codes are listed, with that committee's people under it.
{
"contentType": "RosterItem",
"renderType": "ContactCard",
"rosterCodes": "UALSAFE00001,UALSCHD00002"
}
| Eyebrow | Title | Role | Description | Phone | ||
|---|---|---|---|---|---|---|
| heading | — | Safety | — | — | — | — |
| card | — | Wei Ng | Chair | — | wei.ng@example.org | 5555550101 |
| card | — | Mei Li | Vice Chair | — | mei.li@example.org | 5555550102 |
| card | — | Bob O'Brien | Secretary | — | bob.obrien@example.org | 5555550104 |
| card | — | Claire Lefèvre-Desrosiers | Member | — | claire.lefevre@example.org | — |
| heading | — | Scheduling | — | — | — | — |
| card | — | Mei Li | Chair | — | mei.li@example.org | 5555550102 |
| card | — | Alex Rivera | Member | — | alex.rivera@example.org | 5555550105 |
| List | Code | Name | Title | Seat | Phone | |
|---|---|---|---|---|---|---|
| Committee: Safety | UALSAFE00001 | Claire Lefèvre-Desrosiers | Member | — | claire.lefevre@example.org | — |
| Committee: Safety | UALSAFE00001 | Bob O'Brien | Treasurer | — | bob.obrien@example.org | 5555550104 |
| Committee: Safety | UALSAFE00001 | Wei Ng | Chair | — | wei.ng@example.org | 5555550101 |
| Committee: Safety | UALSAFE00001 | Mei Li | Vice Chair | — | mei.li@example.org | 5555550102 |
| Committee: Safety | UALSAFE00001 | Bob O'Brien | Secretary | — | bob.obrien@example.org | 5555550104 |
| Committee: Scheduling | UALSCHD00002 | Alex Rivera | Member | — | alex.rivera@example.org | 5555550105 |
| Committee: Scheduling | UALSCHD00002 | Mei Li | Chair | — | mei.li@example.org | 5555550102 |
| My LEC reps | — | Pat Moreau | Chair | Captain Representative | pat.moreau@example.org | 5555550106 |
| My LEC reps | — | Sam Okafor | Vice Chair | First Officer Representative | sam.okafor@example.org | — |
| My MEC officers | — | Pat Moreau | Chair | — | pat.moreau@example.org | 5555550106 |
| My MEC officers | — | Dana Whitfield | Secretary-Treasurer | — | dana.whitfield@example.org | 5555550108 |
Feed https://podcast.example.org/feed/, newest first.
| Published | Title |
|---|---|
| 2026-10-06 | Contract talks: what happens next |
| 2026-09-22 | Safety at the table: a conversation with the committee chair |
| 2026-09-08 | Understanding your October bid, with a walkthrough of preferential bidding, reserve rules and how seniority affects each round of awards |
| 2026-08-25 | Member question: reserve availability |
| undated | Welcome to the pilot podcast |
| Category | Grouping | Type | Published | Title | Description |
|---|---|---|---|---|---|
| Communications | MEC Communications | webpage | 2026-09-14 | Scheduling update for October | What changes in the October bid and when it takes effect. |
| Communications | MEC Communications | 2026-10-02 | Negotiating committee report | A summary of this month's sessions. | |
| Communications | MEC Communications | webpage | 2026-08-21 | Recognizing our retiring members | — |
| Communications | MEC Communications | undated | Annual member survey results, including participation by domicile and a comparison with the previous three years | The full results, with the questions as asked and the number of members who answered each. | |
| Communications | LEC Communications | webpage | 2026-09-30 | LEC officer elections open | How to stand for office and when ballots are due. |
| Letter of Agreement | MEC Documents | 2026-07-08 | Letter of Agreement 26-03: reserve availability | Replaces the interim language on reserve availability. | |
| MEC Updates and Weekly | — | 2026-10-23 | MEC Weekly Update: October 23 | — | |
| MEC Updates and Weekly | — | 2026-10-16 | MEC Weekly Update: October 16 | — | |
| MEC Updates and Weekly | — | 2026-10-09 | MEC Weekly Update: October 9 | — |
| Sample | Signed in | Name | Rank | MEC | LEC | Base | Has a contract |
|---|---|---|---|---|---|---|---|
| Captain, short name | yes | Wei Ng | Captain | UAL | 012 | ORD | yes |
| First Officer, short name | yes | Mei Li | First Officer | UAL | 012 | ORD | yes |
| Captain, long name | yes | Anneke Vandersteenhoven-Kowalczyk | Captain | UAL | 012 | ORD | yes |
| First Officer, long name, no contract | yes | Claire Lefèvre-Desrosiers | First Officer | UAL | 012 | ORD | no |
| No rank on record | yes | Jordan O'Brien | — | UAL | 012 | ORD | yes |
| No rank, accented name, no contract | yes | Élodie Lefèvre-Desrosiers | — | UAL | 012 | ORD | no |
| First Officer at DAL (a second US MEC) | yes | Sam Okafor | First Officer | DAL | 044 | ORD | yes |
| Captain at ACA (Canadian MEC) | yes | Luc Tremblay | Captain | ACA | 030 | YYZ | yes |
| Signed out | no | — | — | — | — | — | no |
Each example is checked against this catalog by a test: the content type exists, required keys are present, and every key and render type is valid.
A container with one templated item. The item's own itemType is only a placeholder; the template decides what appears. The container's View All link is a bare page key, which the app expands into the in-app route.
{
"containerType": "Carousel",
"title": "Latest updates",
"viewAllText": "View All",
"viewAllLink": "{ual-media}",
"items": [
{
"itemType": "List",
"template": {
"contentType": "DocumentItem",
"renderType": "HeroCard",
"filterType": "Category",
"filterValue": "MEC Updates and Weekly",
"searchFilter": "?sort_by=date&order=desc&limit=3"
}
}
]
}
One row, no parameters needed: the content comes from the pilot's own sign-in. The renderType is optional and defaults to PilotCard.
{
"containerType": "Stack",
"items": [
{
"itemType": "PilotCard",
"template": { "contentType": "PilotCard" }
}
]
}
A heading per committee followed by its people, in the order the codes are listed. Replace the two codes with real roster codes.
{
"containerType": "Stack",
"items": [
{
"itemType": "MultiCommitteeRoster",
"template": {
"contentType": "RosterItem",
"rosterCodes": "COMMITTEE_CODE_ONE,COMMITTEE_CODE_TWO"
}
}
]
}
In a page payload, template may be a JSON object, as written here, or the same object written as an escaped JSON string. The app reads both. The tests check the object form against this catalog, not the escaped one.
Tests compare this page's data with the app's code, and fail when they differ, for these points:
renderType is required or has a default, and that every render type named is an item type the app draws;filterType, parentFilterType, hiddenUserTypes and the PilotCard variant;{mec}, {lec}, {Property} and page keys are filled in, and that the examples are valid.Tests do not check: a key's type, whether it is required (or required when), what a content type produces, the descriptions, or the section 1 walk-through. The key lists are checked loosely: a listed key must appear in its adapter's code, and a key the adapter reads must be listed, but a key the adapter reads for a different purpose can pass. When something here surprises you, the app's code decides; report the difference so this page can be fixed.
The same data, plus JSON Schemas for a page, container and item and a preview fixture for every component, ships as the ALPAMobile.Catalog package. Use it to build pickers and validation in the authoring tool instead of copying values from this page.