readysite / readysite.org / views / docs / templates.html
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 &amp; 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> &mdash; 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> &mdash; 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> &mdash; 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> &mdash; 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> &mdash; 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> &mdash; 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> &mdash; 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]">&lt;nav&gt;
  {{"{{range $p := pages}}"}}
    &lt;a href="{{"{{$p.Path}}"}}"&gt;{{"{{$p.Title}}"}}&lt;/a&gt;
  {{"{{end}}"}}
&lt;/nav&gt;</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\"}}"}}
  &lt;article&gt;
    &lt;h2&gt;{{"{{$post.GetString \"title\"}}"}}&lt;/h2&gt;
    &lt;p&gt;{{"{{$post.GetString \"content\"}}"}}&lt;/p&gt;
    {{"{{with $date := $post.GetTime \"publishedAt\"}}"}}
      &lt;time&gt;{{"{{$date.Format \"Jan 2, 2006\"}}"}}&lt;/time&gt;
    {{"{{end}}"}}
  &lt;/article&gt;
{{"{{else}}"}}
  &lt;p&gt;No posts yet.&lt;/p&gt;
{{"{{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\"}}"}}
    &lt;div class="featured"&gt;
      &lt;h3&gt;{{"{{$product.GetString \"name\"}}"}}&lt;/h3&gt;
      &lt;span&gt;${{"{{$product.GetInt \"price\"}}"}}&lt;/span&gt;
    &lt;/div&gt;
  {{"{{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]">&lt;header&gt;
  {{"{{partial \"header\"}}"}}
&lt;/header&gt;
&lt;footer&gt;
  {{"{{partial \"footer\"}}"}}
&lt;/footer&gt;</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\"}}"}}
  &lt;h2&gt;{{"{{$about.Title}}"}}&lt;/h2&gt;
  &lt;ul&gt;
    {{"{{range $child := $about.Children}}"}}
      &lt;li&gt;&lt;a href="{{"{{$child.Path}}"}}"&gt;{{"{{$child.Title}}"}}&lt;/a&gt;&lt;/li&gt;
    {{"{{end}}"}}
  &lt;/ul&gt;
{{"{{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]">&lt;div class="max-w-2xl mx-auto"&gt;
  &lt;h1 class="text-4xl font-bold mb-8"&gt;Blog&lt;/h1&gt;

  {{"{{range $post := documents \"blog-posts\"}}"}}
    {{"{{if $post.GetBool \"published\"}}"}}
      &lt;article class="mb-12 pb-12 border-b"&gt;
        &lt;h2 class="text-2xl font-bold"&gt;
          {{"{{$post.GetString \"title\"}}"}}
        &lt;/h2&gt;
        &lt;div class="text-gray-500 text-sm mt-2"&gt;
          By {{"{{$post.GetString \"author\"}}"}}
          {{"{{with $date := $post.GetTime \"publishedAt\"}}"}}
            &amp;middot; {{"{{$date.Format \"January 2, 2006\"}}"}}
          {{"{{end}}"}}
        &lt;/div&gt;
        &lt;div class="mt-4 prose"&gt;
          {{"{{$post.GetString \"content\"}}"}}
        &lt;/div&gt;
      &lt;/article&gt;
    {{"{{end}}"}}
  {{"{{else}}"}}
    &lt;p class="text-gray-500"&gt;No posts yet. Check back soon!&lt;/p&gt;
  {{"{{end}}"}}
&lt;/div&gt;</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}}
← Back