Template documents represent a middle ground between documents that can contain some data in front matter and Origami files that contain templates.
- A template document file is identified with two extensions, where the second-to-last extension is
.ori
, likeindex.ori.html
orabout.ori.md
. - When you ask Origami to evaluate such a file, it will implicitly inline the results of any Origami expressions inside the file.
A template document is appropriate when you have a long template that may need portions of embedded or attached code. (For brevity, some of the samples shown below have very short templates.)
Example
This template document is called inline.ori.html
:
<!DOCTYPE html>
<html>
<head>
<style>
${ inline.css }
</style>
</head>
<body>
This text will be red.
</body>
</html>
Substitutions inside a template document are full Origami expressions so, among other things, they can reference other documents. In this case, the above template includes an embedded Origami expression that references a separate file, inline.css
:
/* inline.css */
body { color: red }
If you have ask Origami to evaluate inline.ori.html
, it will return the text with the results of all expressions inline:
$ ori inline.ori.html/
<!DOCTYPE html>
<html>
<head>
<style>
body { color: red }
</style>
</head>
<body>
This text will be red.
</body>
</html>
Accepting an argument
By default, a template document can be called as a function with one argument referenced with a _
underscore.
<!-- bold.ori.html -->
<b>${ _ }</b>
When called as a function, any value passed to this template will be incorporated into the output:
$ ori "bold.ori.html('Hooray')"
<b>Hooray</b>
Front matter
Like other text documents, a template document can include front matter at the top of the document, enclosed in lines of ---
three hyphens.
By default, front matter is treated as YAML (including JSON). This can be used to define additional data. The template’s body text will be evaluated and added to the data as a @text
property.
Alternatively, front matter can be an Origami expression. This will generally be a function, function call, or an object literal; see below for examples.
Defining the value of the template document
By default, the result of invoking a template document will be template’s body text with the values of all embedded Origami expressions inlined.
You can arrange for some other result by placing an Origami expression in the document’s front matter. If Origami front matter is present, that will be evaluated and returned as the result of invoking the template document.
Within this front matter, you can invoke the template’s body text as @template
.
Example: a website defines its “About” page as a template document called about.ori.html
:
---
page.ori.html(@template())
---
<article>
<p>We have fun making websites.</p>
</article>
The front matter of this document is an Origami expression that will be evaluated and returned as the result of the template document.
In this case, the expression invokes the template’s body text via @template
, then passes that to a base page.ori.html
template defined separately:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
</head>
<body>
${ _ }
</body>
</html>
When you ask for the value of about.ori.html
, that in turn calls page.ori.html
:
$ ori about.ori.html/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
</head>
<body>
<article>
<p>We have fun making websites.</p>
</article>
</body>
</html>
Returning a function
To define your template document as a more complex function — e.g., one that accepts multiple arguments, or that calls other functions — define a function in the front matter.
This link.ori.html
template accepts href
and text
parameters to return an HTML link:
---
(href, text) => @template()
---
<a href="${ href }">${ text }</a>
The value of the href
and link
parameters are in scope for expressions in the template body.
$ ori "link.ori.html('https://weborigami.org', 'Web Origami')"
<a href="https://weborigami.org">Web Origami</a>
Returning an object
Sometimes a template is primarily body text but the result should include some calculated data.
This can be achieved using the above principle of placing an Origami expression in the front matter. In this case, the front matter can define an object using an object literal.
If calcs.ori.md
contains:
---
{
sum: 1 + 1
@text: @template()
}
---
One plus one is ${ sum }.
then invoking this returns an object:
$ ori calcs.ori.md
sum: 2
"@text": |
One plus one is 2.
Behavior within a map
When used inside a tree:map
function, a template document will provide a default key
function to the map. This key
function will add the template document’s last extension to keys in the map’s output.
For example, this template is called movie.ori.html
, so it will add .html
to keys in a map.
<!-- movie.ori.html -->
<article>
<h1>${ _/title } (${ _/year })</h1>
</article>
When applied to this data:
# movies.yaml
kiki:
title: Kiki's Delivery Service
year: 1989
mononoke:
title: Princess Mononoke
year: 1997
spirited:
title: Spirited Away
year: 2001
heron:
title: The Boy and the Heron
year: 2023
the values will end up with .html
extensions:
$ ori map movies.yaml, movie.ori.html
kiki.html: |
<article>
<h1>Kiki's Delivery Service (1989)</h1>
</article>
mononoke.html: |
<article>
<h1>Princess Mononoke (1997)</h1>
</article>
spirited.html: |
<article>
<h1>Spirited Away (2001)</h1>
</article>
heron.html: |
<article>
<h1>The Boy and the Heron (2023)</h1>
</article>
You can override this behavior by providing a key
function to the map.