원클릭으로
kida-template-authoring
Write correct Kida templates from scratch. Use when creating templates, writing views, or authoring template content.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Write correct Kida templates from scratch. Use when creating templates, writing views, or authoring template content.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Convert Jinja2 templates to Kida syntax. Use when migrating from Jinja2, Django templates, or similar engines.
Use Kida with Chirp for HTMX partials, fragment rendering, block validation. Use when building Chirp web apps.
Use Kida with Bengal SSG: block caching, incremental builds, template context. Use when building Bengal sites or optimizing build performance.
Add custom Kida filters with proper type coercion. Use when adding filters, extending templates, or handling YAML/config int/str.
Understand Kida expression behavior: `+` operator, list vs string, export accumulation. Use when debugging unexpected output or expression behavior.
Use Kida static analysis for pre-render validation, incremental builds, block caching. Use when validating template context, optimizing build times, or implementing caching.
| name | kida-template-authoring |
| description | Write correct Kida templates from scratch. Use when creating templates, writing views, or authoring template content. |
{{ name }}
{{ user.email }}
{{ items[0] }}
{{ user.nickname | default("Anonymous") }}
{% if user.is_admin %}
<span class="badge">Admin</span>
{% elif user.is_moderator %}
<span class="badge">Mod</span>
{% else %}
<span class="badge">User</span>
{% end %}
Kida uses unified {% end %} to close all blocks. Explicit closers ({% endif %}, {% endfor %}, {% endblock %}) are also accepted for readability in deep nesting, but {% end %} is the canonical style.
{% for item in items %}
<li>{{ item.name }}</li>
{% else %}
<li>No items found</li>
{% end %}
{{ loop.index }} {# 1-based #}
{{ loop.first }}
{{ loop.last }}
{{ loop.length }}
{% match status %}
{% case "active" %}✓ Active
{% case "pending" %}⏳ Pending
{% case _ %}Unknown
{% end %}
| Keyword | Scope | Jinja2 equivalent |
|---|---|---|
{% let x = ... %} | Template-wide — visible everywhere after assignment | {% set %} at top level |
{% set x = ... %} | Block-scoped — does NOT leak out of {% if %}, {% for %}, etc. | No equivalent |
{% export x = ... %} | Promotes to template (outermost) scope from any depth | namespace() pattern |
Jinja2 trap: In Jinja2,
{% set %}inside a block modifies the outer variable. In Kida,{% set %}is block-scoped. Use{% let %}for template-wide variables.
{# page.html #}
{% extends "base.html" %}
{% block title %}About - My Site{% end %}
{% block content %}
<h2>About Us</h2>
<p>{{ page.content }}</p>
{% end %}
super() — child blocks fully replace parent content{% block extra_head %}{% end %} for add-to patterns{% include "partials/header.html" %}
{% include "partials/user-card.html" with user=current_user %}
Define reusable components with {% def %} and use them with {% call %}:
{% def card(title) %}
<div class="card">
<h3>{{ title }}</h3>
<div class="body">{{ caller() }}</div>
</div>
{% end %}
{% call card("Settings") %}
<p>This becomes the card body (default slot).</p>
{% end %}
Components can define multiple insertion points with named slots:
{% def modal(title) %}
<dialog>
<h2>{{ title }}</h2>
<div class="body">{% slot %}</div>
<footer>{% slot footer %}<button>Close</button>{% end %}</footer>
</dialog>
{% end %}
{% call modal("Confirm") %}
{% slot footer %}<button>Cancel</button> <button>OK</button>{% end %}
<p>Are you sure?</p>
{% end %}
{% slot %} in a {% def %} = default slot placeholder{% slot name %} in a {% def %} = named slot placeholder (with optional default content){% slot name %}...{% end %} inside {% call %} = provides content for a named slot{% call %} = provides content for the default slot{% fill %} tag — always use {% slot %} inside {% call %}{% from "chirpui/modal.html" import modal %}
{% from "chirpui/button.html" import button %}
{% call modal("Delete Item") %}
<p>This cannot be undone.</p>
{% slot footer %}{{ button("Delete", variant="danger") }}{% end %}
{% end %}
Use has_slot() inside a def to conditionally render wrappers:
{% def card(title) %}
<div class="card">
<h3>{{ title }}</h3>
{% if has_slot() %}
<div class="body">{{ caller() }}</div>
{% end %}
</div>
{% end %}
template.render_block("block_name", **ctx) # Render single block for HTMX/partials
{% cache "sidebar" %}
{% for item in nav_items %}
<a href="{{ item.url }}">{{ item.title }}</a>
{% end %}
{% end %}
{% cache "user-" ~ user.id, ttl="5m" %}
{{ render_profile(user) }}
{% end %}
{{ title |> escape |> upper |> truncate(50) }}
{{ items | default([]) | length }}
{{ html_content | safe }}
Output is escaped by default. Use | safe for trusted HTML.
All blocks use unified {% end %}. Explicit closers ({% endif %}, {% endfor %}, {% endblock %}) are accepted but {% end %} is preferred.
page_title, sidebar_navigation| default() for optional variables~ for dynamic URL/path building: hx-post="{{ '/chains/' ~ chain_id ~ '/add-step' }}"{% def %} functions insteadrender_route_tabs, format_date) and noun-like names for context variables (route_tabs, items). Same-name collisions cause the macro to shadow the variable, leading to "Cannot iterate over macro" when the variable is missing.