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 &lt;h1&gt;.

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.

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 %}