Astral Realms Documentation Help

Placeholders

AstralPlayerShops registers one global namespace and four contextual namespaces with AstralCore. For the placeholder syntax itself (%a_b_c%, %a_{b_c}%, $e(...)) see Placeholders.

A note on menu/dialog prefixes

The tables below document each model's own sub-keys — its ComplexPlaceholder.get switch. The full placeholder string to type in a config, though, depends on how that object reached the render, per AstralCore's resolution order:

  • Sign templates. ShopService#updateSignBlock builds a one-off PlaceholderContainer and calls .registerPlaceholder(shop) directly — the shop sits at the top-level shop namespace, so %shop_price% is written as-is.

  • A single object passed into a menu/dialog open call (Map.of("shop", shop, "stats", stats, ...)) is reached through AstralCore's parameters namespace (pluralMenu/ComputedDialog both register a ParametersPlaceholder keyed "parameters"): %parameters_shop_price%, %parameters_stats_dailyEarnings%.

  • One object per row of a layout/list built from an ItemProvider (e.g. the transactions or entries list) is reached through the parameter namespace (singularLayoutInstance/ComputedDialog wrap each row in a ParameterPlaceholder alongside %parameter_index%/%parameter_slot%): %parameter_transaction_id%, %parameter_entry_item%.

Each section's Availability line below states which form applies.

playershops_* (global)

Registered on RootPlaceholderContainer (PSPlaceholders, AstralPlayerShops#onEnable), so it resolves anywhere a placeholder container is evaluated across the network — no menu parameter needed.

Placeholder

Type

Description

%playershops_recapNotification%

Boolean

The context player's away-recap notification preference (PSPlayerData#recapEnabled, synced via AstralSync). Requires a Player context — resolves to null if the evaluation context isn't a player at all, and to false if the player has no synced PSPlayerData yet. Toggled by toggle-playershops-recap.

Availability. Root namespace — %playershops_recapNotification%, unprefixed, anywhere a Player is the evaluation context (messages, menus, dialogs). See Activity Recaps.

shop_* (contextual)

PlayerShop is itself a ComplexPlaceholder (namespace shop). A bare %shop% (no sub-key) resolves to the PlayerShop instance itself.

Placeholder

Type

Description

%shop_id%

UUID

Primary key.

%shop_owner%

MinecraftPlayerPlaceholder

Network-aware handle on the owner, keyed by ownerId — chain _uuid, _name, _online, _head (a player-head ItemStack), _loaded. Works for offline owners.

%shop_ownerName%

String

Owner's player name, captured at shop creation — not live-updated on a later name change.

%shop_price%

int

Price per single item.

%shop_material%

String

Base Material name captured at creation (itemStack.getType().name()) — reflects only the raw block/item type, never a custom item's identity. Use %shop_item% for the full item.

%shop_type%

ShopType

BUY or SELL (raw enum).

%shop_typeFormatted%

Component

The BUY_TYPE/SELL_TYPE message for the shop's ShopType.

%shop_item%

ItemStackPlaceholder

The full traded item, deserialized from stored bytes. Chains into the standard item sub-keys — material, name, hover-name, lore, amount, custom-model-data, durability, enchantments (see Equipment sub-keys).

%shop_location%

LocationPlaceholder

The shop's container location — chain _x, _y, _z, _world_* (see Location and world sub-keys).

%shop_townShared%

Boolean

Whether any town member with USE_PLAYER_SHOPS may trade at the shop, not just the owner.

%shop_townEconomy%

Boolean

Whether the shop's proceeds route through a town's economy account rather than the owner's personal balance — true when economyAccount is non-null.

Availability. Registered directly (%shop_*%) on the shop's wall sign — see Sign lines and The sign. Passed as a menu-open parameter (%parameters_shop_*%) into playershops-main (MenuService#openShopMenu), playershops-history (MenuService#openTransactionHistoryMenu), and the playershops-buy/playershops-sell amount-picker menus opened by ShopService#buy/#sell — see Interacting with a shop.

entry_* (contextual)

ShopRecap is a ComplexPlaceholder (namespace entry) — a record representing one item's aggregated activity within a recap window. A bare %entry% resolves to the record itself.

Placeholder

Type

Description

%entry_id%

UUID

The originating shop's id. Always null in the shipped recap flow — TransactionService#fetchRecapsByPlayer re-groups the per-shop/per-type SQL rows by ItemStack across all of the owner's shops before building the dialog list, discarding the per-shop id in the process.

%entry_item%

ItemStackPlaceholder

The traded item — the key the rows were grouped by.

%entry_type%

ShopType

BUY or SELL for this group. If the owner runs both a BUY and a SELL shop trading the same item within the window, the rows still merge into one entry — this reflects whichever raw row happened to sort first, not necessarily both types.

%entry_typeFormatted%

Component

The BUY_TYPE/SELL_TYPE message for the entry's %entry_type%.

%entry_count%

int

Total quantity traded for this item across the window (summed across all matching shops).

%entry_earnings%

double

Total coin value for this item across the window (summed across all matching shops).

Availability. Rendered per-row (%parameter_entry_*%) inside the entries layout of the playershops-daily-recap (/ps recap) and playershops-absent-recap (login prompt) dialogs. See Activity Recaps → Recap computation for the full grouping behavior and the earned/spent totals computed alongside the entry list.

transaction_* (contextual)

ShopTransaction is a ComplexPlaceholder (namespace transaction) — one persisted row per completed trade. A bare %transaction% resolves to the record itself. Rows sort newest-first (ShopTransaction implements Comparable, by createdAt descending).

Placeholder

Type

Description

%transaction_id%

UUID

Primary key.

%transaction_buyer%

MinecraftPlayerPlaceholder

Network-aware handle on the buyer, keyed by buyerId — chain _uuid, _name, _online, _head, _loaded (same as %shop_owner%).

%transaction_amount%

int

Quantity traded.

%transaction_price%

double

Total coin value of the transaction (already unit price × quantity).

%transaction_date%

TimePlaceholder

When the transaction was recorded. Chain _remaining (ms until, as a raw long), _remaining-format (human-readable), _format (HH:mm:ss dd/MM/yyyy), _format-duration, _format-date (dd/MM/yyyy); a bare %transaction_date% resolves to the raw LocalDateTime.

Availability. Rendered per-row (%parameter_transaction_*%) inside the transactions layout of the playershops-history menu (opened via open-playershops-transactions). Rows are cached per shop for 5 minutes, and rows older than a week are purged every 12 hours (TransactionRepository).

stats_* (contextual)

ShopStats is a ComplexPlaceholder (namespace stats) — a record of rolling 24h/7d aggregates for one shop, computed with a single SUM/COUNT query over that shop's transactions rows (COALESCE(..., 0) when there are no matching rows) and cached per shop for 5 minutes. A bare %stats% resolves to the record itself.

Placeholder

Type

Description

%stats_dailyEarnings%

double

Sum of total_price over transactions from the last 24 hours.

%stats_weeklyEarnings%

double

Sum of total_price over transactions from the last 7 days.

%stats_dailyTransactions%

int

Count of transactions from the last 24 hours.

%stats_weeklyTransactions%

int

Count of transactions from the last 7 days.

%stats_dailyAmount%

int

Sum of quantity (items traded, not transaction count) over the last 24 hours.

%stats_weeklyAmount%

int

Sum of quantity over the last 7 days.

Availability. Passed as a menu-open parameter (%parameters_stats_*%) into playershops-main alongside %parameters_shop_*%MenuService#openShopMenu loads both together via TransactionService#findStatsByShopId before opening.

stock (sign-only)

%stock% is a direct placeholder, not a namespaced/complex one — it's computed live and registered only while rendering a shop's wall sign (ShopService#updateSignBlock), alongside the shop's own shop_* fields in the same one-off container:

PlaceholderContainer placeholderContainer = new PlaceholderContainer() .registerPlaceholder(shop) .registerDirect("stock", stockComponent);

Shop type

Value

BUY

Items currently available in the container to buy, live-counted with ContainerUtils#countItems; the OUT_OF_STOCK message when the count is 0.

SELL

Empty slots left in the container to sell into, via ContainerUtils#countEmptySlots; the FULL message when the count is 0.

The sign refreshes on shop creation, after every buy/sell, and on the periodic sign-refresh tick (see Sign & stock refresh). The shipped config.yml uses it as:

sign: - "Seller: %shop_ownerName%" - "Stock: %stock%" - "Price: $%shop_price%" - "%shop_typeFormatted%"

Availability. Root namespace, sign templates only (%stock%, unprefixed) — not reachable from any menu, dialog, or message.

Context summary

Namespace

Written as

Where

playershops_*

%playershops_*%

Anywhere with a Player evaluation context.

shop_*

%shop_*%

The shop's wall sign.

shop_*

%parameters_shop_*%

playershops-main, playershops-history, playershops-buy, playershops-sell menus.

stats_*

%parameters_stats_*%

playershops-main menu.

transaction_*

%parameter_transaction_*%

transactions layout inside playershops-history.

entry_*

%parameter_entry_*%

entries layout inside playershops-daily-recap/playershops-absent-recap.

%stock%

%stock%

The wall sign renderer only (formatted, stock-or-message form).

Last modified: 25 July 2026