Cecil logo

Templates

Cecil is powered by the Twig template engine, so refer to the official documentation to learn how to use it.

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 with the layout variable: Cecil selects the most appropriate template for you.

homepage

  1. <layout>.<format>.twig
  2. index.<format>.twig
  3. list.<format>.twig
  4. _default/index.<format>.twig
  5. _default/list.<format>.twig
  6. _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. <layout>.<format>.twig
  2. <section>/list.<format>.twig
  3. section/<section>.<format>.twig
  4. _default/section.<format>.twig
  5. _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

You can use variables from different scopes (site, page, etc.) in templates.

site

Contains all variables from the configuration file (config.yml) and some built-in variables.

Example:

title: "My amazing website!"

Can be displayed in a template with:

{{ site.title }}

Built-in variables

Variable Description
site.home ID of the home page.
site.pages Collection of pages, in the current language.
site.pages.showable site.pages with "showable" pages only (published and not virtual/redirect/excluded).
site.page('id') A specific page in the current language.
site.allpages Collection of pages, regardless of their language.
site.taxonomies Collection of vocabularies.
site.time Timestamp of the last generation.

Loop on site.menus.<menu> to get each entry of the <menu> collection (e.g.: main).

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

site.language

Informations about the current language.

Variable Description
site.language Language code (e.g.: en).
site.language.name Language name (e.g.: English).
site.language.locale Language locale code (e.g.: en_EN).
site.language.weight Language position in the languages list.

You can retrieve name, locale and weight of a language different from the current one by passing its code as a parameter, ie: site.language.name('fr').

site.static

The static files collection can be accessed via site.static (if static load is enabled).

Each file exposes the following properties:

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

site.data

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

Examples:

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

page

Contains variables of the 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 Collection of all sub pages. Collection
page.pages.showable page.pages with "showable" pages only. Collection
page.type homepage, page, section, vocabulary or term. page
page.filepath File system path. Blog/Post 1.md
page.translations Collection of translated pages. Collection

page.<prev/next>

Navigation between pages in a same Section.

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

page.pagination

Pagination is avaialable for homepage, sections, and taxonomies.

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

Taxonomy

Variables available in vocabulary and term layouts.

Vocabulary
Variable Description
page.plural Vocabulary name in plural form.
page.singular Vocabulary name in 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 of the official website.
cecil.version Cecil current version.
cecil.poweredby Print Cecil v%s with %s is the current version.

Functions

Functions can be called to generate content.
Functions are called by their name followed by parentheses and may have arguments.

url

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

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

For assets prefer the url filter.

Examples:

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

asset

Creates an asset (CSS, JavaScript, image, audio, etc.) from a file path, an URL or an array of files path (bundle).

{{ asset(path|url|[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 where to save content. string
ignore_missing Do not stop build if file don't exists. boolean false

See assets configuration to define the global behavior.
Uses filters to manipulate assets.

Examples:

{{ asset('styles.css')|minify }}
{{ asset('styles.scss')|inline }}
{{ asset('scripts.js', {minify: false}) }}
{{ asset('image.png', {fingerprint: false}) }}
{{ asset(['poole.css', 'hyde.css'], {filename: styles.css}) }}
{{ asset('https://cdnjs.cloudflare.com/ajax/libs/anchor-js/4.3.1/anchor.min.js') }}

Attributes

  • file: filesystem path
  • path: relative path
  • ext: extension
  • type: media type (e.g.: image)
  • subtype: media sub type (e.g.: image/jpeg)
  • size: size in octets
  • source: content before compiling and/or minifying
  • content: file content
  • integrity: integrity hash
  • width: image width
  • height: image height
  • audio: Mp3Info

Examples:

{{ asset('image.png').width }}px
{{ asset('title.mp3').audio.duration|round }} min
{% set integrity = asset('styles.scss').integrity %}

integrity

Returns the hash (sha384) of a file.

{{ integrity(Asset|path) }}

Used for SRI (Subresource Integrity).

Example:

{{ 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

Sorting collections (Pages, Menus, Taxonomies).

sort_by_title

Sorts a collection by title (with natural sort).

{{ <collection>|sort_by_title }}

sort_by_date

Sorts a collection by date (most recent first).

{{ <collection>|sort_by_date }}

sort_by_weight

Sorts a collection by weight (lighter first).

{{ <collection>|sort_by_weight }}

sort

For more complex cases, you should use Twig’s native sort.

Example:

{% set files = site.static|sort((a, b) => a.date|date('U') < b.date|date('U')) %}

Filters

Filters allow you to modify a variable’s data before you use it:

{{ page.title|capitalize }}

You can chain filters to perform severals alterations at once:

{{ page.title|truncate(25)|capitalize }}

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.

Example:

{% pages|filter(p => p.virtual == false and p.id not in ['page-1', 'page-2']) %}

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 (e.g.: json). string html

Examples:

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

markdown_to_html

Converts a Markdown string to HTML.

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

Examples:

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

json_decode

Converts a JSON string to an array.

{{ json|json_decode }}

Example:

{% set json = '{"foo": "bar"}' %}
{% set array = json|json_decode %}
{{ array.foo }}

yaml_parse

Converts a YAML string to an array.

{{ yaml|yaml_parse }}

Example:

{% set yaml = 'key: value' %}
{% set array = yaml|yaml_parse %}
{{ array.key }}

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 --> tag.

{{ string|excerpt_html(separator, capture) }}
Option Description Type Default
separator String to use as separator. string excerpt|break
capture Capture characters before or after the separator. string before

Examples:

{{ variable|excerpt_html }}
{{ variable|excerpt_html('excerpt|break', 'before') }}

to_css

Compiles a Sass file (to CSS).

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

Examples:

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

fingerprint

Add the file content finger print to the file name.

{{ asset(path)|fingerprint }}
{{ path|fingerprint }}

Examples:

{{ asset('styles.css')|fingerprint }}
{{ 'styles.css'|fingerprint }} {# 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 a CSS string.

{{ 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 a JavaScript string.

{{ 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 string (to CSS).

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

Alias: sass_to_css.

Examples:

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

resize

Resizes an image to a specified with.

{{ asset(image_path)|resize(integer) }}
{{ <image_path>|resize(integer) }} {# deprecated #}

Ratio is preserved, the original file is not altered and the resized version is stored in /assets/thumbnails/<integer>/images/image.jpg.

Example:

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

dataurl

Returns the data URL of an image.

{{ asset(image_path)|dataurl }}

inline

Outputs the content of an Asset.

{{ asset(path)|inline }}

Example:

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

html

Turns an asset into an HTML element.

{{ asset(path)|html({attributes, options}) }}
Option Description Type Default
attributes Adds name="value" couple to the HTML element. array
options {responsive: true}: creates responsives images.
{webp: true}: creates WebP versions of the image.
{preload: true}: preloads CSS.
array

Examples:

{{ asset('image.png')|html }}
{{ asset('image.jpg')|html({alt: 'Description', loading: 'lazy'}, {responsive: true, webp: true}) }}
{{ asset('styles.css')|html({media: print}) }}
{{ asset('styles.css')|html({title: 'Main theme'}, {preload: true}) }}

preg_split

Split a string into an array using a regular expression.

{{ string|preg_split(pattern, limit) }}

Example:

{% set headers = page.content|preg_split('/<h3[^>]*>/') %}

preg_match_all

Perform a regular expression match and return the group for all matches.

{{ string|preg_match_all(pattern, group) }}

Example:

{% set tags = page.content|preg_match_all('/<[^>]+>(.*)<\\/[^>]+>/') %}

hex_to_rgb

Converts a hexadecimal color to RGB.

{{ color|hex_to_rgb }}

Localization

Cecil support text translation and date localization through Twig Extensions.

Text translation

Uses the trans tag to translate a text in templates.

{% trans "Publication date:" %}
{% trans variable %}
{% trans %}
  Hello World!
{% endtrans %}

In a translatable string, you can embed variables:

{% trans %}
  Hello {{ name }}!
{% endtrans %}

To pluralize a translatable string, use the plural block:

{% trans %}
  Hey {{ name }}, I have one apple.
{% plural apple_count %}
  Hey {{ name }}, I have {{ count }} apples.
{% endtrans %}

The plural tag should provide the count used to select the right string. Within the translatable string, the special count variable always contain the count value (here the value of apple_count).

To add notes for translators, use the notes block:

{% trans %}
  Hey {{ name }}, I have one apple.
{% plural apple_count %}
  Hey {{ name }}, I have {{ count }} apples.
{% notes %}
  This is shown in the user menu. This string should be shorter than 30 chars
{% endtrans %}

You can use notes with or without plural.

Within an expression or in a tag, you can use the trans filter to translate simple strings or variables:

{{ variable|default(default_value|trans) }}

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

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

I recommends Poedit Pro to easily translate your templates.

Gettext PHP extension is required. See the i18n Extension documentation.

Date localization

Uses the localizeddate filter to localize a date in templates.

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

Intl PHP extension is required. See the Intl Extension documentation.

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.

Partial templates

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

Suggest a modification