Public Embeds Reference

Embed Tokens & CSS Reference

A practical guide to the pieces you can use when adding Luster to your own pages: small PHP settings, template placeholders, and CSS hooks for styling the output.

Getting Started

Overview

Luster is embed-only. That means you make the public page on your own site, then place the Luster feature inside it with a PHP require.

Thing What it means Example
Embed file The PHP file that prints a public Luster feature on a page. public/embed/members.php
Snippet variable A PHP variable you set before including the embed. $luster_per_page = 25;
Template token A word in braces that Luster replaces with real data. {listing_title}
Loop block A repeat area — Luster repeats the inside once per item. {each_listing}...{/each_listing}
Conditional block A show/hide area — Luster keeps it only when the condition is true. {if_listing_image}...{/if_listing_image}
CSS class A styling hook in the generated HTML. .fl-listing-item

Token names are local to their template. A token only works in the template section where it is listed, even if another section has a token with the same name.

Most tokens print safe text. Tokens ending in _html, plus the form-wrapper token {input}, print real HTML because they are meant to create page markup.

Embed Include file What it does Main CSS classes Token / template surface
Join form embed/join.php Lets someone join one fanlisting. .fl-embed--join, form classes Form field wrapper, success
Members embed/members.php Shows approved members, country summary, sorting, filtering, and pagination. .fl-embed--members, .fl-member-*, .fl-pagination-* Member row tokens, pagination
Update form embed/update.php Lets an existing member update their details. Also includes a "remove me" checkbox — there is no separate remove embed. .fl-embed--update, form classes Update Form Template tokens, success
Password reset embed/reset.php Shows the reset request form or the new-password confirmation form. .fl-embed--reset, form classes Reset Form Template tokens, success
Listing stats embed/stats.php Prints stats for one current fanlisting. .fl-stats, .fl-stat-* Listing stats tokens
Affiliates embed/affiliates.php Shows listing or collective affiliates with optional pagination. .fl-embed--affiliates, .fl-affiliate-* Affiliate section tokens, pagination
Affiliate application embed/affiliate-apply.php Shows a form to apply as an affiliate for a listing or collective. .fl-embed--affiliate-apply, form classes Affiliate Application Form Template tokens, success
Codes embed/codes.php Shows approved codes. Can append the code submission form. .fl-embed--codes, .fl-code-* Codes template tokens
Code submission embed/codes-submit.php Lets visitors donate or submit codes for one listing. .fl-embed--codes-submit, form classes Code Submission Form Template tokens, success
Collective code submission embed/collective-codes-submit.php Lets visitors donate or submit codes site-wide, not tied to one listing. .fl-embed--codes-submit, form classes Code Submission Form Template tokens, success
Contact embed/contact.php Contact form for one listing. .fl-embed--contact, form classes Contact Form Template tokens, success
Collective contact embed/collective-contact.php Contact form for the whole site or collective. .fl-embed--contact, form classes Contact Form Template tokens, success
Owned listings embed/owned.php Shows listings you own, with status and category options. .fl-embed--owned, .fl-category-*, .fl-listing-* Owned listing tokens
Joined listings embed/joined.php Shows fanlistings you have joined, with category options. .fl-embed--joined, .fl-category-*, .fl-joined-* Joined listing tokens
Latest owned listing embed/latest-listing.php Shows the single newest owned listing. .fl-latest-listing-* (no outer .fl-embed--latest) Latest listing tokens
Random owned listing embed/random-listing.php Shows one random owned listing. .fl-random-listing-* (no outer .fl-embed--random) Random listing tokens
Latest joined listing embed/latest-joined-listing.php Shows one most-recently-joined listing. Same row tokens as Joined Listing Tokens, but its own class family: .fl-latest-joined-listing-* (not .fl-joined-*) Joined listing tokens (single row)
Random joined listing embed/random-joined-listing.php Shows one random joined listing. Same row tokens as Joined Listing Tokens, but its own class family: .fl-random-joined-listing-* (not .fl-joined-*) Joined listing tokens (single row)
Wishlist embed/wishlist.php Shows collective wishlist entries. .fl-embed--wishlist, .fl-wishlist-* Wishlist tokens
Per-listing news feed embed/newsfeed.php Shows news feed entries for one fanlisting. .fl-embed--newsfeed, .fl-newsfeed-* News Feed tokens, pagination
Collective news feed embed/collective-newsfeed.php Shows site-wide news feed. .fl-embed--newsfeed (same root class as the per-listing embed), .fl-newsfeed-* News Feed tokens, pagination
Collective membership update embed/collective-update.php Lets a member update their name, URL, country, and password across all their fanlistings via an email verification link. No $luster_fanlisting_id needed. Step 1 is template-controlled; Step 2 is PHP-rendered. .fl-collective-update-form, .fl-collective-update-*, form classes Collective Update Form tokens
KIM list embed/kim-list.php Shows the KIM overview (all subjects) or the KIM member list for one subject, depending on $luster_kim_subject_id. .fl-embed--kim-list, .fl-kim-* KIM list overview / subject tokens
KIM signup embed/kim-signup.php Lets someone sign up for KIM notifications. .fl-embed--kim-signup, .fl-kim, form classes Form field wrapper, success
KIM update embed/kim-update.php Lets someone update their KIM entry. .fl-embed--kim-update, .fl-kim, form classes KIM update form tokens
KIM reset embed/kim-reset.php Lets someone reset their KIM password. .fl-embed--kim-reset, .fl-kim, form classes KIM reset form tokens
Adoption application embed/adopt.php Adoption form — visitors choose which listing to apply for. No $luster_fanlisting_id needed. Requires the Adoption add-on. .fl-embed--adopt, form classes Collective Adoption Form Template tokens, success
Join Rules gate embed/rules-gate.php Shows joining rules and an agreement checkbox. Returns an empty string once the fan has agreed this session. Place before the join embed. Fails open silently (renders nothing) if the Rules add-on is uninstalled. .fl-embed--rules-gate, .fl-rules-gate, form classes Join Rules Gate Body Template tokens, Join Rules Gate classes
Collective stats embed/collective-stats.php Exposes site-wide stats as PHP variables and can render an HTML stats template. .fl-cstats, .fl-cstats-* Collective stats tokens + PHP variables

Note: stats.php, latest-listing.php, random-listing.php, and collective-stats.php print only the template content. If you want one outer wrapper around them, add it in your own template or page.

Configuration

Snippet PHP Variables

These are PHP settings you place above the require line. They tell the embed what to show before Luster starts printing anything.

Variable Used by What it does
$luster_fanlisting_id Per-listing embeds Chooses which fanlisting the embed belongs to. Use 0 for collective affiliates, codes, and affiliate applications.
$luster_return Most embeds When true, the embed returns an HTML string instead of echoing it immediately.
$luster_redirect_url Public form embeds Advanced override for where a successful form action redirects. Used by join, update, reset, contact, collective contact, adopt, affiliate apply, code submit, collective update, KIM forms, and the rules gate.
$luster_per_page Members, affiliates, news feed, KIM list (subject mode), Wishlist Chooses how many rows or items to show per page.
$luster_sort_by Members Forces the starting member sort. Allowed values: name, country, added.
$luster_show_search Members Shows or hides member sorting and filter controls.
$luster_members_base Members Sets the URL used for member sort, filter, and pagination links.
$luster_date_format Members PHP date() format string for {fan_added}. Blank (the default) uses the ordinal style, e.g. "March 1st 2026".
$luster_lost_password_url Update Overrides the forgot-password link URL. There is no separate remove embed — removing an account is a checkbox inside the update form.
$luster_stats_template Stats Inline template override for one stats embed.
$luster_affiliates_base Affiliates Sets the URL used for affiliate pagination links.
$luster_page Affiliates Chooses which affiliate page number to show first.
$luster_append_submit Codes Defaults to false — codes.php shows only the gallery by default. Set to true to append the code submission form after the gallery instead of embedding codes-submit.php separately.
$luster_show_cats Updates Shows or hides category labels on updates.
$luster_contact_action Contact embeds Overrides the form POST URL. Useful when embedding on an external page.
$luster_status Owned, random listing Chooses owned-listing status pool. Owned allows current, upcoming, pending, closed, adopted_out, past (closed + adopted-out combined into one merged, sorted view), all; random allows current, upcoming, all (not past).
$luster_show_past Owned (current status only) Toggles whether the "Past Fanlistings" pseudo-nav tab/count (closed + adopted-out combined) appears alongside the current-listings view. Defaults to true.
$luster_show_closed Owned (current status only) Toggles whether the "Closed" pseudo-nav tab/count appears alongside the current-listings view, as a separate entry from the combined "Past Fanlistings" one. Defaults to false — Past Fanlistings alone covers Closed+Adopted Out by default; set this true to also break Closed out as its own nav entry. Has no effect on the all pool — closed listings are always included there (see $luster_exclude_pending above). Requires Migration 93.
$luster_show_adopted_out Owned (current status only) Same as $luster_show_closed, but for the "Adopted Out" pseudo-nav tab/count. Defaults to false. Requires Migration 93.
$luster_category_id Owned Shows owned listings in one category. If omitted, URL query parameters can choose the category.
$luster_hide_dropdown Owned Hides the owned category dropdown.
$luster_browse_by_category Owned, joined Shows a category index first, then listings after a visitor chooses a category.
$luster_exclude_pending Owned When status is all, hides genuinely pending listings (inactive with no archived/lifecycle status) unless set to false. Closed and Adopted Out listings are archived, not pending — even though they share the same legacy inactive flag, they always stay in the all pool regardless of this setting. Has no effect for other status values.
$luster_category Joined Chooses joined category. Use '' for selector mode, 'all' for all active listings grouped by category, or an exact category name.
$luster_show_all_by_default Joined Shows all joined listings immediately while still showing the selector.
$luster_wishlist_type Wishlist Filters wishlist entries. Allowed values: all, wanted, top, granted.
$luster_kim_signup_url KIM embeds Overrides the public KIM signup page link.
$luster_kim_update_url KIM form embeds Overrides the public KIM update page link.
$luster_kim_reset_url KIM form embeds Overrides the public KIM reset page link.
$luster_kim_list_url KIM form embeds Overrides the public KIM list page link.
$luster_kim_list_base kim-list.php In overview mode, subject links become this URL plus ?id=N. In subject mode, this is the back-to-list URL.
$luster_kim_subject_id kim-list.php When greater than 0, shows approved KIM members for that fanlisting instead of the overview.
$luster_kim_only_with_signups kim-list.php Overview mode only. When true (default), only shows fanlistings with at least one approved KIM member. Set to false to list all fanlistings.
$luster_count Collective stats How many newest listings are fetched for newest arrays. Default is 3.
$luster_cache_ttl Collective stats Cache lifetime in seconds for scalar/category collective stats. Use 0 for no cache.
Template Syntax

Token Syntax

All tokens use single curly braces. Write the token in your template, and Luster swaps it for the real value when the embed loads.

Pattern Meaning Example
{token} Replace with one value. {fan_name}
{each_name}...{/each_name} Repeat the inside once per row. {each_listing}<li>{listing_title}</li>{/each_listing}
{if_name}...{/if_name} Keep the inside only when true. {if_listing_image}<img src="{listing_image_url}">{/if_listing_image}
{if_no_name}...{/if_no_name} Usually the opposite of {if_name} when that inverse condition is supplied. {if_no_affiliates}No affiliates yet.{/if_no_affiliates}
{input} Raw form input HTML inside the field wrapper template. {input}
Token Reference

Listing Stats Tokens

Used by the stats_template setting, $luster_stats_template snippet variable, and public/embed/stats.php.

Related CSS: .fl-stats, .fl-stats-grid, .fl-stats-label, .fl-stats-value, .fl-stat-newmembers, .fl-stat-approved-by.

Token What it means
{stat_opened} Date the listing opened, formatted for display.
{stat_updated} Most recent activity date — whichever is later: the newest approved member's join date or the admin-set last-updated date. Shows N/A when neither is set.
{stat_approved} Number of approved members.
{stat_pending} Number of pending members.
{stat_countries} Number of distinct countries represented by approved members.
{stat_newmembers} Newest approved members, hyperlinked to their sites when available. Count is configurable per listing or globally: "Truncate after 5" shows the 5 most recent and appends ", and more…" once total approved members exceeds 5; "Show all" (limit 0, the default) shows every approved member who joined on the most recent join date — not the listing's entire membership history — and never appends ", and more…", since nothing is being cut off within that group. Raw HTML.
{stat_growth} Average approved members per day since the listing opened, with unit (e.g. 0.15 members/day).
{stat_growth_rate} Numeric growth rate only (e.g. 0.15). Use to build your own formatting.
{listing_title} Listing title.
{listing_subject} Listing subject.
{listing_url} Listing URL.
{approved_by} Uppercase network acronym: TFL, TAFL, or empty string. Plain text.
{network_name} Full network name: The Fanlistings Network, The Anime Fanlistings Network, or empty.
{tfl_url} The listing’s TFL approval page URL when one has been saved; otherwise https://thefanlistings.org/.
{tafl_url} The listing’s TAFL approval page URL when one has been saved; otherwise https://www.animefanlistings.com/.
{approval_url} The per-listing approval page URL exactly as saved, or blank when none is set. Requires Migration 94.
{if_approved_by}...{/if_approved_by} Shows the inside only when {approved_by} has a value.
{if_tfl}...{/if_tfl} Shows only when the listing has a TFL category assigned — independent of "Approved By".
{if_tafl}...{/if_tafl} Shows only when the listing has a TAFL category assigned — independent of "Approved By".
{if_stat_pending}...{/if_stat_pending} Shows the inside only when the pending member count is greater than zero.
{previous_owners} Comma-separated list of previous owners credited on the listing’s edit page, linked when a URL was given. Empty when none are credited.
{previous_owners_count} How many previous owners are credited.
{if_previous_owners}...{/if_previous_owners} Shows the inside only when at least one previous owner is credited.
{each_previous_owner}...{/each_previous_owner} Repeats the inside once per previous owner, for a custom layout instead of the flat {previous_owners} list. Contains its own row tokens, below.
{previous_owner_name} Row token, use inside {each_previous_owner}. The owner’s name, or their URL when no name was given.
{previous_owner_url} Row token, use inside {each_previous_owner}. The owner’s URL, or empty when none was given.
{if_previous_owner_url}...{/if_previous_owner_url} Row token, use inside {each_previous_owner}. Shows the inside only when this owner has a URL.

Choosing the right network conditional

Use {if_approved_by} when the same message works for both TFL and TAFL. Use {if_tfl} and {if_tafl} only when each network needs different text or a different link:

<!-- Same content for both networks — use {if_approved_by} -->
{if_approved_by}<b>Approved by:</b> {network_name}<br>{/if_approved_by}

<!-- Different content per network — use {if_tfl} and {if_tafl} -->
{if_approved_by}Approved by:
  <a href="{if_tfl}{tfl_url}{/if_tfl}{if_tafl}{tafl_url}{/if_tafl}">
    {network_name}
  </a>
{/if_approved_by}
Token Reference

Stats Embed Output Variables

After stats.php runs, your host page can use these PHP variables. They are already made safe for normal page output.

Variable What it contains
$luster_description The listing’s admin-set description text, or blank.
$luster_page_title The listing title (same as $luster_listing_title).
$luster_listing_title The listing title.
$luster_listing_subject The listing subject.
$luster_listing_url The listing URL.
$luster_meta_description The description when set, otherwise A fanlisting for {subject}. Good for <meta name="description">.

To use them in your page’s <head>, run the stats embed before the page starts printing HTML:

<?php
$luster_fanlisting_id = 1;
$luster_return = true;
$stats_html = require '/path/to/luster/public/embed/stats.php';
?>
<head>
  <title><?= $luster_listing_title ?> — My Site</title>
  <meta name="description" content="<?= $luster_meta_description ?>">
</head>
<body>
  <?= $stats_html ?>
</body>
Token Reference

Member Template Tokens

Used by the members_template setting in the members embed.

Related CSS: .fl-member-list, .fl-member-item, .fl-member-name, .fl-member-country, .fl-member-email, .fl-member-field.

Two render modes

New-style — use {each_member}...{/each_member} around the member row. Luster repeats that part for each member, while anything outside it shows once around the whole list. The page-level tokens below only work this way.

Legacy — if there is no {each_member} block, Luster treats the whole template as one member row and repeats all of it for every member. This still works, but it cannot use the page-level tokens below.

Token What it means
{fan_name} Member display name.
{fan_url} Member website URL. Blank when the member opted out via their "Show URL" preference, regardless of whether it's used inside {if_fan_url}...{/if_fan_url} or on its own.
{fan_email} Member email address. Use carefully — this prints publicly.
{fan_country} Member country.
{fan_added} Date the member joined. The built-in defaults wrap this in {if_sort_date}...{/if_sort_date} so it only shows during a Date Joined sort.
{fan_FIELDNAME} A custom additional field value. Replace FIELDNAME with the field's machine name — for example, {fan_fave_song}.
{fan_additional_fields} All of this listing's additional fields for the member, pre-rendered as labeled blocks, skipping any field that's blank for that member. Used by the built-in list default so new listings show custom fields without editing the template by hand.
{fan_additional_field_cells} All of this listing's additional fields for the member, pre-rendered as table cells, value only (blank fields render as a dash so columns stay aligned). Pairs with the page-level {additional_field_headers} token below — used by the built-in table default template.
{if_fan_url}...{/if_fan_url} Shows only when the member has a website URL.
{if_no_fan_url}...{/if_no_fan_url} Shows only when the member has no website URL.
{if_fan_country}...{/if_fan_country} Shows only when the member has a country set.
{if_no_fan_country}...{/if_no_fan_country} Shows only when the member has no country set.
{if_fan_additional_fields}...{/if_fan_additional_fields} / {if_no_fan_additional_fields}...{/if_no_fan_additional_fields} True when at least one additional field is non-blank for that member. Used by the built-in list default to wrap a leading separator so members with no field values don't get a dangling comma.
{if_fan_FIELDNAME}...{/if_fan_FIELDNAME} / {if_no_fan_FIELDNAME}...{/if_no_fan_FIELDNAME} Per-field conditional pair. Replace FIELDNAME with the field's machine name (matching {fan_FIELDNAME} above) to show or hide content based on whether that one specific field is blank for the member.
Token What it means
{join_url} URL to the join page.
{member_count} Total member count.
{stats_line} Summary line text, or blank.
{sort_link_date} Pre-built "Date Joined" sort link, or blank.
{sort_link_name} Pre-built "By Name" sort link, or blank.
{sort_link_country} Pre-built "By Country" sort link, or blank.
{additional_field_headers} Page-level (rendered once, not per member): one table header per additional field, labelled from the field definition. Pairs with {fan_additional_field_cells} to give table-style templates a real header row instead of repeating the label on every row.
{if_members}...{/if_members} Shows only when at least one member exists.
{if_no_members}...{/if_no_members} Shows only when there are no members (empty state).
{if_country_sort}...{/if_country_sort} Content rendered only when the country summary list is shown instead of individual member rows.
{if_no_country_sort}...{/if_no_country_sort} Content rendered when displaying individual member rows (name/added sort), removed when the country summary list is shown instead.
{if_sort_date}...{/if_sort_date} Content rendered only when the list is currently sorted by Date Joined. The built-in defaults use this so a join date only appears next to a Date Joined sort.
{if_no_sort_date}...{/if_no_sort_date} Content rendered only when the list is NOT currently sorted by Date Joined.
Token Reference

Owned Listing Tokens

Used by the owned_template setting and public/embed/owned.php.

Past Fanlistings uses a separate template. When the resolved status/view is past ($luster_status = 'past' — closed + adopted-out combined), owned.php resolves a past_owned_template setting instead of owned_template. Every other status (current/upcoming/pending/closed/adopted_out/all) still uses owned_template unchanged. past_owned_template is edited on its own “Past Fanlistings” section on the Collective Templates page, but shares every loop/row token documented below — it’s a separate stored value, not a separate token set.

Related CSS: .fl-listing-list, .fl-listing-item, .fl-listing-*, .fl-listing-section, .fl-status-badge (the last one used by the built-in past_owned_template default for its Closed/Adopted Out badges).

Token What it means
{each_listing}...{/each_listing} Flat mode. Repeats the inside once for every owned listing shown.
{each_current}...{/each_current} Sectioned mode. Repeats for current owned listings.
{each_upcoming}...{/each_upcoming} Sectioned mode. Repeats for upcoming owned listings.
{each_pending}...{/each_pending} Sectioned mode. Repeats for pending/inactive owned listings.
{each_closed}...{/each_closed} Sectioned mode. Repeats for closed owned listings. Requires Migration 93.
{each_adopted_out}...{/each_adopted_out} Sectioned mode. Repeats for adopted-out owned listings. Requires Migration 93.
{each_past}...{/each_past} Sectioned mode. Repeats for closed + adopted-out owned listings combined, in one merged loop — use instead of separate {each_closed}/{each_adopted_out} boxes for a single “Past Fanlistings” section. Rows still carry their own real status, so {if_status_closed}/{if_status_adopted_out} work inside it.
Token What it means
{listing_title} Listing title/name.
{listing_url} Listing URL (may be blank for archived listings).
{listing_subject} Listing subject/topic.
{listing_status} current, upcoming, pending, closed, or adopted_out. The last two require Migration 93. (A row's real status is always one of these five — past is a view/section, not a per-row status.)
{listing_email} Listing contact email.
{listing_type} Listing type value.
{listing_category} Comma-separated category names for the listing.
{listing_image_url} The listing image URL, or blank if none is set. A same-page ?luster_img=listings/<filename> query URL rather than a direct link into /uploads/ — requires the one-time setup line on the host page to resolve.
{date_opened} Listing opened date.
{date_updated} Most recent of: newest approved member date or admin-set last-updated date.
{member_count} Approved member count.
{member_pending_count} Pending member count for this listing. {pending_count} is an alias for the same value — use whichever reads better in your template.
{country_count} Number of distinct countries represented by approved members.
{approved_by} Uppercase network acronym: TFL, TAFL, or empty string. Plain text.
{network_name} Full network name: The Fanlistings Network, The Anime Fanlistings Network, or empty.
{tfl_url} The listing’s TFL approval page URL when one has been saved; otherwise https://thefanlistings.org/.
{tafl_url} The listing’s TAFL approval page URL when one has been saved; otherwise https://www.animefanlistings.com/.
{approval_url} The per-listing approval page URL exactly as saved, or blank. Requires Migration 94.
{listing_description} Free-text listing description, or blank when none is set. Requires Migration 74.
{adopted_to_name} Name of the person or site that adopted this listing. Non-empty only for adopted_out listings. Requires Migration 93.
{adopted_to_url} URL for the new owner of an adopted-out listing, or blank. Requires Migration 93.
{archive_note} Optional admin note explaining the closure or adoption. Blank when not set. Requires Migration 93.
{archived_at} Date the listing was closed or adopted out. Blank for non-archived listings. Requires Migration 93.
Conditional What it means
{if_listing_url}...{/if_listing_url} Shows only when the listing URL is non-empty. Useful for archived listings that may have no URL.
{if_no_listing_url}...{/if_no_listing_url} Shows only when the listing URL is blank.
{if_listing_image}...{/if_listing_image} Shows only when the listing has an image.
{if_no_listing_image}...{/if_no_listing_image} Shows only when the listing has no image.
{if_description}...{/if_description} Shows only when {listing_description} is non-empty. Requires Migration 74.
{if_countries}...{/if_countries} Shows only when country count is greater than zero.
{if_pending}...{/if_pending} Shows only when pending member count is greater than zero.
{if_status_current}...{/if_status_current} Shows only for current listings.
{if_status_upcoming}...{/if_status_upcoming} Shows only for upcoming listings.
{if_status_pending}...{/if_status_pending} Shows only for pending listings.
{if_status_closed}...{/if_status_closed} Shows only for closed listings. Requires Migration 93.
{if_status_adopted_out}...{/if_status_adopted_out} Shows only for adopted-out listings. Requires Migration 93.
{if_date_updated}...{/if_date_updated} Shows only when the last-updated date is set.
{if_approved_by}...{/if_approved_by} Shows only when {approved_by} is non-empty.
{if_tfl}...{/if_tfl} Shows only when the listing has a TFL category assigned (Network & Category on the edit form) — independent of "Approved By". Used by the built-in default owned template, nested inside {if_approved_by}.
{if_tafl}...{/if_tafl} Shows only when the listing has a TAFL category assigned (Network & Category on the edit form) — independent of "Approved By". Used by the built-in default owned template, nested inside {if_approved_by}.

Use these when your owned-listings template is split into sections, such as current, upcoming, or pending listings.

Token What it means
{current_owned_count} Number of current listings in the rendered set.
{upcoming_owned_count} Number of upcoming listings in the rendered set.
{pending_owned_count} Number of pending listings in the rendered set.
{closed_owned_count} Number of closed listings in the rendered set. Requires Migration 93.
{adopted_out_owned_count} Number of adopted-out listings in the rendered set. Requires Migration 93.
{past_owned_count} Number of closed + adopted-out listings combined in the rendered set (the “Past Fanlistings” count).
{total_count} Total number of listings in the rendered set.
{if_current_listings}...{/if_current_listings} Shows only when current listings exist.
{if_upcoming_listings}...{/if_upcoming_listings} Shows only when upcoming listings exist.
{if_pending_listings}...{/if_pending_listings} Shows only when pending listings exist.
{if_closed_listings}...{/if_closed_listings} Shows only when closed listings exist. Requires Migration 93.
{if_adopted_out_listings}...{/if_adopted_out_listings} Shows only when adopted-out listings exist. Requires Migration 93.
{if_past_listings}...{/if_past_listings} Shows only when the combined closed + adopted-out (“Past Fanlistings”) set is non-empty.
Token Reference

Latest & Random Listing Tokens

Latest and random listings use the same listing tokens as the owned-listings template. Put your listing design inside {each_listing}...{/each_listing} so Luster knows which part to fill in.

Used by random_listing_template and public/embed/random-listing.php. It shows one listing chosen at random.

Default CSS classes: .fl-random-listing, .fl-random-listing-item, .fl-random-listing-image-wrap, .fl-random-listing-image, .fl-random-listing-body, .fl-random-listing-title, .fl-random-listing-subject.

Used by latest_listing_template and public/embed/latest-listing.php. It shows one listing: the newest one by open date.

Default CSS classes: .fl-latest-listing, .fl-latest-listing-item, .fl-latest-listing-image-wrap, .fl-latest-listing-image, .fl-latest-listing-body, .fl-latest-listing-title, .fl-latest-listing-subject, .fl-latest-listing-date.

Token Reference

Joined Listing Tokens

Used by the joined_template setting and public/embed/joined.php.

Related CSS: .fl-joined-list, .fl-joined-*, .fl-category-*.

Token What it means
{each_joined}...{/each_joined} Flat mode. Repeats once for each joined listing shown.
{each_current_joined}...{/each_current_joined} Section-style mode for active joined listings. The data is ordered by category, but the loop does not create category headers by itself.
Token What it means
{listing_subject} What the joined fanlisting is about, such as Archeology or Marilyn Monroe.
{listing_url} Joined listing URL.
{listing_category} Joined listing category.
{listing_type} Always resolves to the literal text listing — reserved for future use (clique/collective/shrine/etc. joined-listing types aren't distinguished yet).
{listing_image_url} The joined listing image URL, or blank if none is set. A same-page ?luster_img=joined/<filename> query URL rather than a direct link into /uploads/ — requires the one-time setup line on the host page to resolve.
{listing_status} Joined listing status text.
{date_joined} Date you joined the listing.
{if_listing_image}...{/if_listing_image} Shows only when the joined listing has an image.
{if_no_listing_image}...{/if_no_listing_image} Shows only when the joined listing has no image.
Token What it means
{current_count} Number of active joined listings in the rendered set.
{total_count} Total number of joined listings in the rendered set.
{if_current_listings}...{/if_current_listings} Shows only when active joined listings exist.
Token Reference

Affiliate Section Tokens

Used by per-listing affiliates_section_template and collective collective_affiliates_section_template.

Related CSS: .fl-affiliate-list, .fl-affiliate-item, .fl-affiliates-section, .fl-affiliate-apply-*.

Token What it means
{each_affiliate}...{/each_affiliate} Repeats the inside once per affiliate on the current page.
{site_name} The listing's title in per-listing mode, or the collective site name in collective mode.
{aff_name} Affiliate site name.
{aff_url} Affiliate site URL.
{aff_image_url} The affiliate image URL, or empty string when the affiliate has no image. A same-page ?luster_img=affiliates/<filename> query URL rather than a direct link into /uploads/ — requires the one-time setup line on the host page to resolve. Use inside {if_aff_image} to avoid broken image tags.
{affiliate_apply_url} URL to the affiliate application form for this listing.
{affiliate_apply_toggle} Clickable trigger that shows/hides the affiliate application form. Renders as <a role="button"> (text link style) or <button type="button"> (button style), set per listing in Preferences. Empty when affiliate applications are disabled.
{affiliate_apply_form} The affiliate application form itself, shown/hidden by clicking {affiliate_apply_toggle}. Place it anywhere in the template — it doesn't have to sit next to the toggle. Starts hidden. Empty when affiliate applications are disabled.
{affiliates_count} Total active affiliate count for this embed.
{if_affiliates}...{/if_affiliates} Shows only when at least one affiliate exists.
{if_no_affiliates}...{/if_no_affiliates} Shows only when no affiliates exist.
{if_aff_image}...{/if_aff_image} Inside {each_affiliate}: shows only when the affiliate has an image.
{if_no_aff_image}...{/if_no_aff_image} Inside {each_affiliate}: shows only when the affiliate has no image. Use to render a fallback text link.
Token Reference

Collective Stats Tokens

Used by the collective_stats_template setting and public/embed/collective-stats.php.

Related CSS: .fl-cstats, .fl-cstats-grid, .fl-cstats-label, .fl-cstats-value, .fl-cstats-newest, .fl-cstats-random.

Token What it means
{site_name} The collective/site name.
{owned_active} Number of current/open owned listings.
{owned_upcoming} Number of upcoming owned listings.
{owned_pending} Number of pending/inactive owned listings.
{owned_tfl_count} Number of active owned listings approved by TFL.
{owned_tafl_count} Number of active owned listings approved by TAFL.
{joined_active} Number of active joined listings.
{joined_pending} Number of pending joined listings.
{joined_total_cats} Number of distinct categories across joined listings.
{joined_tfl_count} Number of active joined listings in TFL categories.
{joined_tafl_count} Number of active joined listings in TAFL categories.
{members_total} Total members across all listings, including pending.
{members_approved} Approved members across all listings.
{members_pending} Pending members across all listings.
{countries_count} Number of distinct countries across approved members.
{affiliates_sitewide} Active collective-level affiliates (fanlisting_id IS NULL).
{affiliates_total} All active affiliates across every scope (collective + per-listing).
{collective_last_updated} Most recent "opened" date across owned listings, formatted.
{owned_newest_title} Title of the newest current owned listing, or blank.
{owned_newest_subject} Subject of the newest owned listing, or blank.
{owned_newest_url} URL of the newest current owned listing, or blank.
{owned_random_title} Title of one random current owned listing, or blank.
{owned_random_subject} Subject of a random owned listing, or blank.
{owned_random_url} URL of one random current owned listing, or blank.
{tfl_url} TFL website URL.
{tafl_url} TAFL website URL.
{if_countries}...{/if_countries} Shows only when countries count is greater than zero.
{if_pending}...{/if_pending} Shows only when pending member count is greater than zero.
{if_owned_upcoming}...{/if_owned_upcoming} Shows only when at least one owned listing is marked upcoming.
{if_owned_pending}...{/if_owned_pending} Shows only when at least one owned listing is marked pending.
{if_affiliates_sitewide}...{/if_affiliates_sitewide} Shows only when at least one collective-level affiliate exists.
{if_affiliates_total}...{/if_affiliates_total} Shows only when at least one affiliate exists in any scope.

collective-stats.php also gives your page PHP variables after you include it. These are not brace tokens; use them like normal PHP variables.

Variable What it means
$luster_owned Total owned listings.
$luster_owned_active Current/open owned listings.
$luster_owned_upcoming Upcoming owned listings.
$luster_owned_pending Pending/inactive owned listings.
$luster_joined Total joined listings.
$luster_joined_active Active joined listings.
$luster_joined_approved Active joined listings that are not upcoming or pending.
$luster_joined_upcoming Upcoming joined listings.
$luster_joined_pending Pending joined listings.
$luster_affiliates Active collective affiliates.
$luster_members_approved Approved members across all listings.
$luster_members_pending Pending members across all listings.
$luster_members_total Total members across all listings.
$luster_owned_growth_rate Average current owned listings added per year.
$luster_joined_growth_rate Average active joined listings added per year.
$luster_members_growth_rate Average approved members added per day.
$luster_owned_newest Array of newest current owned Listing objects.
$luster_joined_newest Array of newest active joined JoinedListing objects.
$luster_owned_random One random current owned Listing object, or null.
$luster_joined_random One random active joined JoinedListing object, or null.
$luster_categories Array of owned-listing categories with counts.
$luster_countries_count Distinct countries across approved members.
$luster_total_cats Number of owned-listing categories. Alias for count($luster_categories).
$luster_owned_tfl_count Number of active owned listings approved by TFL.
$luster_owned_tafl_count Number of active owned listings approved by TAFL.
$luster_joined_tfl_count Number of active joined listings in TFL categories.
$luster_joined_tafl_count Number of active joined listings in TAFL categories.
$luster_joined_categories Array of joined-listing categories with counts.
$luster_joined_total_cats Number of distinct categories across joined listings.
$luster_affiliates_sitewide Active collective-level affiliates (fanlisting_id IS NULL).
$luster_affiliates_total All active affiliates across every scope (collective + per-listing).
$luster_collective_last_updated Most recent "opened" date across owned listings, formatted.

These older variable names are included to make it easier to move existing Enthusiast collective pages into Luster.

Alias Maps to
$total_cats, $collective_categories Number of owned-listing categories.
$owned $luster_owned
$owned_current $luster_owned_active
$owned_upcoming $luster_owned_upcoming
$owned_pending $luster_owned_pending
$joined, $joined_total $luster_joined
$joined_current $luster_joined_active
$joined_approved $luster_joined_approved
$joined_upcoming $luster_joined_upcoming
$joined_pending $luster_joined_pending
$affiliates_collective, $collective_affiliates $luster_affiliates
$collective_total_fans_approved $luster_members_approved
$collective_total_fans_pending $luster_members_pending
$collective_total_fans $luster_members_total
$countries_count $luster_countries_count
$owned_growth_rate $luster_owned_growth_rate
$joined_growth_rate $luster_joined_growth_rate
$collective_fans_growth_rate $luster_members_growth_rate
$owned_newest, $owned_random Flat arrays with keys url, name, title, subject, desc, listingtype, opened.
$joined_newest, $joined_random Flat arrays with keys url, name, subject, desc, category, added.
Token Reference

Pagination Tokens

Used by per-listing pagination_template, collective pagination templates, and the shared Pagination renderer.

Related CSS: .fl-pagination-nav, .fl-page-prev, .fl-page-next, .fl-page-link, .fl-page-current, .fl-page-gap.

Token What it means
{if_pages}...{/if_pages} Shows only when there is more than one page.
{current_page} Current page number.
{total_pages} Total page count.
{prev_url} URL for the previous page, or blank.
{next_url} URL for the next page, or blank.
{if_prev}...{/if_prev} Shows only when a previous page exists.
{if_next}...{/if_next} Shows only when a next page exists.
{each_page}...{/each_page} Repeats for each page item in the pagination window.
{page_label} Page number label, or gap label.
{page_url} URL for a linked page item, or blank for current/gap items.
{if_current}...{/if_current} Shows only for the current page item.
{if_linked}...{/if_linked} Shows only for clickable page items.
{if_gap}...{/if_gap} Shows only for gap items.
Token Reference

Form Field Wrapper Tokens

Used by field_wrapper_template, which controls the little block around each form field: label, input, hint, and error text.

Related CSS: .fl-field, .fl-label, .fl-input, .fl-select, .fl-textarea, .fl-field-hint, .fl-field-error, .fl-error.

Token What it means
{input} Raw, trusted input/select/textarea HTML generated by Luster. Raw HTML.
{label} Field label text.
{field_id} Input ID, when the field has one.
{required_html} A <span class="fl-required">*</span> when the field is required; empty when optional. Raw HTML.
{hint} Help text for the field.
{error} Validation error text for the field.
{lost_password_url} Password reset URL for forms that need a forgot-password link.
{if_field_id}...{/if_field_id} Shows only when a field ID exists.
{if_no_field_id}...{/if_no_field_id} Shows only when no single field ID exists.
{if_hint}...{/if_hint} Shows only when hint text exists.
{if_error}...{/if_error} Shows only when a validation error exists.
{if_lost_password_url}...{/if_lost_password_url} Shows only when a lost-password URL exists.
Token Reference

Form Body Template Tokens

Several public forms support a fully admin-editable whole-form body template, not just the generic field wrapper above. Each {field_x} token below is the full wrapped block (label + input + hint + error, per Form Field Wrapper Tokens); {field_x_input} is the bare <input>/<select>/<textarea> only, for custom layouts. {captcha_block} / {captcha_block_input} follow the same wrapped/bare pattern for the captcha question field. All of these are edited the same way as other listing/collective templates — per-listing ones under Edit Listing → Templates, collective ones under Admin → Collective → Templates.

Used by join_form_template (per-listing) / listing_default_join_form_template (global default) in public/embed/join.php. Unlike Update/Reset/KIM Reset below, this covers the entire join form in one step — there is no separate fixed PHP-rendered step.

Token What it means
{listing_title} Listing title/name.
{listing_subject} Listing subject/topic.
{listing_url} Listing URL.
{field_name} / {field_name_input} Name field (full block / raw input).
{field_email} / {field_email_input} Email field (full block / raw input).
{field_url} / {field_url_input} Website URL field (full block / raw input).
{field_country} / {field_country_input} Country field (full block / raw input). Empty string when the country field is disabled for this listing.
{additional_fields} All of this listing's additional fields, pre-rendered as full label + input blocks, one per line.
{additional_fields_input} All of this listing's additional fields, pre-rendered as raw inputs only (no labels), one per line.
{field_password} / {field_password_input} Password field (full block / raw input).
{field_password_confirm} / {field_password_confirm_input} Confirm password field (full block / raw input).
{captcha_block} / {captcha_block_input} Captcha question field (full block / raw input).
{captcha_question} Just the captcha question text, for custom layouts.
{submit_button} The "Join Listing" submit button.
{clear_button} The "Clear Form" reset button.

Used by update_form_template in public/embed/update.php. Covers only the sign-in step (email + password to reach the editable form). The step where a member actually edits or deletes their membership is fixed and cannot be customized, so a mistake here can never lock anyone out of updating their info — see templates/default/update.php's hardcoded signed-in branch.

Token What it means
{listing_title} Listing title/name.
{listing_subject} Listing subject/topic.
{listing_url} Listing URL.
{field_signin_email} Email field.
{field_signin_password} Password field.
{lost_password_url} Forgot-password link.
{submit_button} The submit button.
{clear_button} The "Clear Form" reset button.

Used by reset_form_template in public/embed/reset.php. Covers only the request step (email address to receive the reset link). The step where a member actually sets their new password is fixed and cannot be customized, so a mistake here can never lock anyone out of resetting their password — see templates/default/reset_confirm.php's hardcoded markup.

Token What it means
{listing_title} Listing title/name.
{listing_subject} Listing subject/topic.
{listing_url} Listing URL.
{field_email} Email field.
{reset_request_url} Same value as the form's own action URL. Useful for an explicit link back to this request page (e.g. a "try again" link) inside a custom layout, rather than relying only on the submit button.
{submit_button} The submit button.
{clear_button} The "Clear Form" reset button.

Used by contact_form_template in public/embed/contact.php and collective_contact_form_template (same tokens) in public/embed/collective-contact.php.

Token What it means
{field_name} Sender name field.
{field_email} Sender email field.
{field_url} Sender URL field (optional).
{field_subject} Message subject field.
{field_message} Message body field.
{captcha_block} Captcha question field.
{captcha_question} Just the captcha question text, for custom layouts.
{submit_button} The form's submit button.
{clear_button} A reset button to clear the form.

Used by codes_submit_form_template in public/embed/codes-submit.php (per-listing) and collective_codes_submit_form_template in public/embed/collective-codes-submit.php (site-wide).

Token What it means
{listing_title}, {listing_subject}, {listing_url} Per-listing embed only.
{site_name} Collective embed only.
{field_code_image} Code image upload field.
{field_submitter_name} Submitter/donor name field.
{field_submitter_email} Submitter email field.
{field_submitter_url} Submitter URL field (optional).
{captcha_block} Captcha question field.
{captcha_question} Just the captcha question text, for custom layouts.

Used by affiliate_apply_form_template in public/embed/affiliate-apply.php (per-listing) and collective_affiliate_apply_form_template (site-wide).

Token What it means
{site_name} Collective mode only.
{field_name} Applicant site name field.
{field_url} Applicant site URL field.
{field_email} Applicant email field.
{field_image} Applicant button/image URL field.
{field_message} Optional message field.
{captcha_block} Captcha question field.
{captcha_question} Just the captcha question text, for custom layouts.

Used by collective_adoption_form_template in public/embed/adopt.php. Requires the Adoption add-on. There is no per-listing variant — the visitor picks which listing to apply for from a dropdown inside the form.

Token What it means
{site_name} The collective/site name.
{field_listing_id} Listing-picker dropdown field.
{field_name} Applicant name field.
{field_email} Applicant email field.
{field_url} Applicant URL field (optional).
{field_message} Optional message field.
{captcha_block} Captcha question field.
{captcha_question} Just the captcha question text, for custom layouts.
{submit_button} The form's submit button.
{clear_button} A reset button to clear the form.
Token Reference

Success Template Tokens

Used by public form success/action confirmation templates.

Related CSS: .fl-success, .fl-success-body, .fl-success-actions.

Token What it means
{action} The action slug, such as joined-pending or contact-sent.
{fan_name} Fan/member name when available.
{listing_title} Listing title when available.
{listing_url} Listing URL when available.
{sender_name} Contact sender name.
{sender_email} Contact sender email.
{site_name} Site or collective name.
{owner_name} Owner/admin name.
{owner_email} Owner/admin email.
{aff_name} Affiliate applicant site name.
{aff_url} Affiliate applicant URL.
{aff_email} Affiliate applicant email.
Conditional What it means
{if_joined}...{/if_joined} Shows only after an auto-approved join.
{if_joined_pending}...{/if_joined_pending} Shows only after a join awaiting approval.
{if_updated}...{/if_updated} Shows only after an approved update.
{if_updated_pending}...{/if_updated_pending} Shows only after an update awaiting approval.
{if_removed}...{/if_removed} Shows only after removal.
{if_reset_sent}...{/if_reset_sent} Shows only after a reset email is requested.
{if_reset_done}...{/if_reset_done} Shows only after password reset completion.
{if_code_submitted}...{/if_code_submitted} Shows only after a code submission.
{if_kim_signed_up}...{/if_kim_signed_up} Shows only after a KIM signup.
{if_kim_updated}...{/if_kim_updated} Shows only after a KIM update.
{if_kim_reset_done}...{/if_kim_reset_done} Shows only after KIM password reset completion.
{if_adopt_submitted}...{/if_adopt_submitted} Shows only after an adoption application.
{if_contact_sent}...{/if_contact_sent} Shows only after a contact form send.
{if_affiliate_apply_sent}...{/if_affiliate_apply_sent} Shows only after an affiliate application.
{if_aff_email}...{/if_aff_email} Shows only when affiliate email is present.
{if_no_aff_email}...{/if_no_aff_email} Shows only when affiliate email is blank.
Token Reference

Codes Template Tokens

Used by per-listing codes_template and collective collective_codes_template in public/embed/codes.php. Both are fully admin-editable and render through the same code.

Related CSS: .fl-codes, .fl-code-group, .fl-code-group-label, .fl-code-list, .fl-code-item, .fl-code-image, .fl-code-caption.

Token What it means
{each_code}...{/each_code} Flat mode — repeats once per approved code. In grouped mode, nest this inside {each_size_group} to repeat per code within the current group.
{each_size_group}...{/each_size_group} Grouped mode — repeats once per code size group.
Token What it means
{site_name} The listing's title in per-listing mode, or the collective site name in collective mode.
{codes_submit_toggle} Clickable trigger that shows/hides the code donation form, same pattern as the affiliate application toggle (<a role="button"> for text link style, <button type="button"> for button style). Empty when code donations are disabled.
{codes_submit_form} The code donation form itself, shown/hidden by clicking {codes_submit_toggle}. Place it anywhere in the template. Starts hidden. Empty when code donations are disabled.
{if_codes}...{/if_codes} Shows only when at least one code exists.
{if_no_codes}...{/if_no_codes} Shows only when no codes exist.
Token What it means
{group_size} Size label for the group, such as 50x50px or Other.
{group_code_count} Number of codes in the current group.
Token What it means
{code_url} The code image URL. A same-page ?luster_img=codes/<filename> query URL rather than a direct link into /uploads/ — requires the one-time setup line on the host page to resolve.
{code_width} Code width, or blank.
{code_height} Code height, or blank.
{code_size} Size label such as 50x50, or blank.
{code_name} Optional per-code label/name.
{code_donor_name} Donor/submitter name, or blank.
{code_donor_url} Donor/submitter URL, or blank.
Conditional What it means
{if_size}...{/if_size} Shows only when width and height are known.
{if_size_changed}...{/if_size_changed} Flat mode only. Shows when the code size differs from the previous code.
{if_donor}...{/if_donor} Shows only when donor name exists.
{if_no_donor}...{/if_no_donor} Shows only when donor name is blank.
{if_donor_url}...{/if_donor_url} Shows only when donor URL exists.
{if_no_donor_url}...{/if_no_donor_url} Shows only when donor URL is blank.
{if_code_name}...{/if_code_name} Shows only when code name exists.
Token Reference

News Feed Template Tokens

Used by per-listing newsfeed_template and collective collective_newsfeed_template. Requires the News Feed add-on.

Related CSS: .fl-newsfeed, .fl-newsfeed-item, .fl-newsfeed-header, .fl-newsfeed-title, .fl-newsfeed-date, .fl-newsfeed-body, .fl-newsfeed-meta, .fl-newsfeed-categories, .fl-newsfeed-category-tag, .fl-newsfeed-img.

Token What it means
{each_newsfeed_entry}...{/each_newsfeed_entry} Repeats once per entry on the current page.
{newsfeed_title} Entry title.
{newsfeed_date} Display date, formatted like June 8, 2026.
{newsfeed_body_html} Entry body as safe generated HTML with line breaks. The raw body is escaped first, then a small allowlist is selectively converted back: <b>, <strong>, <i>, <em>, <u>, <s>, <p>, <blockquote>, <a>, <img>, <br>. class= is only kept if every token matches fl-newsfeed-* or nf-*; <img> always gets .fl-newsfeed-img added; <a> always gets target="_blank" rel="noopener noreferrer" added. Raw HTML.
{newsfeed_author} Entry author, or blank.
{newsfeed_categories} Comma-separated entry category names.
{if_author}...{/if_author} Shows only when author exists.
{if_categories}...{/if_categories} Shows only when categories exist.
{if_newsfeed}...{/if_newsfeed} Shell-level. Shows only when at least one entry exists on the current page.
{if_no_newsfeed}...{/if_no_newsfeed} Shell-level. Shows only when no entries exist.
{site_name} Available in both templates. Substituted into the shell before the loop runs.
{listing_title}, {listing_subject}, {listing_url} Per-listing embed only — not available to collective_newsfeed_template. Also substituted into the shell before the loop runs.
Token Reference

Wishlist Template Tokens

Used by collective wishlist_template and public/embed/wishlist.php. Requires the Wishlist add-on.

Related CSS: .fl-wishlist-group, .fl-wishlist-list, .fl-wishlist-item, .fl-wishlist-image, .fl-wishlist-info, .fl-wishlist-subject, .fl-wishlist-type-badge.

Token What it means
{each_wishlist_item}...{/each_wishlist_item} Flat mode. Repeats once for every wishlist entry, regardless of type.
{each_wishlist_item_top}...{/each_wishlist_item_top} Sectioned mode. Repeats once per top-wanted entry only.
{each_wishlist_item_wanted}...{/each_wishlist_item_wanted} Sectioned mode. Repeats once per wanted entry only.
{each_wishlist_item_granted}...{/each_wishlist_item_granted} Sectioned mode. Repeats once per granted entry only.

Using any of the three type-scoped loops switches the template into sectioned mode — put each one under its own heading rather than relying on {item_type} to sort them visually. Row tokens below work identically inside any of the four loops.

Token What it means
{site_name} The collective site name.
{if_has_top}...{/if_has_top} Shell-level. Shows only when at least one top-wanted entry exists.
{if_has_wanted}...{/if_has_wanted} Shell-level. Shows only when at least one wanted entry exists.
{if_has_granted}...{/if_has_granted} Shell-level. Shows only when at least one granted entry exists.
Token What it means
{item_subject} Wishlist subject/title.
{item_url} Optional URL for the subject.
{item_type} Human-readable type label: Top Wanted, Wanted, or Granted.
{item_category} Wishlist category, or blank.
{item_description} Wishlist description, or blank.
{item_image_url} The wishlist image URL, or blank if none is set. A same-page ?luster_img=wishlist/<filename> query URL rather than a direct link into /uploads/ — requires the one-time setup line on the host page to resolve.
{if_item_url}...{/if_item_url} Shows only when URL exists.
{if_no_item_url}...{/if_no_item_url} Shows only when URL is blank.
{if_item_category}...{/if_item_category} Shows only when category exists.
{if_item_description}...{/if_item_description} Shows only when description exists.
{if_item_image}...{/if_item_image} Shows only when image exists.
{if_type_top}...{/if_type_top} Shows only for top-wanted entries.
{if_type_wanted}...{/if_type_wanted} Shows only for wanted entries.
{if_type_granted}...{/if_type_granted} Shows only for granted entries.
Token Reference

KIM Templates

The KIM add-on has separate editable templates for its lists and forms. You can edit them in Admin → Collective → Templates under the KIM group. If you leave one blank, Luster uses its built-in version.

Used by kim_signup_form_template in public/embed/kim-signup.php. Covers the entire sign-up form in one step.

Token What it means
{site_name} The collective/site name from settings.
{field_name} / {field_name_input} Name field (full block / raw input).
{field_url} / {field_url_input} Website URL field (full block / raw input).
{field_email} / {field_email_input} Email field (full block / raw input).
{field_fanlisting_id} / {field_fanlisting_id_input} Fanlisting-picker dropdown field (full block / raw input).
{field_password} / {field_password_input} Password field (full block / raw input).
{field_password_confirm} / {field_password_confirm_input} Confirm password field (full block / raw input).
{captcha_block} / {captcha_block_input} Captcha question field (full block / raw input).
{captcha_question} Just the captcha question text, for custom layouts.
{submit_button} The "Sign Up" submit button.
{clear_button} The "Clear" reset button.

Used by collective_kim_list_overview_template for the main KIM list page, where visitors see all fanlistings that have KIM sign-ups.

Token What it means
{each_kim_listing}...{/each_kim_listing} Repeats once per fanlisting that has at least one approved KIM member.
{listing_title} Fanlisting display name. Use inside {each_kim_listing}.
{listing_subject} What the fanlisting is about. Use inside {each_kim_listing}.
{listing_url} Link to the fanlisting. Use inside {each_kim_listing}.
{listing_kim_url} Link to this fanlisting's KIM member list. Use inside {each_kim_listing}.
{listing_kim_count} Number of approved KIM members for this fanlisting. Use inside {each_kim_listing}.
{if_has_listings}...{/if_has_listings} Shows only when at least one fanlisting has approved KIM members.
{if_no_listings}...{/if_no_listings} Shows only when no fanlistings have approved KIM members (empty state).

Used by collective_kim_list_subject_template for one fanlisting’s KIM member list.

Token What it means
{each_kim_member}...{/each_kim_member} Repeats once per approved KIM member.
{member_name} KIM member name. Use inside {each_kim_member}.
{member_url} KIM member URL, or blank. Use inside {each_kim_member}.
{if_member_url}...{/if_member_url} Inside {each_kim_member}: shows only when the member has a website.
{if_no_member_url}...{/if_no_member_url} Inside {each_kim_member}: shows only when the member has no website.
{listing_title} Fanlisting display name.
{listing_subject} What the fanlisting is about.
{listing_url} Link to the fanlisting.
{kim_overview_url} Link back to the KIM list overview page.
{kim_signup_url} Link to the KIM sign-up form.
{if_kim_overview_url}...{/if_kim_overview_url} Shows only when a KIM overview URL is available.
{if_kim_signup_url}...{/if_kim_signup_url} Shows only when a KIM sign-up URL is available.
{if_has_kim_members}...{/if_has_kim_members} Shows only when at least one approved KIM member exists.
{if_no_kim_members}...{/if_no_kim_members} Shows only when there are no approved KIM members (empty state).
{pagination} Pagination links (embed mode only). Empty string on the direct route.

Used by kim_update_form_template for the KIM update form. The regular field tokens print the whole field block; the _input versions print just the form control when you want to build your own layout.

Token What it means
{site_name} The collective/site name from settings.
{field_email} / {field_email_input} Email field (full block / raw input).
{field_password} / {field_password_input} Password field (full block / raw input).
{lost_password_url} URL to the KIM password reset page.
{if_lost_password_url}...{/if_lost_password_url} Shows only when a reset URL is available.
{submit_button} The submit button.
{clear_button} A reset button that clears the form.

Used by kim_reset_form_template when kim-reset.php is embedded and the template string is non-empty. Covers only the email-entry step. The step where a member actually sets their new password is fixed and cannot be customized, so a mistake here can never lock anyone out of resetting their password — see templates/default/addons/kim/reset-confirm.php's hardcoded markup.

Token What it means
{site_name} The collective/site name from settings.
{field_email} / {field_email_input} Email field (full block / raw input).
{reset_request_url} Same value as the form's own action URL. Useful for an explicit link back to this request page inside a custom layout, rather than relying only on the submit button.
{submit_button} The submit button.
{clear_button} A reset button that clears the form.

kim_member_template is the older fallback for KIM member rows. New setups should use collective_kim_list_subject_template, which gives you more control over the whole subject page.

Token What it means
{each_kim_member}...{/each_kim_member} Repeats once per approved KIM member for the selected fanlisting.
{kim_name} KIM member name.
{kim_url} KIM member URL, or blank.
{listing_title} Related fanlisting title.
{listing_subject} Related fanlisting subject.
{if_kim_url}...{/if_kim_url} Shows only when KIM member URL exists.
{if_no_kim_url}...{/if_no_kim_url} Shows only when KIM member URL is blank.
Token Reference

Collective Update Form Template Tokens

Used by collective_update_form_template. Controls the email-request step (Step 1) of embed/collective-update.php, where the member submits their email to receive a verification link. Edit in Admin → Collective → Templates.

Step 2 (the update form with name, URL, country, password fields, and listing checkboxes) is PHP-rendered and not template-controlled.

Token What it means
{site_name} The collective/site name from settings.
{field_email} Full email field block (label + input + hint).
{field_email_input} The <input> element only, for custom layouts.
{submit_button} The “Send verification link” submit button.
{clear_button} A reset button to clear the form.
Token Reference

Join Rules Gate Body Template Tokens

Used by the per-listing and global rules body text (rendered via RulesBodyRenderer, called from public/embed/rules-gate.php). The body auto-detects whether it's an HTML template (contains HTML tags or {gate_button}) or legacy plain text (numbered lines become an ordered list, other lines become paragraphs). Edit per-listing at Edit Listing → Rules, or the global default at Admin → Collective → Templates.

Token What it means
{subject} The fanlisting's subject/topic. Available in both the HTML-template and legacy plain-text paths.
{listing_title} The fanlisting's display title. Available in both paths.
{listing_type} The listing type value. Available in both paths.
{listing_url} The fanlisting's URL. Available in both paths.
{join_url} Link to the join form. Available in both paths.
{update_url} Link to the update form. Available in both paths.
{gate_button} Raw HTML. The agreement submit button. HTML-template path only. Presence of this token is what marks a body as using the gate-token system — if a custom body omits it, Luster appends gate controls after the rendered body automatically, so a fan can never get stuck with no way to proceed.
{gate_checkbox} Raw HTML. The agreement checkbox input. HTML-template path only. Non-empty only when the gate style is set to Checkbox; empty string under the Button gate style.
{if_gate_checkbox}...{/if_gate_checkbox} HTML-template path only. Resolved before all other tokens. Keeps its content only when the checkbox gate style is active.

Unlike KIM (which shows a visible in-page error when its add-on isn't installed), rules-gate.php fails open silently: if the Rules add-on is uninstalled or its table is unreachable, the embed falls back to any global rules, then to returning an empty string if there's nothing to show. Nothing is shown to the visitor either way — there's no error message.

CSS

Baseline Stylesheet

Luster includes a small starter stylesheet at public/assets/css/default/style.css. It makes embeds readable while still letting your site’s design stay in charge.

One-time setup

Every host page needs one PHP line above the embed require, added once per page (most sites put it in a shared header file):

<?php defined('LUSTER_EMBED') || define('LUSTER_EMBED', '/path/to/luster/public/embed'); require_once dirname(LUSTER_EMBED) . '/../vendor/autoload.php'; Luster\Core\View::serveEmbedAsset(); ?>

The Admin → Embed Codes wizard generates this line for you with your real install path already filled in — copy it from there rather than typing it by hand. It loads Composer's autoloader and registers a small handler, View::serveEmbedAsset(), that intercepts two special query-string requests on the current page: the stylesheet link below, and any uploaded listing/affiliate/code/wishlist image an embed prints. Both are served this way instead of as direct links so a public page never reveals your server's real install path in a URL a visitor can see.

Linking the stylesheet

With the setup line in place, load the stylesheet through the current page itself rather than a direct path:

<link rel="stylesheet" href="?luster_css">

Recommended load order

Load your site’s normal CSS first, then Luster’s CSS, then any extra CSS you write just for Luster embeds:

<!-- 1. Your site's normal stylesheet -->
<link rel="stylesheet" href="/style.css">

<!-- 2. Luster baseline -->
<link rel="stylesheet" href="?luster_css">

<!-- 3. Your Luster overrides (optional) -->
<link rel="stylesheet" href="/my-luster-overrides.css">
CSS

CSS Custom Properties

These are theme settings. Change them in your own stylesheet to adjust many Luster embed colors and borders at once.

Custom property What it customizes
--fl-font-family Default font family used by .fl-embed.
--fl-font-size Default font size used by .fl-embed.
--fl-color Default text color used by .fl-embed.
--fl-link-color Link color for embed links.
--fl-link-hover Hover color for embed links.
--fl-border-color Borders between rows and items.
--fl-radius Border radius for success boxes, buttons, badges, and similar elements.
--fl-gap General spacing between inline or flex items.
--fl-row-gap Spacing between vertical row and list items.
--fl-muted Muted secondary text color.
--fl-input-border Form input border color.
--fl-input-bg Form input background.
--fl-input-color Form input text color.
--fl-input-padding Form input padding.
--fl-input-radius Form input border radius.
--fl-status-current-bg Background color reserved for current status styling.
--fl-status-current-fg Text color for current status styling.
--fl-status-upcoming-bg Background color reserved for upcoming status styling.
--fl-status-upcoming-fg Text color for upcoming status styling.
--fl-status-pending-bg Background color reserved for pending status styling.
--fl-status-pending-fg Text color for pending status styling.
--fl-error-color Error text color.
--fl-success-bg Success-message background.
--fl-success-border Success-message border.
CSS

CSS Classes

Use .fl-embed--... classes when you want your CSS to affect one kind of embed without changing the rest.

Class What it scopes
.fl-embed Shared root wrapper for most embeds. Useful for broad embed styling.
.fl-embed--adopt Adoption application embed root.
.fl-embed--affiliate-apply Affiliate application embed root.
.fl-embed--affiliates Affiliates list embed root.
.fl-embed--codes Codes gallery embed root.
.fl-embed--codes-submit Code submission form embed root (per-listing and collective both use this).
.fl-embed--contact Listing or collective contact form root.
.fl-embed--join Join form root.
.fl-embed--joined Joined listings root.
.fl-embed--kim-list KIM overview or subject list root.
.fl-embed--kim-reset KIM password reset root.
.fl-embed--kim-signup KIM signup root.
.fl-embed--kim-update KIM update root.
.fl-embed--members Members list root.
.fl-embed--owned Owned listings root.
.fl-embed--reset Password reset root.
.fl-embed--rules-gate Join Rules gate root.
.fl-embed--update Update-member form root.
.fl-embed--newsfeed News feed root — per-listing and collective both use this exact class; there is no .fl-embed--collective-newsfeed.
.fl-embed--wishlist Wishlist embed root.
Class What it customizes
.fl-empty Empty-state text, such as "No members to display yet."
.fl-hint Help text and short explanatory lines.
.fl-powered-by Luster attribution line.
.fl-pagination-wrap Wrapper around generated pagination.
.fl-errors Error box or list area.
.fl-error Single error line, usually inside form field wrappers.
Class What it customizes
.fl-category-nav Category navigation wrapper.
.fl-category-list Category navigation as a list.
.fl-category-list-children Nested child category list.
.fl-category-count Number next to a category name.
.fl-category-dropdown Category navigation as a dropdown form.
.fl-category-back Back-to-categories link in browse-by-category mode.
.fl-cat-heading Heading for the current category or section.
.fl-joined-nav Shared dropdown form class used by both joined and owned category dropdowns.

Note: #fl-owned-cat and #fl-joined-cat are element IDs (not classes) used on the category select elements. Target them with #fl-owned-cat or #fl-joined-cat if you need to style the selects directly.

Class What it customizes
.fl-pagination-nav Main pagination wrapper.
.fl-page-prev Previous-page link.
.fl-page-next Next-page link.
.fl-page-link Normal clickable page number.
.fl-page-current Current page indicator.
.fl-page-gap Gap marker between distant page numbers.
Class What it customizes
.fl-form Main form element.
.fl-form-fields Optional wrapper around form fields, styled for vertical spacing.
.fl-field One field row or wrapper.
.fl-label Form label.
.fl-input Text-like input.
.fl-select Select dropdown.
.fl-textarea Textarea.
.fl-field-hint Hint/help text for one field.
.fl-field-error Error text for one field.
.fl-form-actions Button and action row.
.fl-submit Submit button.
.fl-btn General button class.
.fl-btn-secondary Secondary button or action style.
.fl-captcha-row Captcha row or wrapper.
.fl-captcha-question Captcha prompt text.
.fl-fieldset Fieldset emitted by the KIM update template. Rendered but not styled by the active baseline stylesheet.
.fl-field--danger Modifier on .fl-field for a "permanently delete" option (update, collective update).
.fl-label-danger Modifier on .fl-label for the label of a danger-zone checkbox.

Success messages use .fl-success, .fl-success-body, .fl-success-actions, and (for messages that show a bulleted rundown, like collective update) .fl-success-list.

Class What it customizes
.fl-member-controls Wrapper for member sort and filter controls.
.fl-member-sort Sort-link line.
.fl-member-sort-link Individual sort link or current sort label.
.fl-member-filter Optional member filter area.
.fl-member-back Back-to-country-summary link.
.fl-member-list Member list container.
.fl-member-item One member or country-summary row.
.fl-member-name Member name or country link.
.fl-member-country Member country or country count.
.fl-member-email Member email text if a custom template prints it.
.fl-member-field One custom additional field value.
.fl-member-field-label Label for a custom member field.
.fl-member-field-value Value for a custom member field. Rendered but not styled by the active baseline stylesheet.
Class What it customizes
.fl-stats Listing stats block.
.fl-stats-grid Stats grid wrapper.
.fl-stats-label Label part of a stats row.
.fl-stats-value Value part of a stats row.
.fl-stat-newmembers Newest-members row in custom stats templates.
.fl-stat-approved-by Approval-network stats row.
Class What it customizes
.fl-affiliate-list Affiliate list container.
.fl-affiliate-item One affiliate item.
.fl-affiliate-image Affiliate image.
.fl-affiliate-name Affiliate text/name.
.fl-affiliates-section Custom affiliate section wrapper.
.fl-affiliates-heading Custom affiliate section heading.
.fl-affiliates-empty Custom affiliate empty-state text.
.fl-affiliate-apply-toggle The trigger that shows/hides the application form — <a role="button"> for the link style, <button type="button"> for the button style.
.fl-affiliate-apply-toggle--link Modifier: toggle rendered as an <a> with no href, styled as an underlined text link.
.fl-affiliate-apply-toggle--button Modifier: toggle rendered as a <button type="button">, styled as a button.
.fl-affiliate-apply-form-wrap Wrapper around the application form. Hidden until the toggle is clicked.
.fl-codes-submit-toggle The trigger that shows/hides the code donation form — <a role="button"> for the link style, <button type="button"> for the button style.
.fl-codes-submit-toggle--link Modifier: toggle rendered as an <a> with no href, styled as an underlined text link.
.fl-codes-submit-toggle--button Modifier: toggle rendered as a <button type="button">, styled as a button.
.fl-codes-submit-form-wrap Wrapper around the code donation form. Hidden until the toggle is clicked.
Class What it customizes
.fl-listing-list Owned listing list container.
.fl-listing-item One owned listing row or card.
.fl-listing-item--current Modifier for current listing rows.
.fl-listing-item--upcoming Modifier for upcoming listing rows.
.fl-listing-item--pending Modifier for pending listing rows.
.fl-listing-image-wrap Wrapper around an owned listing image.
.fl-listing-image Owned listing image itself.
.fl-listing-body Text or body area for one listing.
.fl-listing-title Main linked title in owned listing templates.
.fl-listing-subject Subject or topic text.
.fl-listing-meta Metadata row or wrapper.
.fl-listing-category Category metadata.
.fl-listing-status Status metadata.
.fl-listing-date-opened Opened-date metadata.
.fl-listing-date-updated Last-updated metadata.
.fl-listing-member-count Member-count metadata.
.fl-listing-country-count Country-count metadata.
.fl-listing-section Wrapper for a sectioned owned-listings group.
.fl-listing-section-heading Heading for a sectioned owned-listings group.
.fl-listing-section-count Count inside a section heading.
Class What it customizes
.fl-joined-list Joined listing list container (flex-wrap — items flow inline).
.fl-joined-item One joined listing entry.
.fl-joined-image-wrap Wrapper around a joined listing image.
.fl-joined-image Joined listing image itself.
.fl-joined-body Text or body area for one joined listing.
.fl-joined-title Main linked joined listing title.
.fl-joined-category Joined listing category text.
.fl-joined-date Date joined text.
.fl-joined-status Joined listing status text.
.fl-joined-section Wrapper for a custom joined-listing section.
.fl-joined-section-heading Heading for a custom joined-listing section.
Class What it customizes
.fl-cstats Canonical collective stats block.
.fl-cstats-grid Canonical collective stats grid.
.fl-cstats-label Collective stats label.
.fl-cstats-value Collective stats value.
.fl-cstats-newest Newest-owned section in collective stats templates.
.fl-cstats-random Random/featured-owned section in collective stats templates.
.fl-cstats-categories Categories section in collective stats templates.
.fl-muted Muted inline text in the collective stats fallback. Rendered but not styled by the active baseline stylesheet.
Class What it customizes
.fl-codes Whole codes gallery wrapper.
.fl-code-group One size group.
.fl-code-group-label Size group heading.
.fl-code-list List or grid of code items.
.fl-code-item One code item.
.fl-code-image Figure or wrapper around one code image.
.fl-code-caption Caption under or beside a code.
Class What it customizes
.fl-newsfeed News feed wrapper.
.fl-newsfeed-item One entry.
.fl-newsfeed-header Header row for one entry.
.fl-newsfeed-title Entry title.
.fl-newsfeed-date Entry date.
.fl-newsfeed-body Entry body or content.
.fl-newsfeed-meta Entry metadata row.
.fl-newsfeed-categories Category-tag wrapper.
.fl-newsfeed-category-tag One update category tag.
.fl-newsfeed-img Force-added to any <img> inside a formatted entry body ({newsfeed_body_html}).
Class What it customizes
.fl-kim Shared inner wrapper for KIM embeds.
.fl-kim-heading KIM heading.
.fl-kim-intro KIM intro or explanatory text.
.fl-kim-list KIM fanlisting or subject list.
.fl-kim-item One KIM fanlisting or subject item.
.fl-kim-count Interested-member count.
.fl-kim-count--empty Empty count state, such as "none yet".
.fl-kim-meta KIM metadata or navigation text.
.fl-kim-subject Subject view wrapper if used in a custom template.
.fl-kim-subject-heading Subject view heading.
.fl-kim-member-list Interested-member list for one subject.
.fl-kim-member-item One interested-member row.
.fl-kim-member-name Interested-member name or link.
Class What it customizes
.fl-embed--rules-gate Outer root wrapper for the rules gate embed.
.fl-rules-gate Inner wrapper shown when the fan has not yet agreed.
.fl-rules-form The agreement <form> element (also carries the generic .fl-form class).
.fl-rules-list The <ol> wrapping numbered rules in the built-in default body. Only present if your rules body kept this class.
.fl-rules-gate-checkbox Paragraph wrapping the agreement checkbox and its label text, in the built-in default body.
.fl-rules-agree-check The agreement checkbox input itself (checkbox gate style only).
.fl-rules-gate-btn The submit button (also carries the generic .fl-submit class).
.fl-form-actions Wrapper div around the submit button, in the built-in default body.
.fl-rules-agreed Wrapper shown when the fan has already agreed this session.
Class What it customizes
.fl-wishlist-group Wrapper for a wishlist type group.
.fl-wishlist-group--top Group modifier for top-wanted entries.
.fl-wishlist-group--wanted Group modifier for wanted entries.
.fl-wishlist-group--granted Group modifier for granted entries.
.fl-wishlist-group-label Heading or label for a wishlist group.
.fl-wishlist-list Wishlist list container.
.fl-wishlist-item One wishlist item.
.fl-wishlist-item--top Item modifier for top-wanted entries.
.fl-wishlist-item--wanted Item modifier for wanted entries.
.fl-wishlist-item--granted Item modifier for granted entries.
.fl-wishlist-image Wishlist image.
.fl-wishlist-info Text or body area for one wishlist item.
.fl-wishlist-subject Wishlist subject link or text.
.fl-wishlist-category Wishlist category text.
.fl-wishlist-description Wishlist description text.
.fl-wishlist-type-badge Type badge or label.
Class What it customizes
.fl-collective-update-form Root <form> on the Step 2 update form.
.fl-collective-update-table-wrap Scrolling wrapper div around the listing-selection table.
.fl-collective-update-table The <table> of listings the member can select and apply changes to (columns: checkbox, Listing, Subject, Website URL, Date Joined).
.fl-collective-update-changes The <fieldset> containing the "Changes to apply to selected fanlistings" fields (name, email, URL, country, password).

The "permanently delete my membership(s)" option uses the general .fl-field--danger / .fl-label-danger classes, not a collective-update-specific class.

CSS

Common Styling Recipes

These are small copy-paste examples for common styling changes.

Style one embed type

.fl-embed--members .fl-member-list {
  margin-top: 1rem;
}

Style every embed form

.fl-embed .fl-form {
  display: grid;
  gap: 0.75rem;
}

Change the whole Luster embed color system

:root {
  --fl-link-color: #8a3ffc;
  --fl-link-hover: #5f249f;
  --fl-border-color: #d8c7ff;
}

Style joined listing images

.fl-embed--joined .fl-joined-image {
  width: 88px;
  height: 31px;
  object-fit: cover;
}

Style owned listing images

.fl-embed--owned .fl-listing-image {
  max-width: 120px;
  height: auto;
}