Skip to content

Templating

Jinja2-based template engine for Gemtext output.

TemplateEngine

High-level template rendering interface.

TemplateEngine

TemplateEngine(
    templates_dir: Path, app: Xitzin | None = None
)

High-level template rendering interface.

Example

engine = TemplateEngine(Path("templates")) response = engine.render("page.gmi", title="Welcome", items=["a", "b"])

With app integration (enables reverse() in templates): engine = TemplateEngine(Path("templates"), app=app) # In templates: # {{ reverse("user_profile", username="alice") | link("Profile") }}

Create a template engine.

Parameters:

Name Type Description Default
templates_dir Path

Directory containing template files.

required
app Xitzin | None

Optional Xitzin app instance for URL reversing in templates.

None

Raises:

Type Description
ValueError

If templates_dir doesn't exist.

Source code in src/xitzin/templating.py
def __init__(self, templates_dir: Path, app: Xitzin | None = None) -> None:
    """Create a template engine.

    Args:
        templates_dir: Directory containing template files.
        app: Optional Xitzin app instance for URL reversing in templates.

    Raises:
        ValueError: If templates_dir doesn't exist.
    """
    if not templates_dir.exists():
        msg = f"Templates directory does not exist: {templates_dir}"
        raise ValueError(msg)

    self._env = GemtextEnvironment(templates_dir, app=app)

render

render(
    template_name: str, **context: Any
) -> TemplateResponse

Render a template file.

Parameters:

Name Type Description Default
template_name str

Name of the template file (e.g., "page.gmi").

required
**context Any

Variables to pass to the template.

{}

Returns:

Type Description
TemplateResponse

TemplateResponse that can be returned from handlers.

Example

return engine.render("user.gmi", username="alice", posts=posts)

Source code in src/xitzin/templating.py
def render(self, template_name: str, **context: Any) -> TemplateResponse:
    """Render a template file.

    Args:
        template_name: Name of the template file (e.g., "page.gmi").
        **context: Variables to pass to the template.

    Returns:
        TemplateResponse that can be returned from handlers.

    Example:
        return engine.render("user.gmi", username="alice", posts=posts)
    """
    template = self._env.get_template(template_name)
    content = template.render(**context)
    return TemplateResponse(content)

render_string

render_string(source: str, **context: Any) -> str

Render a template from a string.

Parameters:

Name Type Description Default
source str

Template source string.

required
**context Any

Variables to pass to the template.

{}

Returns:

Type Description
str

Rendered string.

Example

result = engine.render_string("# {{ title }}", title="Hello")

Source code in src/xitzin/templating.py
def render_string(self, source: str, **context: Any) -> str:
    """Render a template from a string.

    Args:
        source: Template source string.
        **context: Variables to pass to the template.

    Returns:
        Rendered string.

    Example:
        result = engine.render_string("# {{ title }}", title="Hello")
    """
    template = self._env.from_string(source)
    return template.render(**context)

TemplateResponse

Response wrapper for rendered templates.

TemplateResponse

TemplateResponse(
    content: str, mime_type: str = "text/gemini"
)

Response from a rendered template.

Can be returned from handlers and will be converted to a GeminiResponse.

Source code in src/xitzin/templating.py
def __init__(self, content: str, mime_type: str = "text/gemini") -> None:
    self.content = content
    self.mime_type = mime_type

Gemtext Filters

The template engine includes these filters for generating Gemtext:

Generate a Gemtext link line.

{{ "/about" | link("About Us") }}
{# Output: => /about About Us #}

{{ "/home" | link }}
{# Output: => /home #}

heading

Generate a Gemtext heading (levels 1-3).

{{ "Title" | heading(1) }}
{# Output: # Title #}

{{ "Section" | heading(2) }}
{# Output: ## Section #}

{{ "Subsection" | heading(3) }}
{# Output: ### Subsection #}

list

Generate a Gemtext list from an iterable.

{{ ["Apple", "Banana", "Cherry"] | list }}
{# Output:
* Apple
* Banana
* Cherry
#}

quote

Generate a Gemtext blockquote.

{{ "Hello world" | quote }}
{# Output: > Hello world #}

preformat

Generate a preformatted code block.

{{ code | preformat }}
{# Output:
code
#}

{{ python_code | preformat("python") }}
{# Output:
```python
python_code

}

```