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.
{
"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.
A partial is a shared piece
Print it with {{> name}}. It sees the data around it, or the value you hand it:
{{> 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:
{{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.
<!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,nonceand 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 has | The document is |
|---|---|
| A layout | The layout, with the page in {{{body}}}. |
No layout, and a template that starts with <!doctype or <html | Your template, whole. |
| No layout, and any other template | A 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
| Template | Sees |
|---|---|
| The page and its layout | data fields, custom pins, web, plus title, description, nonce, language, viewport and head. A layout also has body. |
A web_template | data fields, custom pins and web. |
A row of web_foreach | The item's fields first, then data fields, custom pins and web. |
| A partial | What 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.