16.7 KB
templates.html
{{template "docs.html" .}}
{{define "title"}}Templates{{end}}
{{define "content"}}
<article class="space-y-12">
<header>
<div class="w-12 h-1 rounded-full bg-gradient-to-r from-violet-500 to-cyan-500 mb-6"></div>
<h1 class="text-3xl font-bold text-white mb-3">Templates</h1>
<p class="text-[#888] text-lg">Template function reference for dynamic page content.</p>
</header>
<section class="space-y-6">
<div>
<h2 class="text-xl font-semibold text-white">Overview</h2>
<p class="text-[#888] mt-2">Page content is rendered as a Go template. This means you can use <code class="text-violet-400 bg-violet-400/10 px-1.5 py-0.5 rounded">{{"{{...}}"}}</code> syntax to insert dynamic data from your collections, pages, and site settings.</p>
</div>
<div class="grid sm:grid-cols-3 gap-4">
<div class="border border-white/10 rounded-lg p-5">
<div class="text-violet-400 font-medium mb-2">Functions</div>
<p class="text-sm text-[#888]">Query collections, fetch pages, and access site settings with built-in template functions.</p>
</div>
<div class="border border-white/10 rounded-lg p-5">
<div class="text-cyan-400 font-medium mb-2">Document Methods</div>
<p class="text-sm text-[#888]">Access typed field values from collection records using GetString, GetInt, and more.</p>
</div>
<div class="border border-white/10 rounded-lg p-5">
<div class="text-emerald-400 font-medium mb-2">Page Methods</div>
<p class="text-sm text-[#888]">Navigate page hierarchy with Path, Parent, Children, and Siblings methods.</p>
</div>
</div>
</section>
<!-- Tip callout -->
<div class="flex gap-3 p-4 rounded-lg border border-emerald-400/20 bg-emerald-400/[0.03]">
<svg class="w-5 h-5 text-emerald-400 flex-shrink-0 mt-0.5" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9.663 17h4.673M12 3v1m6.364 1.636l-.707.707M21 12h-1M4 12H3m3.343-5.657l-.707-.707m2.828 9.9a5 5 0 117.072 0l-.548.547A3.374 3.374 0 0014 18.469V19a2 2 0 11-4 0v-.531c0-.895-.356-1.754-.988-2.386l-.548-.547z"/></svg>
<div>
<span class="text-emerald-400 font-medium text-sm">Tip</span>
<p class="text-sm text-[#888] mt-1">The AI assistant validates templates before saving. If your template has a syntax error, it will catch it and suggest a fix.</p>
</div>
</div>
<!-- Available Functions -->
<section class="space-y-6">
<div class="border-t border-white/10 pt-8">
<h2 class="text-xl font-semibold text-white">Available functions</h2>
<p class="text-[#888] mt-2">Functions available in every page template, organized by what they access.</p>
</div>
<!-- Collection functions -->
<div class="space-y-3">
<h3 class="text-sm font-medium text-cyan-400 uppercase tracking-wider">Collection & Document Functions</h3>
<div class="grid sm:grid-cols-2 gap-3">
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-cyan-400">documents "name"</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">[]Document</span> — All documents in a collection</p>
</div>
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-cyan-400">document "collection" "id"</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">Document</span> — Single document by collection and ID</p>
</div>
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-cyan-400">collection "name"</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">Collection</span> — Collection metadata (name, fields)</p>
</div>
</div>
</div>
<!-- Page functions -->
<div class="space-y-3">
<h3 class="text-sm font-medium text-emerald-400 uppercase tracking-wider">Page Functions</h3>
<div class="grid sm:grid-cols-2 gap-3">
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-emerald-400">page "id"</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">Page</span> — Single page by ID</p>
</div>
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-emerald-400">pages</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">[]Page</span> — All pages</p>
</div>
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-emerald-400">partial "name"</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">string</span> — Rendered partial template by name</p>
</div>
</div>
</div>
<!-- Partial functions -->
<div class="space-y-3">
<h3 class="text-sm font-medium text-violet-400 uppercase tracking-wider">Partial Functions</h3>
<div class="grid sm:grid-cols-2 gap-3">
<div class="border border-white/10 rounded-lg p-4">
<code class="text-sm text-violet-400">partials</code>
<p class="text-xs text-[#888] mt-1">Returns <span class="text-[#ccc]">[]string</span> — All available partial template names</p>
</div>
</div>
</div>
</section>
<!-- Document Methods -->
<section class="space-y-6">
<div class="border-t border-white/10 pt-8">
<h2 class="text-xl font-semibold text-white">Document methods</h2>
<p class="text-[#888] mt-2">Documents returned by <code class="text-violet-400 bg-violet-400/10 px-1.5 py-0.5 rounded">documents</code> and <code class="text-violet-400 bg-violet-400/10 px-1.5 py-0.5 rounded">document</code> have typed accessor methods:</p>
</div>
<div class="border-l-2 border-cyan-400/30 pl-6">
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-white/10">
<th class="text-left text-[#888] py-3 pr-4">Method</th>
<th class="text-left text-[#888] py-3 pr-4">Returns</th>
<th class="text-left text-[#888] py-3">Use for</th>
</tr>
</thead>
<tbody class="text-[#ccc]">
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-cyan-400">GetString "field"</code></td>
<td class="py-3 pr-4">string</td>
<td class="py-3">Text, email, URL, select fields</td>
</tr>
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-cyan-400">GetInt "field"</code></td>
<td class="py-3 pr-4">int</td>
<td class="py-3">Number fields</td>
</tr>
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-cyan-400">GetBool "field"</code></td>
<td class="py-3 pr-4">bool</td>
<td class="py-3">Boolean fields</td>
</tr>
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-cyan-400">GetTime "field"</code></td>
<td class="py-3 pr-4">time.Time</td>
<td class="py-3">Date fields</td>
</tr>
<tr>
<td class="py-3 pr-4"><code class="text-cyan-400">GetStrings "field"</code></td>
<td class="py-3 pr-4">[]string</td>
<td class="py-3">JSON array fields (tags, categories)</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<!-- Page Methods -->
<section class="space-y-6">
<div class="border-t border-white/10 pt-8">
<h2 class="text-xl font-semibold text-white">Page methods</h2>
<p class="text-[#888] mt-2">Pages returned by <code class="text-violet-400 bg-violet-400/10 px-1.5 py-0.5 rounded">pages</code> and <code class="text-violet-400 bg-violet-400/10 px-1.5 py-0.5 rounded">page</code> have navigation methods:</p>
</div>
<div class="border-l-2 border-emerald-400/30 pl-6">
<div class="overflow-x-auto">
<table class="w-full text-sm">
<thead>
<tr class="border-b border-white/10">
<th class="text-left text-[#888] py-3 pr-4">Method</th>
<th class="text-left text-[#888] py-3 pr-4">Returns</th>
<th class="text-left text-[#888] py-3">Description</th>
</tr>
</thead>
<tbody class="text-[#ccc]">
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-emerald-400">Path()</code></td>
<td class="py-3 pr-4">string</td>
<td class="py-3">Full URL path (e.g. <code class="text-[#888]">/about/team</code>)</td>
</tr>
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-emerald-400">Parent()</code></td>
<td class="py-3 pr-4">Page</td>
<td class="py-3">Parent page (nil if top-level)</td>
</tr>
<tr class="border-b border-white/5">
<td class="py-3 pr-4"><code class="text-emerald-400">Children()</code></td>
<td class="py-3 pr-4">[]Page</td>
<td class="py-3">Direct child pages</td>
</tr>
<tr>
<td class="py-3 pr-4"><code class="text-emerald-400">Siblings()</code></td>
<td class="py-3 pr-4">[]Page</td>
<td class="py-3">Pages at the same level</td>
</tr>
</tbody>
</table>
</div>
</div>
</section>
<section class="space-y-6">
<div class="border-t border-white/10 pt-8">
<h2 class="text-xl font-semibold text-white">Examples</h2>
</div>
<div class="space-y-4">
<div class="border border-white/10 rounded-lg p-4">
<div class="text-sm text-white font-medium mb-2">Navigation from pages</div>
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]"><nav>
{{"{{range $p := pages}}"}}
<a href="{{"{{$p.Path}}"}}">{{"{{$p.Title}}"}}</a>
{{"{{end}}"}}
</nav></code></pre>
</div>
<div class="border border-white/10 rounded-lg p-4">
<div class="text-sm text-white font-medium mb-2">Blog listing with dates</div>
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]">{{"{{range $post := documents \"blog-posts\"}}"}}
<article>
<h2>{{"{{$post.GetString \"title\"}}"}}</h2>
<p>{{"{{$post.GetString \"content\"}}"}}</p>
{{"{{with $date := $post.GetTime \"publishedAt\"}}"}}
<time>{{"{{$date.Format \"Jan 2, 2006\"}}"}}</time>
{{"{{end}}"}}
</article>
{{"{{else}}"}}
<p>No posts yet.</p>
{{"{{end}}"}}</code></pre>
</div>
<div class="border border-white/10 rounded-lg p-4">
<div class="text-sm text-white font-medium mb-2">Conditional content</div>
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]">{{"{{range $product := documents \"products\"}}"}}
{{"{{if $product.GetBool \"featured\"}}"}}
<div class="featured">
<h3>{{"{{$product.GetString \"name\"}}"}}</h3>
<span>${{"{{$product.GetInt \"price\"}}"}}</span>
</div>
{{"{{end}}"}}
{{"{{end}}"}}</code></pre>
</div>
<div class="border border-white/10 rounded-lg p-4">
<div class="text-sm text-white font-medium mb-2">Include a partial template</div>
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]"><header>
{{"{{partial \"header\"}}"}}
</header>
<footer>
{{"{{partial \"footer\"}}"}}
</footer></code></pre>
</div>
<div class="border border-white/10 rounded-lg p-4">
<div class="text-sm text-white font-medium mb-2">Child page navigation</div>
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]">{{"{{with $about := page \"about-page-id\"}}"}}
<h2>{{"{{$about.Title}}"}}</h2>
<ul>
{{"{{range $child := $about.Children}}"}}
<li><a href="{{"{{$child.Path}}"}}">{{"{{$child.Title}}"}}</a></li>
{{"{{end}}"}}
</ul>
{{"{{end}}"}}</code></pre>
</div>
</div>
</section>
<section class="space-y-6">
<h2 class="text-xl font-semibold text-white">Full blog example</h2>
<p class="text-[#888]">A complete blog page using collections and template functions:</p>
<div class="border border-white/10 rounded-lg p-4">
<pre class="bg-[#1a1a1a] border border-white/10 rounded-lg p-4 text-sm overflow-x-auto"><code class="text-[#e5e5e5]"><div class="max-w-2xl mx-auto">
<h1 class="text-4xl font-bold mb-8">Blog</h1>
{{"{{range $post := documents \"blog-posts\"}}"}}
{{"{{if $post.GetBool \"published\"}}"}}
<article class="mb-12 pb-12 border-b">
<h2 class="text-2xl font-bold">
{{"{{$post.GetString \"title\"}}"}}
</h2>
<div class="text-gray-500 text-sm mt-2">
By {{"{{$post.GetString \"author\"}}"}}
{{"{{with $date := $post.GetTime \"publishedAt\"}}"}}
&middot; {{"{{$date.Format \"January 2, 2006\"}}"}}
{{"{{end}}"}}
</div>
<div class="mt-4 prose">
{{"{{$post.GetString \"content\"}}"}}
</div>
</article>
{{"{{end}}"}}
{{"{{else}}"}}
<p class="text-gray-500">No posts yet. Check back soon!</p>
{{"{{end}}"}}
</div></code></pre>
</div>
</section>
<!-- What's Next -->
<section class="border-t border-white/10 pt-12 space-y-4">
<h2 class="text-xl font-semibold text-white">What's next?</h2>
<div class="grid sm:grid-cols-2 gap-4">
<a href="/docs/pages" class="border border-white/10 rounded-lg p-5 hover:border-white/20 hover:bg-white/[0.02] transition-all">
<div class="text-violet-400 font-medium mb-1">Pages</div>
<p class="text-sm text-[#888]">Create pages, organize with hierarchy, and publish content.</p>
</a>
<a href="/docs/collections" class="border border-white/10 rounded-lg p-5 hover:border-white/20 hover:bg-white/[0.02] transition-all">
<div class="text-cyan-400 font-medium mb-1">Collections</div>
<p class="text-sm text-[#888]">Store and query structured content like blog posts or products.</p>
</a>
<a href="/docs/endpoints" class="border border-white/10 rounded-lg p-5 hover:border-white/20 hover:bg-white/[0.02] transition-all">
<div class="text-pink-400 font-medium mb-1">Endpoints</div>
<p class="text-sm text-[#888]">Write custom API logic with serverless Lua scripts.</p>
</a>
</div>
</section>
</article>
{{end}}