Front matter keys, TT variables, configuration keys, and file locations.
Front matter is the YAML metadata block at the top of each page. Its keys are documented, with examples, in Front matter.
Site-wide configuration in public_html/lazysite/lazysite.conf. One
key-value pair per line.
key: value - used as-is.
key: ${ENV_VAR} - interpolated from the CGI environment. Multiple
vars and mixed text supported: ${REQUEST_SCHEME}://${SERVER_NAME}
key: url:https://... - fetched, trimmed, and cached with the page.
key: scan:/path/*.md sort=field dir - returns array of page objects.
site_namesite_url${REQUEST_SCHEME}://${SERVER_NAME} so the same
config works on staging and production.
layoutlazysite/layouts/NAME/layout.tt. May also be a remote URL.
themelazysite/layouts/LAYOUT/themes/THEME/theme.json. The theme's
layouts[] array must contain the active layout or the theme is
skipped with a warning.
layouts_reponav_filelazysite/nav.conf.
search_defaultsearch: front matter key. Set to true
(default) or false. Pages without an explicit search: key inherit
this value.
managerenabled or disabled. Controls the built-in manager UI at
/manager.
manager_path/manager.
manager_groups (retired - SM138)ui capability granted to a group (Groups
page); on upgrade any group this key named receives its capabilities and the
line is removed.
update_channeledge < beta < stable < certified ladder: stable takes supported
releases; certified takes only builds whose compliance records were
walked (ADR 0010),
beta takes beta and stable, any other value (default) accepts every
release. Out-of-channel upgrades are skipped and audited. See
Update channel.
update_policyauto or manual (default). Whether the fleet-wide
lazysite upgrade --all run on deb-managed hosts upgrades this site;
manual sites are skipped. Set with install.pl --policy.
log_levelERROR, WARN, INFO, DEBUG. Default: INFO.
log_formattext (default) or json.
pluginsauth_defaultauth: front matter key. Set to required,
optional, or none (default).
auth_header_user, auth_header_name, auth_header_email, auth_header_groupsX-Remote-User, X-Remote-Name, X-Remote-Email, X-Remote-Groups.
alias_hostsalias.<host>.<key><key> is limited to site_name, theme,
layout, nav_file, search_default; other keys are ignored.
Each alias host has its own page-cache slot (lazysite/cache/hosts/),
cleared alongside the primary cache. Conf-file only - not settable via
the manager or API.
All other keys are available as TT variables in page content and the layout template.
See Configuration for full details.
page_titletitle:.
page_subtitlesubtitle:.
page_modifiedpage_modified_isocontentrequest_uri/about. Set from REDIRECT_URL or
REQUEST_URI.
page_source.md file, e.g. /about.md.
Useful for admin bar and edit links.
navnav.conf. Each item has label, url,
children (array of label/url hashes).
query, paramsquery_params: is declared
in front matter. params is an alias for query.
year2026.
search_enabled1 if a search-results.md (or .url) page exists in the docroot,
0 otherwise.
site_name, site_urllazysite.conf.
alias_hostbrand2.example) when the request's
Host header matches a declared alias_hosts entry; empty string on the
primary host. Useful for per-host branching or canonical links.
layout_namethemetheme.json (hash) when a compatible theme is active. Access
config values as [% theme.config.GROUP.KEY %]. Empty hash when no
theme is active.
theme_nametheme_assets/lazysite-assets/LAYOUT/THEME/ for local themes (nested per D013);
/lazysite-assets/CACHE_KEY/ for remote layouts (flat).
Unset when no theme is active.
theme_css<style>:root { ... } block of CSS custom properties
derived from theme.config. Empty string when no theme is active.
Naming convention: --theme-GROUP-KEY.
authenticated1 if the request carries valid auth headers, 0 otherwise.
auth_userauth_nameauth_emailauth_groupseditor1 if the authenticated user has manager access (a group grants the ui
capability), 0 otherwise. Use in layouts to gate admin UI.
Site variables (from lazysite.conf) are loaded first. Page variables
(from tt_page_var) override site variables of the same name. Automatic
variables (page_title, page_subtitle, content, etc.) override both.
Only these CGI variables may be interpolated via ${VAR} in
lazysite.conf:
SERVER_NAME - server hostnameSERVER_PORT - server portREQUEST_SCHEME - http or httpsHTTPS - on if HTTPSREQUEST_URI - full request URIREDIRECT_URL - requested page path (e.g. /about)DOCUMENT_ROOT - filesystem docroot pathSERVER_ADMIN - server admin emailHTTP_HOST is intentionally excluded - it is request-supplied and
untrusted. Use SERVER_NAME for host-based URL construction.
sanitise_uri rejects null bytes, .. path segments, and suspicious
characters before constructing filesystem paths. After construction, each
path is verified with realpath to confirm it resolves within $DOCROOT.
Symlinks pointing outside the docroot are rejected.
The same check is applied inside write_html before any file is written,
guarding against symlink-based overwrite attacks on the cache output path.
All values extracted from YAML front matter - including title, subtitle,
and tt_page_var entries - have TT directive markers ([% and %]) stripped
before entering the template context. register list items are stripped at
parse time. This prevents authored content from injecting TT directives into
the rendering pipeline.
The class name following ::: is validated against /\A[\w][\w-]*\z/ before
use. Blocks with class names containing characters outside word characters and
hyphens are rejected - the content renders without a wrapper div and a warning
is written to the error log.
oEmbed provider responses are parsed with JSON::PP (Perl core module) rather
than regex extraction. The html field from the parsed response is injected
into the page. Provider responses are trusted as-is - restrict %OEMBED_PROVIDERS
in lazysite-processor.pl to known hosts if untrusted providers are a concern in
your deployment.
DOCROOT/
lazysite/
lazysite.conf <- site configuration
nav.conf <- navigation
layouts/
NAME/layout.tt <- layout template
NAME/layout.json <- layout metadata (optional)
NAME/themes/THEME/
theme.json <- theme manifest
main.css <- theme-scoped CSS
assets/ <- theme assets (images, fonts)
manager/
layout.tt <- manager UI chrome (internal)
assets/manager.css <- manager CSS source
templates/
registries/ <- registry templates (.tt)
auth/
users <- user credentials
groups <- group memberships
forms/
FORMNAME.conf <- per-form target config
handlers.conf <- named dispatch handlers
smtp.conf <- SMTP connection settings
cache/
layouts/ <- remote-layout cache
tt/ <- TT compile cache
logs/ <- log files
lazysite-assets/
LAYOUT/THEME/ <- web-served theme assets (nested)
manager/
assets/
manager.css <- manager CSS (mirrored from source)
cm/ <- CodeMirror assets
404.md
index.md
[content pages]
Scripts (repo root, copied to site by the installer):
lazysite-processor.pl <- main processor
lazysite-auth.pl <- built-in auth
plugins/form-handler.pl <- form dispatch
plugins/form-smtp.pl <- SMTP helper
lazysite-manager-api.pl <- manager JSON API
plugins/payment-demo.pl <- payment demo helper
Source files:
*.md <- Markdown pages
*.url <- remote page pointers
*.html <- generated cache (auto-created)
Registry output (generated at DOCROOT):
sitemap.xml <- generated from sitemap.xml.tt
llms.txt <- generated from llms.txt.tt
feed.rss <- generated from feed.rss.tt
feed.atom <- generated from feed.atom.tt