Core reference · source audited
Template language essentials.
The v4 language is deliberately small. This page is matched against the current v0.3 parser and documents the public primitives we intend people to build new projects around.
@content places page content. @input composes reusable files. @pathto creates project-aware paths. $[...] exposes page/build metadata. @getenv reads build-time environment values. @ent emits the supported HTML entities.
@content — place tracked content
@content accepts zero parameters. Internally the parser processes the tracked content through the same input mechanism, so the content becomes part of the dependency graph.
<main>
@content
</main>
@input(...) — process and insert one file
@input accepts exactly one path. Nift first checks the path as supplied; if it does not exist there, it also checks relative to the directory of the file currently being processed.
@input('templates/partials/header.html')
@content
@input('templates/partials/footer.html')
The inserted file is parsed as Nift source, recorded as a dependency, and can itself contain additional @input calls. Input loops are detected and reported as build errors.
Relative partial composition
templates/
partials/
header.html
navigation.html
<!-- templates/partials/header.html -->
<header>
@input('navigation.html')
</header>
Because Nift can also resolve relative to the file currently being processed, nested partial structures do not have to repeat project-root paths everywhere.
@pathto(...) — checked paths from the current output
@pathto accepts exactly one value. If the value matches a tracked name, Nift resolves the target's output. Otherwise it treats the value as a concrete path and requires that path to exist.
Tracked-page links
<nav>
<a href="@pathto('/')">Home</a>
<a href="@pathto('about')">About</a>
<a href="@pathto('docs/getting-started')">Getting started</a>
</nav>
Nift calculates the path relative to the output currently being generated. For tracked targets whose output filename is index.html, it resolves to the containing directory rather than forcing index.html into the URL.
Concrete local assets
<link
rel="stylesheet"
href="@pathto('public/assets/css/site.css')">
<script
type="module"
src="@pathto('public/assets/js/app.js')"></script>
<img
src="@pathto('public/assets/images/logo.svg')"
alt="Site logo">
<a href="@pathto('public/files/guide.pdf')">
Download guide
</a>
If one of those concrete local paths does not exist, the parser reports that the target is neither a tracked name nor an existing file. That gives shared templates a useful build-time correctness check.
Why prefer it to manual relative paths?
<!-- fragile: tied to one output depth -->
<img src="../../assets/images/logo.svg" alt="Site logo">
<!-- project-aware and checked -->
<img
src="@pathto('public/assets/images/logo.svg')"
alt="Site logo">
See the full paths guide with more real HTML examples →
$[...] — tracked-page and build metadata
The current parser recognises exactly these 13 metadata names:
Templating essentials
docs/templating
content/docs/templating.html
public/docs/templating.html
templates/docs.html
UTC
04:53:14
04:53:14
Thursday August 13 2026
Thursday August 13 2026
2026
26
Linux
<title>$[title]</title>
<!-- built $[build-date] -->
Metadata reference and practical examples →
@getenv(...) — read one environment variable
@getenv accepts exactly one environment-variable name and writes its value into the generated output. An unset variable resolves to an empty value.
@getenv('NIFT_ENV')
<meta
name="deployment-environment"
content="@getenv('DEPLOY_ENV')">
Do not use @getenv to leak private tokens, passwords or credentials into client-visible HTML/JavaScript.
@ent(...) — emit a supported HTML entity
@ent accepts exactly one value. The mapping below is the complete mapping implemented by the current v4 parser.
| Input | Emits | Input | Emits |
|---|---|---|---|
` | ` | ~ | ˜ |
! | ! | @ | @ |
# | # | $ | $ |
% | % | ^ | ^ |
& | & | * | * |
? | ? | < | < |
> | > | ( | ( |
) | ) | [ | [ |
] | ] | { | { |
} | } | - | − |
_ | _ | = | = |
+ | + | | | | |
\ | \ | / | / |
; | ; | : | : |
' | ' | " | " |
, | , | . | . |
£ | £ | ¥ | ¥ |
€ | € | § or section | § |
+- | ± | -+ | ∓ |
!= | ≠ | <= | ≤ |
>= | ≥ | -> | → |
<- | ← | <-> | ↔ |
==> | ⇒ | <== | ⇐ |
<==> | ⇔ | <=!=> | ⇎ |
... | … |
@ent('@')
@ent('&')
@ent('...')
@ent('section')
@dep(...) — advanced escape hatch
@dep is implemented by the parser and accepts one or more existing dependency paths, but it is intentionally documented separately because most projects should not need it. Normal template/content/@input relationships already establish dependencies automatically.
Read the advanced @dep guide →
Escaping literal template characters
In Nift-processed files, prefix literal @, $ and # with a backslash when they would otherwise be interpreted by Nift:
Nift source Generated output
----------- ----------------
@media @media
$HOME $HOME
#release-notes #release-notes
This is particularly useful when Nift processes CSS containing rules such as:
@media (min-width: 60rem) {
.layout {
display: grid;
}
}
The generated CSS contains the normal @media rule.