Templates are written in Jinja2 look at his documentation for details.

Almoststatic add only a few rules:

  • Into pages you can set the templ_name metadata field or accept the default which is page.html here a sample:

    {%extends page.extends or "base.html" %}
    {%block body%}
    <main role="main">

    The content field is the content of page with list of widgets.

  • The extends metadata field in page can change the base of page, if not present accept the default. The base template contain the common part for each page, to simplify:

    <!DOCTYPE html>
    <meta name="description" content="{{page.description}}">
    <meta name="author" content="{{page.author}}">
    <meta name="generator" content="{{meta.generator}}">
    <link rel="stylesheet" href="{{get_media('css/main.css')}}">
    <div class="container">
       {% block body %}
       {% endblock %}
    <script src="{{get_media('js/main.js')}}" type="text/javascript"></script>
  • The content part of a yaml page file, is al list of widgets, each widget must have his template file, i.e. the tabbed widget must have a tabbed.html like this:

    {%include "include/widget_style.html" -%}
    <div id="{{widget.id}}" class="{{widget.class}}">
    <ul class="nav {{widget.tabs_style or 'nav-tabs'}}" role="tablist">
        {% for i,item in enum_list(widget.tabs) -%}
        <li class="nav-item" role="presentation">
        <button class="nav-link {{' active' if item.active else ''}}" id="nav-{{widget.id}}{{i}}-tab" data-bs-toggle="tab"
            data-bs-target="#nav-{{widget.id}}{{i}}" type="button" role="tab" aria-controls="{{item.label}}"
            aria-selected="{{'true' if item.active else 'false'}}">{{item.label}}</button>
        {% endfor -%}
    <div class="tab-content" id="nav-{{widget.id}}-content">
        {% for i,item in enum_list(widget.tabs) -%}
        <div class="tab-pane fade{{' show active' if item.active else ''}}" id="nav-{{widget.id}}{{i}}" role="tabpanel"
        {% endfor -%}

    Within a widget template you have access to the widget object with all values declared into yaml file.

  • In each template you have access to the page object with all it’s metatada fields, the content list and all extra fields added to it.

  • In each template you have access to global data declared in config.yaml file also as a dictionary in the config field, for example, if you have into config file a list called MainMenu, you can write something like:

    {% for item in config[page.menu] or MainMenu -%}
    <a href="{{get_url(item.url)}}">{{ item.name }}</a>
    {% endfor -%}