Layouts and Partials

Store a template once with the type web and a name. {{> name}} prints it inside another template, the layout pin wraps a page in it, and saving it takes effect everywhere at once.

A stored template has a type and a name

Create it through the cluster API. Your token needs the blueprinttemplates create scope.

POST /api/v1/blueprinttemplates
{
  "type": "web",
  "name": "product-card",
  "html": "<li>{{name}}: {{price | money \"EUR\"}}</li>"
}

A template also has a stylesheet and a script field. Once it exists it shows up in Manage Templates in RUAL Studio, where you can edit its HTML, its stylesheet and its script.

Creating one from Studio The create dialog in Manage Templates has no web type yet. A name no web template has is also looked up among all other templates, so an Email Template you create there and give the same name works as a partial or a layout, too. Replace its starting HTML with your own.

A partial is a shared piece

Print it with {{> name}}. It sees the data around it, or the value you hand it:

Using partials
{{> site-header}}

<ul>
  {{for p in products}}
    {{> product-card p}}
  {{/for}}
</ul>
  • Where it may stand: only where text goes, and it must end there too. Inside a tag, an attribute or a <script> it does not compile, because a partial is compiled on its own and could not be escaped for the place it lands in.
  • A name that does not exist fails the render with a message naming it. The visitor reads that the page failed, and a blueprint developer reads why.
  • A partial that includes itself fails at 48 levels deep with a message.
  • Only a layout's stylesheet and script are linked. Those fields of a partial are not, so put a partial's styles in the layout or the page.

For a small template used in one place only, keep it in the template itself:

A local partial
{{define "badge"}}<span class="badge">{{.}}</span>{{/define}}

<h1>{{title}} {{> badge status}}</h1>

A layout wraps the page

Set the layout pin of web_render to the template's name or GUID. The block's template_guid setting does the same when the pin is empty.

Layout template (type web, name main)
<!doctype html>
<html lang="{{language}}">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="{{viewport}}">
  {{{head}}}
</head>
<body>
  {{> site-header}}
  {{{body}}}
  {{> site-footer}}
</body>
</html>
  • {{{body}}} is the page, rendered first. {{{head}}} is where the generated head tags go. Without it they go right before </head>.
  • The layout sees the same data as the page: data, the custom pins, title, nonce and the rest.
  • The layout's own stylesheet and script are linked automatically, after the other head tags.
  • A name is looked up among web templates first and then among all others, so a mail layout can be a page's layout too.

Three ways a page gets its document

The render block hasThe document is
A layoutThe layout, with the page in {{{body}}}.
No layout, and a template that starts with <!doctype or <htmlYour template, whole.
No layout, and any other templateA plain HTML5 document around your template, with lang, charset and viewport set.

The head tags are written in all three. They go where {{{head}}} stands, else before </head>, else right after <head>. A tag your head already has is not written twice.

Every template can read the same variables

TemplateSees
The page and its layoutdata fields, custom pins, web, plus title, description, nonce, language, viewport and head. A layout also has body.
A web_templatedata fields, custom pins and web.
A row of web_foreachThe item's fields first, then data fields, custom pins and web.
A partialWhat the template around it sees, with the given value in front when you hand it one.

Template Syntax lists each variable.

Saving takes effect everywhere

Saving a template takes effect on every node at once. A template is compiled once per version of its text, so a new version never reuses an old compile. A brand new name is found within seconds: a name nobody has created is remembered as missing for 5 seconds, then looked for again.

Store what more than one flow renders

Store it

The header, the footer, a product card, a table row. The page's web_foreach and the action's web_template both say {{> order-row}}, so an edited row looks the same as a loaded one.

Copy it

The same row typed into the list block and into the action's render block. The first change you make to one of them is a bug the visitor sees only after they edit something.

Next steps

Lists and Tables Rows from a stored template, each with its own key. SEO and Sharing What goes into the head of every page. Email System Mail templates: the same template store and syntax, used for email.