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
<layout>.<format>.twig
index.<format>.twig
list.<format>.twig
_default/index.<format>.twig
_default/list.<format>.twig
_default/page.<format>.twig
page
<section>/<layout>.<format>.twig
<layout>.<format>.twig
<section>/page.<format>.twig
page.<format>.twig
_default/page.<format>.twig
section
<layout>.<format>.twig
<section>/list.<format>.twig
section/<section>.<format>.twig
_default/section.<format>.twig
_default/list.<format>.twig
vocabulary
taxonomy/<plural>.<format>.twig
_default/vocabulary.<format>.twig
term
taxonomy/<term>.<format>.twig
_default/term.<format>.twig
_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. |
site.menus
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 pathpath
: relative pathext
: extensiontype
: media type (e.g.:image
)subtype
: media sub type (e.g.:image/jpeg
)size
: size in octetssource
: content before compiling and/or minifyingcontent
: file contentintegrity
: integrity hashwidth
: image widthheight
: image heightaudio
: 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.