Skip to content

Templates Reference

Each template lives in its own directory under templates/. The directory name is the template identifier — it is how Codraft matches user requests to templates.

  • Directorytemplates/
    • Directory_examples/
      • DirectoryBonterms_Mutual_NDA/
        • Bonterms-Mutual-NDA.docx
      • Directoryinvoice/
        • invoice.html
      • Directoryconsulting_agreement/
        • consulting_agreement.docx
        • config.yaml
      • Directoryevent_invitation/
        • event-invitation.html
        • config.yaml
    • Directorymy_template/
      • my_template.docx
      • manifest.yaml (auto-generated)
      • config.yaml (optional)
  • The directory name is the template identifier used for matching user intent
  • Each directory contains exactly one template file: either .docx or .html — not both
  • Variable names in the template must be valid Python identifiers: lowercase letters, numbers, and underscores
FormatEngineOutput
.docxdocxtpl.docx + .pdf (when docx2pdf or LibreOffice available)
.htmljinja2.html + .pdf (via weasyprint)

Both formats use the same Jinja2-style syntax for placeholders, conditionals, and loops.

Use double-brace syntax to mark text that should be collected from the user:

This Agreement is entered into by {{ disclosing_party_name }}
(the "Disclosing Party") with address at {{ disclosing_party_address }}.

Always include spaces inside the braces: {{ name }} not {{name}}. The same variable can appear multiple times in a template — it is collected once and substituted everywhere.

Use {% if %} / {% else %} / {% endif %} to include or exclude sections based on user answers:

{% if include_warranty %}
The Seller warrants that the goods are free from defects
for a period of {{ warranty_period }}.
{% else %}
The goods are sold "as is" without warranty.
{% endif %}

Two condition forms are supported:

Truthiness — the variable is truthy (boolean true or any non-empty string):

{% if include_ip_assignment %}
...
{% endif %}

Equality — the variable equals a specific value:

{% if payment_method == 'bank_transfer' %}
Bank: {{ bank_name }}, Account: {{ account_number }}
{% else %}
Payment will be made via {{ payment_method }}.
{% endif %}

Use {% for %} / {% endfor %} for repeating sections:

{% for milestone in milestones %}
Milestone: {{ milestone.description }}
Due Date: {{ milestone.date }}
Amount: {{ milestone.amount }}
{% endfor %}

Inside the loop body, sub-variables use dot notation: {{ loop_variable.field_name }}. Claude collects items one at a time, asking “Would you like to add another?” after each entry.

  • Single-level nesting only — no {% for %} inside {% if %}, or vice versa
  • No {% elif %} — use separate {% if %} blocks
  • No expressions{{ price * quantity }} is not supported
  • Variables are always user-supplied — no computed or derived fields

The manifest is auto-generated by the Analyzer skill when it parses your template. It records all discovered variables, conditionals, loops, and any overrides from config.yaml.

An optional file placed alongside the template by the developer. It controls the interview experience — custom questions, grouping, validation, and explicit types — without modifying the template itself.

See Configuring with config.yaml for a practical guide and config.yaml Reference for the complete field-by-field reference.

The templates/_examples/ directory contains example templates that ship with Codraft and are tracked in git:

ExampleFormatFeatures
Bonterms_Mutual_NDA.docxSimple variable substitution
invoice.htmlHTML template with CSS styling
consulting_agreement.docxConditionals, loops, and config.yaml
event_invitation.htmlConditionals, loops, and config.yaml

These are read-only references. To experiment, copy an example to a new directory under templates/.

Your own templates go in templates/<name>/ and are gitignored by default. Each template directory should contain:

  1. One template file (.docx or .html)
  2. An optional config.yaml for interview customization
  3. A manifest.yaml that will be auto-generated on first analysis