Table of Contents
Zola tips
Things that are easy to miss when developing for Zola.
Use the "safe" filter in templates
You need to pass {{ page.contents }}
through the safe
filter, thus:
{{ page.contents | safe}}
Content that isn't marked as safe
will have its HTML converted to entities, e.g. <h1>
becomes <h1>
.
Sections and _index.md
This scheme seems like it's more complicated than it needs to be.
When you create a folder for organizing content, think of it as a section. A section of your website typically has an index page and a number of sub-pages. In Zola, the content for the section's index page is specified in _index.md
. Other pages have regular names.
_index.md
has special access to information about the section's sub-pages. The typical use case for this is listing blog entries. Also, _index.md
files can (should? must?) specify not just the template they will use but also the (default?) template page used by sub-pages.
You don't need to have a _index.md
file in a folder (except the root—see below). If you don't, Zola does not formally consider it a section, but the pages defined in it are still accessible. You can define an index.md
file in a folder if you don't need the abilities of a section.
You can nest sections.
The homepage
The root is also regarded as a section and can have an _index.md
file in it. This specifies the content of your homepage. However, unlike other sections, the root is a section whether or not you define a _index.md
file in it.
Section templates
With _index.md
files, you access variables (title
, content
, etc.) in templates using section
instead of page
:
{{ page.content | safe }} {# for regular files #} {{ section.content | safe }} {# for _index.md files #}
This means you'll need different templates (and base templates!) for section pages and regular pages! As an alternative, you can use some logic in the template:
<title> {% if page.title %} {{ page.title }} {% else %} {{ section.title }} {% endif %} </title>
Better yet, use the following idiom to set current
to the current context, either section
or page
:
{% set current = section | default(value=page) %} {{ current.title }}
It looks like the root _index.md
file can use a template named something other than index.html
. Similarly, it looks like non-root _index.md
files can use templates named index.html
.
Custom front matter variables
Custom front matter variables are placed in the [extra]
array:
[extra] image = "assets/img/12AT7-lum.jpg"
In templates, you can access elements using dot notation:
{{ section.extra.image }}
Kludging content segments
Many CMSes and some SSGs let you define segments of content that are rendered into named portions in a template.
--- title: Home --- ---heading--- Custom made noise ================= ---lead--- I build what fashionable people call boutique amplifiers. ---body--- Professionally crafted. With heaps of love and soul. [Take a look.]({{pcurl('products')}})
It doesn't look like Zola lets you do this. However, you can kludge this using front matter.
+++ ... [extra] heading = "# Custom made noise" lead = "I build what fashionable people call _boutique amplifiers_." +++ Professionally crafted with heaps of love and soul. [Take a look.](/products)
And in the template:
{{ section.extra.heading | markdown(inline=true) | safe }} <div class="lead"> {{ section.extra.lead | markdown | safe }} </div> {{ section.content | safe }} {{ section.extra.image }}
Marking a menu item as active
There may be a better way to do this, but selectively adding a class if the relative path matches seems to work.
<ul class="nav navbar-nav navbar-right"> {# for each of the menu entries, if the relative path leads matches the page, add class="active" #} {% set current = section | default(value=page) %} {% set rpath = current.relative_path %} <li {% if rpath == "_index.md" %} class="active"{% endif %}><a href="/">Home</a></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown">Products <span class="caret"></span></a> <ul class="dropdown-menu" role="menu"> <li {% if rpath == "products/_index.md" %} class="active"{% endif %}><a href="/products">Overview</a></li> <li {% if rpath == "products/upcycled.md" %} class="active"{% endif %}><a href="/products/upcycled">Upcycled amps</a></li> <li {% if rpath == "products/classic.md" %} class="active"{% endif %}><a href="/products/classic">Classic amps</a></li> </ul> </li> <li {% if rpath == "about.md" %} class="active"{% endif %}><a href="/about">About</a></li> <li {% if rpath == "contact.md" %} class="active"{% endif %}><a href="/contact">Contact</a></li> </ul>
No doubt, there are opportunities to stuff some of this into macros and/or partials and/or similar.
Breadcrumbs
See this forum post, reproduced and re-formatted here in case it goes away:
{% block breadcrumb %} <div class="breadcrumb-container"> <a class="breadcrumb-path" href="/">Home</a> {% set current = section | default(value=page) %} {% for ancestor in current.ancestors %} {% if loop.first %} {% continue %} {% endif %} <span class="breadcrumb-separator">/</span> {% set section = get_section(path=ancestor) %} <a class="breadcrumb-path" href="{{ section.permalink }}">{{ section.title }}</a> {% endfor %} <span class="breadcrumb-separator">/</span> <a class="breadcrumb-path active" href="{{ current.permalink }}">{{ current.title }}</a> </div> {% endblock breadcrumb %}