Templates

Cecil use Twig as template engine, so refer to the official documentation for basic usage.

Example

<h1>{{ page.title }} | {{ site.title }}</h1>
<span>{{ page.date|date('j M Y') }}</span>
<p>{{ page.content }}</p>
<p>{{ page.customvar }}</p>

Files organization

Templates files are stored in layouts/.

<mywebsite>
├─ content
├─ layouts
|  ├─ _default           <- Contains default templates
|  |  ├─ list.html.twig  <- Used by "section" and "term" pages type
|  |  └─ page.html.twig  <- Used by "page" pages type
|  └─ index.html.twig    <- Used by the "homepage" type
└─ themes
   └─ <theme>            <- A custom theme
      ├─ layouts
      └─ ...

Lookup rules

Cecil searches for the best layout to use, for a given page, in a defined order.

In most of cases you don’t need to specify the template in layout variable: Cecil selects the most appropriate template for you.

Notes:

<format> is the output format (ie: html).
<layout> is the value of variable layout set in front matter (ie: layout: post).
<section> is the page’s Section (ie: blog).

homepage

  1. <layout>.<format>.twig
  2. index.<format>.twig
  3. _default/list.<format>.twig
  4. _default/page.<format>.twig

page

  1. <section>/<layout>.<format>.twig
  2. <layout>.<format>.twig
  3. <section>/page.<format>.twig
  4. page.<format>.twig
  5. _default/page.<format>.twig

section

  1. section/<section>.<format>.twig
  2. _default/section.<format>.twig
  3. _default/list.<format>.twig

vocabulary

  1. taxonomy/<plural>.<format>.twig
  2. _default/vocabulary.<format>.twig

term

  1. taxonomy/<term>.<format>.twig
  2. _default/term.<format>.twig
  3. _default/list.<format>.twig

Variables

site

Contains all variables from the configuration file (config.yml).

Example:

title: "My amazing website !" is printed in a template with {{ site.title }}.

Built-in variables

Variable Description
site.pages Collection of (published) pages.
site.pages.all Collection of (non-virtual) pages.
site.taxonomies Collection of vocabularies.
site.language Language code (default: en).
site.time Timestamp of the last generation.

site.menus

Loop on site.menus.<key> to get each entry of <key>.

<key> is the identifier of the menu collection (ie: main).

Variable Description
<entry>.name Menu entry name.
<entry>.url Menu entry URL (relative or absolute).
<entry>.weight Menu entry weight (useful to sort menu entries).

site.static

The static files collection can be accessed via site.static.

Available if static load is enabled

Each file has the following properties:

  • path: relative path (ie: /images/img-1.jpg)
  • date: creation date (timestamp)
  • updated: modification date (timestamp)
  • name: name (ie: img-1.jpg)
  • basename: name without extension (ie: img-1)
  • ext: extension (ie: jpg)

site.data

A data collection can be accessed via site.data.<filename> (without file extension).

Example:

  • data/authors.yml : site.data.authors
  • data/galleries/gallery-1.json : site.data.galleries.gallery-1

site.language

Experimental

Variable Description
site.language.name Language full name (ie: English).
site.language.locale Language locale code (ie: en_EN).
site.language.weight Language position in languages list.

page

Contains variables of the current Page and those set in the front matter.

Variable Description Example
page.id Unique identifier. blog/post-1
page.title File name (without extension). Post 1
page.date File creation date. DateTime
page.updated File modification date. DateTime
page.body File body. Markdown
page.content File body converted in HTML. HTML
page.section File root folder (slugified). blog
page.path File path (slugified). blog/post-1
page.slug File name (slugified). post-1
page.tags Array of tags. [Tag 1, Tag 2]
page.categories Array of categories. [Category 1, Category 2]
page.pages Subpages. Collection
page.type homepage, page, section, vocabulary or term page
page.filepath File system path. Blog/Post 1.md

page.<prev/next>

Navigation between pages of a section.

Variable Description
page.<prev/next>.id ID of the previous / next page (ie: blog/post-2).
page.<prev/next>.path Path of the previous / next page (ie: blog/post-2).
page.<prev/next>.title Title of the previous / next page (ie: Post 2).

page.pagination

Variable Description
page.pagination.totalpages Paginated total pages.
page.pagination.pages Paginated pages collection.
page.pagination.current Number of the current page.
page.pagination.count Number of the last page.
page.pagination.links.self ID of the current page.
page.pagination.links.first ID of the first page.
page.pagination.links.prev ID of the previous page.
page.pagination.links.next ID of the next page.
page.pagination.links.last ID of the last page.

Taxonomy

Variables available in vocabulary and term layouts.

Vocabulary
Variable Description
page.plural Vocabulary name (plural form).
page.singular Vocabulary name (singular form).
page.terms List of terms (Collection).
Term
Variable Description
page.term Term ID.
page.pages List of pages in this term (Collection).

cecil

Variable Description
cecil.url URL to the official website.
cecil.version Cecil current version.
cecil.poweredby Print Cecil v%s with %s is the current version.

Functions

url

Turns a Page, a Page ID or a path into an URL.

{{ url(Page|page-id|path,{options}) }}
Option Description Type Default
canonical Prefixes URL with baseurl. boolean false
format Page output format (ie: json). string html

Examples:

{{ url(page) }}
{{ url('page-id') }}
{{ url(menu.url|url) }}
{{ usrl('tags/'~tag) }}

Prefer the url filter for assets.

asset

Creates an asset (CSS, JavaScript, media file) from a file path or an array (bundle) of files path.

{{ asset(path|[paths],{options}) }}
Option Description Type Default
fingerprint Add the file content finger print to the file name. boolean true
minify Compress file content (CSS or JavaScript). boolean true
filename File to save as a bundle. string
ignore_missing Ignore if file don't exists. boolean false

See assets configuration for default configuration.

Examples:

{{ asset('styles.css') }}
{{ asset('scripts.js',{minify:false}) }}
{{ asset('image.png',{fingerprint:false}) }}
{{ asset(['poole.css','hyde.css'],{filename:styles.css}) }}

Notes:

Uses filters to manipulate assets:

{{ asset('styles.scss')|inline }}
{{ asset('styles.scss')|html }}

You must use the url filter to save an asset:

{{ asset('styles.css')|minify|url }}

Get integrity:

{% set integrity = asset('styles.scss').integrity %}

See the integrity function.

integrity

Returns the hash (sha384) of a file.

{{ integrity(Asset|path) }}

Used for SRI (Subresource Integrity).

Examples:

{{ integrity('styles.css') }}

readtime

Returns read time, in minutes.

{{ readtime(string) }}

Example:

{{ readtime(page.content) }} min

getenv

Gets the value of an environment variable.

{{ getenv(key) }}

Example:

{{ getenv('VAR') }}

Sorts

sort_by_title

Sorts a collection (Pages) by title (with natural sort).

{{ <collection>|sort_by_title }}

sort_by_date

Sorts a collection (Pages) by date (most recent first).

{{ <collection>|sort_by_date }}

sort_by_weight

Sorts a collection (Pages or Menu) by weight (lighter first).

{{ <collection>|sort_by_weight }}

sort

For more complex cases, you should use Twig's native sort:

{% set files = site.static|sort((a, b) => a.date|date('U') < b.date|date('U')) if file.path matches '/^photos/' %}

Filters

filter_by

Filters a pages collection by variable name/value.

{{ <collection>|filter_by(variable, value) }}

Example:

{{ pages|filter_by('section', 'blog') }}

filter

For more complex cases, you should use Twig's native filter:

{% pages|filter(p => p.virtual == false and p.id not in ['404', 'robots', 'sitemap']) %}

url

Turns a Page, an Asset or a path into an URL.

{{ <Page|Asset|path>|url({options}) }}
Option Description Type Default
canonical Prefixes with baseurl. boolean false
format Defines Page output format (ie: json). string html

Examples:

{{ page|url }}
{{ asset('styles.css')|url({canonical:true}) }}

html

Turns an asset into an HTML element.

{{ asset(path)|html }}

Available for CSS, JavaScript and image file.

Option Description Type Default
attributes Adds name="value" couple to the HTML element. string

Example:

{{ asset('image.png')|html({title:'Title',alt:'Alternative'}) }}

inline

Outputs the content of an asset.

{{ asset(path)|inline }}

Example:

{{ asset('styles.css')|inline }}

markdown_to_html

Converts a Markdown string to HTML.

{{ markdown|markdown_to_html }}
{% apply markdown_to_html %}
{# Markdown here #}
{% endapply %}

Example:

{% set markdown = '**This is bold text**' %}
{{ markdown|markdown_to_html }}
{% apply markdown_to_html %}
**This is bold text**
{% endapply %}

to_css

Compiles a Sass file (to CSS).

{{ asset(path)|to_css }}
{{ path|to_css }}

Example:

{{ asset('styles.scss')|to_css }}
{{ 'styles.scss'|to_css }} {# deprecated #}

minify

Minifying a CSS or a JavaScript file.

{{ asset(path)|minify }}
{{ path|minify }} {# deprecated #}

Examples:

{{ asset('styles.css')|minify }}
{{ 'styles.css'|minify }} {# deprecated #}
{{ asset('scripts.js')|minify }}

minify_css

Minifying CSS.

{{ variable|minify_css }}
{% apply minify_css %}
{# CSS here #}
{% endapply %}

Examples:

{% set styles = 'some CSS here' %}
{{ styles|minify_css }}
<style>
{% apply minify_css %}
  html {
    background-color: #fcfcfc;
    color: #444;
  }
{% endapply %}
</style>

minify_js

Minifying JavaScript.

{{ variable|minify_js }}
{% apply minify_js %}
{# JavaScript here #}
{% endapply %}

Examples:

{% set script = 'some JavaScript here' %}
{{ script|minify_js }}
<script>
{% apply minify_js %}
  var test = 'test';
  console.log(test);
{% endapply %}
</script>

scss_to_css

Compiles a Sass (to CSS).

{{ variable|scss_to_css }}
{% apply scss_to_css %}
{# SCSS here #}
{% endapply %}

Example:

{% set scss = 'some SCSS here' %}
{{ scss|scss_to_css }}
<style>
{% apply scss_to_css %}
  $color: #fcfcfc;
  div {
    color: lighten($color, 20%);
  }
{% endapply %}
</style>

Alias: sass_to_css.

resize

Experimental

Resizes an image to a specified with.

{{ <image_path>|resize(integer) }}

Ratio is preserved, the original file is not altered and the resized version is stored in /images/thumbs/<resize>/path/to/image/.

Example:

{{ page.image|resize(300) }}

slugify

Converts a string to a slug.

{{ string|slugify }}

excerpt

Truncates a string and appends suffix.

{{ string|excerpt(integer,suffix) }}
Option Description Type Default
length Truncates after this number of characters. integer 450
suffix Appends characters. string

Examples:

{{ variable|excerpt }}
{{ variable|excerpt(250,'...') }}

excerpt_html

Reads characters before <!-- excerpt --> or <!-- break -->.

{{ string|excerpt_html }}

Built-in templates

Cecil comes with a set of built-in templates.

Default templates

_default/page.html.twig
A very simple default main template with a clean CSS.
_default/list.html.twig
A pages list with pagination.
_default/vocabulary.html.twig
A basic list of all terms of a vocabulary.
_default/list.atom.twig
A clean Atom feed for sections.
_default/list.rss.twig
A clean RSS feed for sections.

Utility templates

robots.txt.twig
The robots.txt template: allow all pages except 404, with a reference to the XML sitemap.
sitemap.xml.twig
The sitemap.xml template: list all pages sorted by date.

Component templates

partials/pagination.html.twig
A simple pagination component for list templates with "Older" and "Newer" links.
partials/metatags.html.twig
All metatags in one component: title, description, canonical, open-graph, twitter card, etc.
partials/googleanalytics.js.twig
Google Analytics traking script.

Internationalization

Experimental

Cecil support text translation and date localization through Twig Extensions.

Translation

{% trans "Publication date:" %}

See https://twig-extensions.readthedocs.io/en/latest/i18n.html.

Translation files (.mo) must be stored in the right directory of your project:

<mywebsite>
└─ locale
   └─ fr_FR              <- Language code
      └─ LC_MESSAGES
         ├─ messages.mo  <- Compiled translation file
         └─ messages.po  <- Translation file

This extension required Gettext.

Localization

{{ page.date|localizeddate('long', 'none') }}

See https://twig-extensions.readthedocs.io/en/latest/intl.html.

This extension required intl.

Suggest a modification

Content Configuration

Table of contents