Skip to content

Search tags, filters, functions and guides.

Tags / extends and block

Tags

extends and block

Share a layout between pages.

Layouts hold the markup that pages share. A layout defines named block sections, and a page extends the layout and fills them in.

page.kiln
{% extends "layouts/base" %}

{% block title %}{{ page.title }} | {{ parent() }}{% endblock %}

{% block content %}
	<h1>{{ page.title }}</h1>
{% endblock %}
layouts/base.kiln
<title>{% block title %}{{ site.name }}{% endblock %}</title>
<main>
	{% block content %}{% endblock %}
</main>
Output
<title>About us | Example</title>
<main>
	<h1>About us</h1>
</main>

Pages

  • extends must be the first tag in the template.
  • The name can be any expression, such as layout ?? "layouts/base".
  • Outside blocks, a page can only contain set, props, import, from, macro and comments. Anything else is an error, because it would never be shown.
  • Top-level set tags run before the layout renders. The layout and every block can use their variables. When they wait for async data, the parts of the layout that don't use them start straight away.

Blocks

  • Block names must be unique within a template.
  • {% endblock title %} may repeat the name. If it does, it must match.
  • {% block title page.title %} is a short form for a block that holds one expression.
  • Layouts can extend other layouts, as deep as you need.

Reusing blocks

parent() outputs the layout's version of the current block. block("name") outputs another block of the current template again, and block("name") is defined checks that it exists.

<meta property="og:title" content="{{ block("title") }}">

{% if block("sidebar") is defined %}
	<aside>{{ block("sidebar") }}</aside>
{% endif %}

To render one block on its own, such as a fragment for a partial page update, see renderBlock.