Common Recipes & Patterns
Ready-to-use snippets: price formatting, excerpt, date, image presets, fallback, QueryLoop card, and an AI Generate tip.
Ready-to-use patterns for common cases. Copy-paste and swap tags to fit your context.
1. Product Price
Regular price
{product_price_raw|currency}
Use in any heading / basicText / button text field. CTA example:
Buy Now — {product_price_raw|currency}
Discount with strikethrough original price
{product_original_price_raw|currency} {product_sale_price_raw|currency}
For the visual strikethrough effect, either use a richText element with inline formatting, or two basicText elements (one styled strikethrough via the Style tab).
2. Excerpt / Text Preview
Truncate product description with ellipsis:
{product_description|strip_html|truncate:120}
Post content preview:
{post_content|strip_html|truncate:200}
3. Images with Presets
Pick a preset that fits the context (see Tags & Filters Reference for the full list):
{product_image|image_url:cardMedium}
{post_featured_image|image_url:cardWide}
{site_logo|image_url:logo}
{page_featured_image|image_url:hero}
4. Dates
Long format:
{post_date|date:long}
→ "May 5, 2026"
Footer copyright:
© {site_year} {site_name}
→ "© 2026 Acme Store"
Sale countdown (use in basicText):
Sale ends: {product_sale_ends_at|date:long}
5. Fallbacks
Missing author:
{post_author|default:"Anonymous"}
Default tagline:
{site_tagline|default:"Endless Possibilities"}
6. Query Loop Pattern
A Query Loop is an element with queryLoop.enabled = true rendered N times — once per query result. Inside the loop, entity tags resolve against the current row: a postQuery loop sees {post_*}, a product loop sees {product_*}, a course loop sees {course_*}.
Blog-post card template (Query Loop iterating posts):
<!-- container[queryLoop=postQuery] containing: -->
<article>
<img src="{post_featured_image|image_url:cardMedium}" alt="{post_title}">
<h3>{post_title}</h3>
<p>{post_excerpt|default:"—"}</p>
<a href="{post_url}">Read more</a>
</article>
Numbered item (uses {{loop.*}} metadata which stays double-brace):
{{loop.number}}. {post_title}
{{loop.first}} / {{loop.last}} are useful in Display Conditions on child elements — e.g. show a "NEW" badge only on the first item using {{loop.first}} == "true".
7. Best Practices & Gotchas
- Prefer
_raw+ filter over pre-formatted tags.{product_price_raw|currency}is better than{product_price}(deprecated). Reason: currency formatting follows site Settings, so it stays consistent with cart/checkout. - The picker auto-appends the suggested filter when you click a tag. Don't remove it unless you have a reason — it's the recommended pairing.
- Inside a Query Loop, use entity tags for row data (
{product_title},{post_title},{course_title}, ...); only{{loop.*}}metadata uses the double-brace syntax. - Tag not resolving? Check the template context.
{product_title}in a custom page renders empty because page isn't a product context. {{loop.*}}outside a Query Loop won't resolve — it stays as literal{{loop.number}}text.- WhatsApp button (
whatsappMessagefield) is also tag-resolved. Send a personalized message:Hi, I'm interested in {product_title} ({product_url}). - The
defaultfilter is ambiguous for number/boolean — fallback is always a string. For boolean branching, prefer Display Conditions.
8. AI Generate Tip
When you use the ✨ AI Generate button in the builder, explicitly ask for dynamic tags so the output stays reusable:
Build a single_product template. MUST use dynamic tags for all product
data (title, price, image, description) so the template works for every
product instead of hardcoding one specific product.
The AI already has access to the MCP tools get_dynamic_tags, list_dynamic_filters, and get_data_contexts — so it knows which tags are valid for the requested template type.