Layouts
With Sculpin, a layout is more or less a wrapper or shell around your pages
content. Layouts can technically live in any of the view directories
(_views
, _layouts
, _partials
, _includes
) but for the sake of consistency
it is best to place them either in _views
(if you only ever use the _views
directory for all of your templates) or in _layouts
.
For a layout to work, it must be able to render a Source's content
block. For
a Twig template, that means:
{% block content %}{% endblock %}
... or ...
{{ page.blocks.content }}
Inheritance and Sources
Many static site generators, including Jekyll and Phrozn, will render each source first, and inject the resulting output into the layout. While this approach (the "russian dolls" approach) is simpler, it means you end up losing the inheritance capabilities that are built into both Twig and Liquid.
Sculpin attempts to solve this problem by wrapping each source in a block named
content
. So, given the following file:
---
layout: default
---
# This is a markdown file with YAML frontmatter
Internally, Sculpin treats this file like the following:
{% extends "default" %}
{% block content %}
# This is a markdown file with YAML frontmatter
{% endblock %}
The end result is that each source file can be rendered together in one go rather than rendering the content by itself and injecting the content into the wrapper template. This means that additional data can be passed from the source into the wrapper template!
Given a source file like this:
---
layout: default
special_value: nice
---
# This is a markdown file with YAML frontmatter
One can reference the special_value
key in the default
template like this:
<html>
{% if page.special_value is defined %}
Special value exists and is <strong>{{ page.special_value }}</strong>!.
{% endif %}
{% block content %}Fallback content{% endblock %}
</html>
After rendering, the final result will be:
<html>
Special value exists and is <strong>nice</strong>!.
<h1>This is a markdown file with YAML frontmatter</h1>
</html>
Content Wrapper
When working with multiple levels of view inheritance, wrap page.blocks.content
or {% block content %}{% endblock %}
or {% block content '' %}
in a content_wrapper
block, like in this example _views/project.html
layout:
{% extends 'default' %}
{% block content_wrapper %}
<article>
<header>
<h2>{{ page.title }}</h2>
</header>
<section class="main_body">
{{ page.blocks.content }}
</section>
</article>
{% endblock %}
This will help ensure that inheritance properly applies, so that the content gets embedded in the project
view, which then gets embedded in the default
view.