Page structure

The same content can be delivered to the Web in different structured formats, and the transformation of that content in the final pages must be completely automatic.

General operation

Web pages structure is defined by the HTML markup, and using jqt it is added to the input content and data using a template. jqt transforms templates into jq scripts, but before that GPP is used to preprocess them. The generated script will be combined with the document and data inputs in the render stage to produce the final HTML page. This is described on the top of this diagram:

jqt workflow
           jqt        +------+   +-------+  jq script
Template +----------->|expand|-->|convert|-------------------------------+
                      +------+   +-------+                               |
                                             HTML and CSS                | 
                                             fragments                   v
           MarkDown   +------+   +------+   /-------->+-----+  JSON   +------+ HTML
Document +----------->|expand|-->|markup|--+          |merge|-------->|render|------> Page
                      +------+   +------+   \-------->+-----+         +------+
                                             YAML      ^   ^
                                             metadata  |   |
           JSON       +------+                         |   |
         +----------->|expand|-------------------------+   |
    Data   YAML       +------+                             |     CSS  +------+ 
         +-------------------------------------------------+    +---->|expand|------> Style
           YAML snippets         +------+                  |          +------+
         +---------------------->|markup|------------------+
                                 +------+
When invoking jqt you can use the -D, -I, -i, -j and -L options to modify template rendering:
-D NAME=STRING
Defines the user macro NAME as equal to STRING.
-I DIRECTORY
Appends DIRECTORY to the end of the preprocessor list of directories to be searched for include files.
-i MODULE
Includes the jq MODULE in the render stage.
-j NAME:MODULE
Imports the jq MODULE in the render stage and define helper function named NAME if MODULE is a data module and has the suffix .json.
-L DIRECTORY
Appends DIRECTORY to the end of the jq list of directories to be searched for included and imported modules.

Template syntax

A template is a text file with intermixed snippets of jq code. Snippets can be expressions (delimited by {{ and }}), which get replaced with values when a template is rendered and actions (delimited by {% and %}), which control the logic of the template. Comments (delimited by {# and #}) are ignored and not copied to the output. This is a complete template example:

<html lang='{{page.lang//site.lang}}'>
<head>
    <title>{{page.title | gsub("<[^>]*>"; "")}}</title>
    {# include files in preprocessing stage: #}
    <%include "head.html">
    <meta name="generator" content="JQT v<%version>"/>
    {# optional line: #}
    <meta name='dcterms.modified' content='{{page.updated//empty}}' />
    {# implicit loop for all authors: #}
    {% page.author | sort[] %}<meta name='author' content='{{.}}' />
</head>
<body>
    <h1>{{page.title}}</h1>
    <div id="CONTENT">
        {{$jqt._content}}
    </div>
    {# macro calls: #}
    <%partial analytics 'UA-82432866-1'>
</body>
</html>

Preprocessing

Templates are preprocessed using GPP. All the expected options in a preprocessor are available, like defining new macros, include other files, etc. For example, a template fragment like

<meta name="generator" content="JQT v<%version>"/>

will expand to the string <meta name=“generator” content=“JQT v0.5.1”/> (assuming the macro version has been defined) as you can see in the internal code of this page.

Macro calls

The macro syntax used by jqt in templates and MarkDown documents precedes macro names with the characters <% and finishes the macro calls with the character >. Here are some of the predefined macros:

<%defeval x y>
<%define x y>
<%elif expr>
<%else>
<%endif>
<%eval expr>
<%if expr>
<%ifdef x>
<%ifeq x y>
<%ifndef x>
<%ifneq x y>
<%include file>
<%undef x>

Inside macro definitions parameters are prefixed by a dollar ($1, $2, etc.), but named parameters are also possible:

<%define stylesheet
    <link rel="stylesheet" type="text/css" href="$1"/>
>

Predefined macros and user define macros have the same call sequence:

<%include head.html>
<%stylesheet jqt.css>

With these simple tools is possible to emulate features considered advanced in some template engines, like template inheritance (also known as blocks). For example, in the base template (assume it is named default.html) you can put this conditional macro call to define a default title block:

<%ifndef HEAD_TITLE>
    <title>{{page.title}}</title> {# default block #}
<%else><%call HEAD_TITLE><%endif>

And in the derived template you can define a new macro for the desired block, before include the base template:

<%define HEAD_TITLE
  <title>{{page.title}} – {{site.title}}</title>
>
<%include default.html>

In addition to GPP predefined macros jqt define some macros to be included in the render stage. The more useful will be perhaps <%partial name arg...>, to include a template file passing arguments to it and <%call name arg...>, to call a macro by name.

Warning: you must see the GPP manual if you want to know all the gory details.

Skips

Some fragments of text are skipped during macro expansion, like comments, continuation lines and delimited strings of characters:

<# Block comments, removed #>
Continuation lines using an ampersand &
just before the newline character

Strings are copied to the output, but evaluation of macros inside strings can be enabled or disabled. String delimiters can be copied, or not, to the output:

<!-- XML comments -->
<%sc 'Single quoted strings, only available in user defined macro calls'>
<%sc "Double quoted strings, only available in user defined macro calls">
All jqt template delimited regions: {#...#}, {%...%}, {{...}} 

This table summarizes all the available skips:

Semantics for all jqt template skips
Delimiters Macro expansion Delimiters removed Content removed
&\n1 No Yes There is no content
<# #> No Yes Yes
' '2 No Yes No
" "3 Yes Yes No
<!-- --> No No No
{{ }} No No No
{% %} No No No
{# #} No No No

Code snippets

The input text for a template is UTF-8 text with intermixed snippets of jq code. Snippets can be expressions, actions and comments. The delimiters used by jqt are as follows:

Delimiters used in jqt templates
Delimiters Purpose
{{ ... }} Expressions to evaluate
{% ... %} Actions for conditional evaluation and loops
{# ... #} Comments not included in the output

Expressions

The text in expressions and actions is normal jq code, where as a bonus, the $jqt global variable points to the jq JSON input (the initial .). The rules for expression evaluation are very simple:

Warning: if a line contains two or more expressions producing multiple values a cartesian product is generated!

Actions

There are two kinds of actions:

The evaluation rules for one line actions are as follows:

The evaluation rules for multiline actions are as follows:


  1. An ampersand followed by a newline is treated as a line continuation (that is, the ampersand and the newline are removed and effectively ignored).↩︎

  2. Only inside user defined macros.↩︎

  3. Only inside user defined macros.↩︎