Dario Castañé

Updated: · By Dario Castañé · Permalink

Templates and plugins

Zas uses Go templates in page content and in the shared .zas/layout.html, with different escaping behavior.

Layout

A minimal layout can use:

<!doctype html>
<html lang="{{.Language}}">
<head>
  <meta charset="utf-8">
  <title>{{.Title}}</title>
  <link rel="canonical" href="{{.Canonical}}">
  {{with .Summary}}<meta name="description" content="{{.}}">{{end}}
</head>
<body>
  <main>{{.Body}}</main>
</body>
</html>

The layout runs through Go's html/template, which escapes values according to their HTML context. .Body contains the already-rendered page body.

Metadata helpers

Helper Value
.Title Explicit page title, otherwise the first H1.
.Language Resolved page language.
.Canonical Absolute page URL with a final /index.html replaced by /.
.URL Absolute generated path; retains /index.html when that is the filename.
.Date Explicit RFC3339 date, or zero time.
.Updated Explicit updated, otherwise the tracked source's latest git commit date, or zero time.
.Summary Explicit summary, or an empty string.
.Tags Explicit string-list tags, in their original order.
.Page Page YAML map.
.Directory Directory configuration map.
.Resolve "language" Page, directory, then site setting.
.Extra "/site/baseurl" Direct string lookup in the site configuration.

A standalone article.md has canonical /article.html; the helper only normalizes index pages. To format a publication date, first check that it is present:

{{if not .Date.IsZero}}<time datetime="{{.Date.Format "2006-01-02T15:04:05Z07:00"}}">{{.Date.Format "2006-01-02"}}</time>{{end}}

Invalid explicit metadata stops template execution when its helper is used. Publication dates are never inferred from git, file timestamps or build time. A full-history checkout gives .Updated accurate git history.

Inside a page's own content, .Page, .Title and .FirstTitle use a best-effort preview. The layout sees the final values after page rendering. .Body is empty inside the page's own template.

JSON in layouts

dict, list and json are layout-only helpers. Build objects rather than passing a pre-encoded JSON string:

{{$person := dict "@type" "Person" "name" "Dario Castañé" "url" .Site.BaseURL}}
<script type="application/ld+json">{{json (dict "@context" "https://schema.org" "@graph" (list $person))}}</script>

json serializes the value with encoding/json and retains its HTML-sensitive character escaping. Serialization errors fail the build. It adds no schema automatically.

Embeds

Built-in handlers support Markdown, HTML and plain text:

<embed src="navigation.md" type="text/markdown" />

Page-body embeds resolve relative to the containing page. Layout embeds resolve relative to the site root. Built-in nested embeds remain inside the site root and have a depth limit.

Mark an embedded-only navigation file publish: false to prevent it also becoming a standalone page. With Markdown twins enabled, Markdown embeds must occupy a standalone line; combinations with reference definitions or footnotes are rejected to avoid changing reference scopes.

Plugin and template trust model

Page content runs through Go's text/template with no automatic escaping. This includes template actions inside code fences. To display literal actions, put template: false in the page's leading configuration comment. The layout still runs normally.

External subcommands named zs<name> and MIME handlers named mzs<name> are programs found on PATH. Content can trigger MIME handlers through embeds, or zs programs through <script type="application/zas+name"> tags. Zas does not sandbox or verify these binaries.

Build content you do not fully control with:

zas -full -no-plugins

-no-plugins rejects content-triggered external MIME and script plugins rather than executing them. Built-in embeds still run, and the flag does not restrict a plugin explicitly invoked as zas <name> on the command line.

template: false alone does not disable embeds or plugins, and -no-plugins alone does not disable Go template execution. For untrusted documentation, render or sanitize it separately, avoid executing its template actions, and keep -no-plugins enabled in the assembly build.

Use layout noescape or .H only for HTML you trust. .E is escaped in the layout but not in a page's own template; .H marks translations as trusted HTML in the layout.

Source: Zas at d89a28125f63. AGPL-3.0-or-later license. Documentation index · Full documentation.