Origami template documents

Text files with embedded Origami expressions

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, like index.ori.html or about.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.