Origami supports .yaml files as a known file type.
Origami’s YAML parser adds support for two custom YAML tags: !ori and !ori.call, which allow for Origami expressions to be embedded in YAML documents.
These tags can be helpful in contexts where the bulk of the data in a file can be easily expressed in YAML, but you wish to attach additional data from other data sources or incorporate the results of calculations.
!ori tag #
The !ori tag evaluates the rest of the line as an Origami expression.
# tagDemo.yaml
sample: This is plain text
calculation: !ori 1 + 1
greeting: !ori greet.js("world")
Evaluating this causes the !ori expressions to be evaluated.
$ ori tagDemo.yaml/
sample: This is plain text
calculation: 2
greeting: Hello, world.
Because Origami expressions are evaluated asynchronously, the parsed YAML data will be an object whose calculation and greeting properties are each a Promise for the expression’s value.
!ori.call tag #
The related !ori.call tag takes an array of values. The first will be evaluated as an Origami expression, which should return a function. That function will be called with the remaining array values as arguments.
Suppose callTagDemo.yaml contains:
sample: This is plain text
html: !ori.call
- Origami.mdHtml
- Here is some text with _formatting_.
The !ori.call tag will invoke the Origami.mdHtml function, passing it the remaining value in the array as its argument.
Evaluating this YAML file invokes the function:
$ ori callTagDemo.yaml/
sample: This is plain text
html: |
<p>Here is some text with <em>formatting</em>.</p>
Incorporate a file as a property #
Suppose you have a set of data files to represent information on products. Most of the data is text or numbers, but you’d also like to associate each product with an image. A typical solution is to reference an image by a path:
product: Widget
description: Our latest model
image: images/widget.svg
The image property is a string, “images/widget.svg”. Code that renders this object has to be aware of the path and know what base address the path is relative to.
In some cases, it may be preferable to make the file contents available as a property of the data object.
product: Widget
description: Our latest model
image: !ori images/widget.svg
Here the image property will be (a Promise for) the actual SVG content. The path will be resolved using the Origami scope for the folder containing the YAML file. The expression could just as easily reference a network file via a URL.
Code that renders the product as an HTML page won’t need to care where the image came from.
YAML includes #
A related use for the !ori tag is to break apart YAML files into pieces that can be combined. Programming languages often support such decomposition with include statements.
Suppose a commonly-used block of YAML is defined in its own file:
# address.yaml
street: 123 Main St
city: Anytown
state: CA
postal_code: 12345
country: USA
This can then be included in a second YAML file:
# order.yaml
product: Widget 2.0
quantity: 3
ship_to: !ori address.yaml/
To include the object represented by the first YAML file, the address.yaml/ needs a trailing slash to unpack that file. Referencing address.yaml on its own would return the YAML file text.
With that, evaluating the second file returns an object that incorporates the first:
$ ori order.yaml/
product: Widget 2.0
quantity: 3
ship_to:
street: 123 Main St
city: Anytown
state: CA
postal_code: 12345
country: USA
This allows complex files to be broken down into smaller, reusable pieces.
Apply a template to data #
One use for !ori.call is to apply a template to data.
Suppose a project defines a template document called page.ori.html:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>${ _.title }</title>
</head>
<body>
<h1>${ _.title }</h1>
${ _._body }
</body>
</html>
This template document defines a function that accepts a single _ underscore parameter. The argument passed as that parameter should have title and _body properties.
A YAML file can define data and indicate that the template function should be applied to it:
!ori.call
- page.ori.html
- title: The Hitchhiker's Guide to the Galaxy
_body: |
Far out in the uncharted backwaters of the unfashionable end of the western
spiral arm of the Galaxy lies a small unregarded yellow sun. Orbiting this
at a distance of roughly ninety-two million miles is an utterly
insignificant little blue-green planet whose ape-descended life forms are so
amazingly primitive that they still think digital watches are a pretty neat
idea. —Douglas Adams
Evaluating this applies the template as a function to the data and returns the resulting text. (While YAML files typically define objects, they can also define a single value, such as a text string.)
$ ori quote.yaml/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<title>The Hitchhiker's Guide to the Galaxy</title>
</head>
<body>
<h1>The Hitchhiker's Guide to the Galaxy</h1>
Far out in the uncharted backwaters of the unfashionable end of the western
spiral arm of the Galaxy lies a small unregarded yellow sun. Orbiting this
at a distance of roughly ninety-two million miles is an utterly
insignificant little blue-green planet whose ape-descended life forms are so
amazingly primitive that they still think digital watches are a pretty neat
idea. —Douglas Adams
</body>
</html>
This effectively treats a YAML file as a format for describing a function call, with potentially complex arguments and significant blocks of multi-line text.