Single source of truth for Birkly CMS documentation

Quick reference for Birkly’s public template language, plus phantoms to avoid. Aligns with TEMPLATE_LANGUAGE_SPEC v1.0.

In short: Single braces. Quote collections and user fields. Loop with with / ordered by / optional limit N. Dates use format. Detail pages use URL context. Forms use {entry for}. Print this page when building sites or reviewing AI output.

Printable Birkly template syntax sheet with phantoms to avoid

Beginner

Output

{title}
{slug}
{'excerpt'}
{'content'}
{created_at}
{created_at format "F j, Y"}
{current.language}
{current_year}
{query.'slug'}

Loops

{for each entry in 'blog'}
{for each entry in 'blog' with status = published}
{for each entry in 'blog' with status = published ordered by newest}
{for each entry in 'blog' with status = published ordered by newest limit 5}
{for each entry in 'nav' ordered by order}
{for newest entry in 'blog'}
{for each entry in 'comments' of 'blog'.current ordered by newest}
{for each item in 'tags'}
{endfor}

From…get / existence / conditionals

{from 'site_elements' get entry 'header'} … {endget}
{from 'site_elements'.'header' get 'content'}
{if 'site_elements'.'hero' exist} … {endif}
{if entry has 'excerpt'} … {else} … {endif}
{if entry has 'price' <= 15 or entry has 'discount'} … {endif}
{if current.language = 'de'} … {endif}

Regions / client

<script src="/birkly-client.js" data-cms-url="https://cms.example.com"></script>
<birkly-region collection="site_elements" entry="header"></birkly-region>
<birkly-region collection="blog" list ordered="newest">…</birkly-region>
<select data-birkly-language-select>…</select>

Forms

{entry for 'contact'}
  <input name="{email}" required>
{endentry}
{public_form 'contact'}

Detail URL

post.html?collection=blog&slug={slug}

On detail: {title} / {'content'} — no {for each entry in 'blog'}.

Core shelf (fieldtypes)

{media_url('hero')}
{media_img('hero', 'Alt text')}
{gallery_html('photos')}
{oembed_html('video')}
{relation_titles('related')}
{relation_links('related')}
{dynamicitems_html('blocks')}
{for each id in 'gallery'}{media_img(id)}{endfor}
{for each tag in 'tags'}{tag}{endfor}
Advanced Users

Ordering phrases

PhraseField
newest / oldestcreated_at
last-updatedupdated_at
orderorder or sort_order

Phantoms (reject in review)

PhantomUse instead
{{ }} / {% for %}{…} / {for each}
{entry 'blog'.'slug'}…{endentry}{from 'blog' get entry 'slug'}…{endget}
{ date "F j, Y" }{created_at format "F j, Y"}
{title truncate 80}excerpt field
{'content' strip_tags}plain field / CMS cleanup
{from 'blog' get entries …} / sort= / limit=ordered by + limit N
{ media … }{media_img('featured_image', '…')} or {media_url('featured_image')}
ordered="date:desc"ordered="newest"
Detail page collection loopURL context + .current
Manual /plugins/…/storefront.js tagsSingle birkly-client.js — Project sites and plugins
Custom club-gate.js auth scriptdata-user-require-auth on <html> / <body>

Learning map

TaskDoc
Mental modelTemplating overview
Script tag + pluginsClient setup, Project sites and plugins
List/detailLoops, Detail pages
Media / shelfCore template shelf, Media in templates
FormsPublic forms templating
Full tutorialWorked site walkthrough
Spec (CMS)docs/TEMPLATE_LANGUAGE_SPEC.md