Template Authoring Guide (Jinja Essentials)

Your template file is a standard document with special VIBE commands mixed in. These commands use a language called Jinja. You only need to know a few core commands and helpers to do most of what you'll need.

Printing a Variable: {{ ... }}

This is the most common command. It tells VIBE to "print the value of this variable here."

The agreement is between Acme Inc. and {{ client_name }}.
The total value is ${{ contract_value }}.

Conditional Logic: {% if ... %}

This allows you to show or hide entire blocks of text based on the user's answers. Every {% if %} must be closed with an {% endif %}.

Using a bool (Yes/No) variable:

{% if include_nda %}
A Non-Disclosure Agreement must be signed by both parties.
{% endif %}

Comparing a variable to a value:

{% if contract_type == 'premium' %}
As a premium client, you are entitled to 24/7 support.
{% else %}
Standard support hours are 9 AM to 5 PM.
{% endif %}

Looping Through a List: {% for ... %}

If you have a list question type, you can loop through each item the user entered and print its details.

**Project Stakeholders:**
{% for stakeholder in project_stakeholders %}
- Name: {{ stakeholder.name }}, Email: {{ stakeholder.email }}
{% endfor %}

Built-in Filters: |

Filters modify a variable's value right before it's printed. You use the pipe | character.

  • | safe_default('fallback text'): Provides fallback text if a variable is unanswered. Recommended for cleaner previews and optional sections.

    Prepared for: {{ client_name | safe_default('[Client Name Here]') }}
    

  • | selected_choices: Used with multichoice variables. It returns a list of only the options the user actually checked.

    {% for item in service_scope | selected_choices %}
    - {{ item }}
    {% endfor %}
    

  • | markdown: Converts a string containing Markdown into HTML. Useful for printing the content of a textarea that might have formatting.

    {{ project_description | markdown }}
    

Built-in Functions

VIBE provides helpful functions you can use in your templates.

  • defined('variable_id'): Checks if a variable has been answered. This is more powerful than a simple {% if variable %} because it doesn't fail if the variable doesn't exist in the context yet. It always returns true or false.

    {% if defined('optional_notes') %}
    **Additional Notes:**
    {{ optional_notes }}
    {% endif %}
    

  • show_message(message_id): Triggers the display of a note, warning, or error block from your config.yml. This function doesn't print anything itself; it just tells VIBE to make the message block relevant.

    {% if total_value > 100000 %}
      {{ show_message(large_contract_warning) }}
    {% endif %}
    

  • insert(component_id): Inserts a component into the template at that point. See Building with Components for details.

    {{ insert('contract_header') }}
    

  • appendix(component_id, alias): Creates a separate appendix document that will be generated alongside your main document. See Generating Appendices and Annexes for details.

    {{ appendix('schedule_a', 'payment_schedule') }}
    

Template Metadata

VIBE provides a special meta object that gives you access to session information, timestamps, and template details.

  • meta.session_id: The unique identifier for this interview session.
  • meta.now(): Current timestamp (use with |strftime('%Y-%m-%d') to format).
  • meta.template.name: The template identifier.
  • meta.template.version: The version (Git SHA or "WORKING_TREE").
  • meta.assistant.<name>.turns: Number of interactions with an AI assistant (Assistant extension only).
  • meta.assistant.<name>.tokens: Total tokens consumed by an AI assistant (Assistant extension only).
Generated {{ meta.now()|strftime('%B %d, %Y') }} | Session: {{ meta.session_id }}

See Template Metadata Reference for complete details.