Cecil logo
What's on this page

Content

There is different kinds of content in Cecil:

Pages
Pages are the main content of the site, written in Markdown.
Assets
Assets are manipulated files (i.e.: resized images, compiled Sass, minified scripts, etc.).
Static files
Static files are copied as is in the generated site.
Data files
Data files are custom variables collections.

Files organization

File system tree

Project files organization.

<mywebsite>
├─ pages
|  ├─ blog            <- Section
|  |  ├─ post-1.md    <- Page in Section
|  |  └─ post-2.md
|  ├─ projects
|  |  └─ project-1.md
|  └─ about.md        <- Root page
├─ assets
|  ├─ styles.scss     <- Asset file
|  └─ logo.png
├─ static
|  └─ file.pdf        <- Static file
└─ data
   └─ authors.yml     <- Data collection

Built website tree

Result of the build.

<mywebsite>
└─ _site
   ├─ index.html               <- Generated home page
   ├─ blog/
   |  ├─ index.html            <- Generated list of posts
   |  ├─ post-1/index.html     <- A blog post
   |  └─ post-2/index.html
   ├─ projects/
   |  ├─ index.html
   |  └─ project-1/index.html
   ├─ about/index.html
   ├─ styles.css
   ├─ logo.png
   └─ file.pdf

File based routing

Markdown files in the pages directory enable file based routing. Meaning that adding a pages/my-projects/project-1.md for instance will make it available at /project-1 in your browser.

File:
                   pages/my-projects/project-1.md
                        └───── filepath ──────┘
URL:
    ┌───── baseurl ─────┬─────── path ────────┐
     https://example.com/my-projects/project-1/index.html
                        └─ section ─┴─ slug ──┘

Pages

A page is a file made up of a front matter and a body.

Front matter

The front matter is a collection of variables (in key/value format) surrounded by ---.

Example:

---
title: "The title"
date: 2019-02-21
tags: [tag 1, tag 2]
customvar: "Value of customvar"
---

Body

Body is the main content of a page, it could be written in Markdown or in plain text.

Example:

# Header

[toc]

## Sub-Header 1

Lorem ipsum dolor [sit amet](https://example.com), consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
<!-- excerpt -->
Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.

## Sub-Header 2

![Description](/image.jpg "Title")

## Sub-Header 3

:::tip
This is an advice.
:::

Markdown

Cecil supports Markdown format, but also Markdown Extra.

Cecil also provides extra features to enhance your content, see below.

Attributes

With Markdown Extra you can set an id, class and custom attributes on certain elements using an attribute block.
For instance, put the desired attribute(s) after a header, a fenced code block, a link or an image at the end of the line inside curly brackets, like this:

## Header {#id .class attribute=value}

You can create a link with the syntax [Text](url) with "url" can be a path, a relative path to a Markdown file, an external URL, etc.

Example:

[Link to a path](/about/)
[Link to a Markdown file](../about.md)
[Link to Cecil website](https://cecil.app)

You can easily create a link to a page with the syntax [Page title](page:page-id).

Example:

[Link to a blog post](page:blog/post-1)

You can let Cecil tries to turns a link into an embedded content by using the {embed=true} attribute or by setting the global configuration option body.links.embed.enabled to true.

Example:

[An example YouTube video](https://www.youtube.com/watch?v=Dj-rKHmLp5w){embed=true}

Cecil can also create a video or audio HTML elements, through the file extension.

Video

Example:

[The video](/video/test.mp4){controls poster=/images/video-test.png style="width:100%;"}

Is converted to:

<video src="/video/test.mp4" controls poster="/images/video-test.png" style="width:100%;"></video>
Audio

Example:

[The audio file](/audio/test.mp3){controls}

Is converted to:

<audio src="/video/test.mp3" controls></audio>

Images

To add an image, use an exclamation mark (!) followed by alternative description in brackets ([]), and the path or URL to the image in parentheses (()).
You can optionally add a title in quotation marks.

![Alternative description](/image.jpg "Image title")

Lazy loading

By default Cecil apply the attribute loading="lazy" on each images.

Example:

![](/image.jpg)

Is converted to:

<img src="/image.jpg" loading="lazy">

Resize

Each image in the body can be resized by setting a smaller width than the original one with the extra attribute {width=X} (the resize option in the body configuration must be enabled).

Example:

![](/image.jpg){width=800}

Is converted to:

<img src="/assets/thumbnails/800/image.jpg" width="800" height="600">

Responsive

If the responsive option in the body configuration is enabled, then all images in the body will be automatically responsived.

Example:

![](/image.jpg){width=800}

If resize and responsive options are enabled, then this Markdown line will be converted to:

<img src="/assets/thumbnails/800/image.jpg" width="800" height="600"
  srcset="/assets/thumbnails/320/image.jpg 320w,
          /assets/thumbnails/640/image.jpg 640w,
          /assets/thumbnails/800/image.jpg 800w"
  sizes="100vw"
>

The sizes attribute take the value of the assets.images.responsive.sizes.default configuration option by default, and can be customized by creating a new entry named with the class name added to the image.

Example:

assets:
  images:
    responsive:
      sizes:
        default: 100vw
        my_class: "(max-width: 800px) 768px, 1024px"
![](/image.jpg){.my_class}

WebP

If the webp option in the body configuration is enabled, an alterative image in the WebP format is created.

Example:

![](/image.jpg)

Is converted to:

<picture>
  <source srcset="/image.webp" type="image/webp">
  <img src="/image.jpg">
</picture>

Caption

You can automatically add a caption (figcaption) to an image with the optional title.

Example:

![](/images/img.jpg "Title")

Is converted to:

<figure>
  <img src="/image.jpg" title="Title">
  <figcaption>Title</figcaption>
</figure>

Table of contents

You can add a table of contents with the following Markdown syntax:

[toc]

Excerpt

An excerpt can be defined in the body with one of those following tags: excerpt or break.

Example:

Introduction.
<!-- excerpt -->
Main content.

Notes

Create a Note block (info, tips, important, etc.).

Example:

:::tip
**Tip:** This is an advice.
:::

Is converted to:

<aside class="note note-tip">
  <p>
    <strong>Tip:</strong> This is an advice.
  </p>
</aside>

Syntax highlight

Enables code block syntax highlighter by setting the body.highlight.enabled option to true.

Example:

```php
echo "Hello world";
```

Is rendered to:

echo "Hello world";

Inserted text

Represents a range of text that has been added.

++text++

Is converted to:

<ins>text</ins>

Variables

The front matter can contains custom variables applied to the current page.

It must be the first thing in the file and must be a valid YAML.

Predefined variables

Variable Description Default value Example
title Title File name without extension. Post 1
layout Template See Lookup rules. 404
date Creation date File creation date (PHP DateTime object). 2019/04/15
updated Modification date File modification date (PHP DateTime object). 2021/11/19
section Section Page's Section. blog
path Path Page's path. blog/post-1
slug Slug Page's slug. post-1
published Published or not true. false
draft Published or not false. true

A page can be added to a menu.

A same page could be added to severals menus, and the position of each entry can be defined with the weight key (the lightest first).

See Menus configuration for details.

Examples:

---
menu: main
---
---
menu: [main, navigation]
---
---
menu:
  main:
    weight: 10
  navigation:
    weight: 20
---

Taxonomy

Taxonomies are declared in the Configuration.

A page can contain several vocabularies (e.g.: tags) and terms (e.g.: Tag 1).

Example:

---
tags: ["Tag 1", "Tag 2"]
---

Schedule

Schedules pages’ publication.

Example:

The page will be published if current date is >= 2023-02-07:

schedule:
  publish: 2023-02-07

This page is published if current date is <= 2022-04-28:

schedule:
  expiry: 2022-04-28

redirect

As indicated by its name, the redirect variable is used to redirect a page to a dedicated URL.

Example:

---
redirect: "https://arnaudligny.fr"
---

alias

Alias is a redirection to the current page

Example:

---
title: "About"
alias:
  - contact
---

In the previous example contact/ redirects to about/.

output

Defines the output (rendred) format(s). See formats configuration for more details.

Example:

---
output: [html, atom]
---

external

A page with an external variable try to fetch the content of the pointed resource.

Example:

---
external: "https://raw.githubusercontent.com/Cecilapp/Cecil/master/README.md"
---

File prefix

The filename can contain a prefix to define date or weight of the page (used by sortby).

date

The date prefix is used to set the date of the page, and must be a valid date format (i.e.: « YYYY-MM-DD »).

Example:

In « 2019-04-23-My blog post.md »:

  • the prefix is « 2019-04-23 »
  • the date of the page is « 2019-04-23 »
  • the title of the page is « My blog post »

weight

The weight prefix is used to set the sort order of the page, and must be a valid integer value.

Example:

In « 1-The first project.md »:

  • the prefix is « 1 »
  • the weight of the page is « 1 »
  • the title of the page is « The first project »

Section

Some dedicated variables can be used in a custom Section (i.e.: <section>/index.md).

sortby

The order of pages in a Section can be changed.

Available values are:

  • date: more recent first
  • title: alphabetic order
  • weight: lightest first

Example:

---
sortby: title
---

Options:

---
sortby:
  variable: date    # date, updated, title or weight
  desc_title: false # used with date or updated variable to sort by desc title order if items have same date
  reverse: false    # reversed if true
---

pagination

Global pagination configuration can be overridden in each Section.

Example:

---
pagination:
  max: 5
  path: "page"
---

cascade

Any variables in cascade are added to the front matter of all sub pages.

Example:

---
cascade:
  banner: image.jpg
---

circular

Set circular to true to enable circular pagination with page.<prev/next>.

Example:

---
circular: true
---

Home page

Like another section, Home page support sortby and pagination configuration.

pagesfrom

Set a valid Section name in pagesfrom to use pages collection from this Section in Home page.

exclude

Set exclude to true to hide a page from list pages (i.e.: Home page, Section, Sitemap, etc.).

Example:

---
exclude: true
---

Multilingual

If your pages are available in multiple languages there is 2 differents ways to define it:

Language in the file name

This is the common way when you want to translate a page from the main language to others languages.

So you just need to duplicate the reference page and suffix it with the target language code (e.g.: fr).

Example:

├─ about.md    # the reference page in english (`en`)
└─ about.fr.md # the french version (`fr`)

Language in the front matter

If you want to create a page in a language other than the main language, without it being a translation of an existing page, you can use the language variable in its front matter.

Example:

---
language: fr
---

Each translated page reference the pages in others languages.

Those pages collection is available in templates with the following variable:

{{ page.translations }}

Dynamic content

With this experimental feature you can use variables and shortcodes in the body.

Display variables

Front matter variables can be use in the body with the template’s syntax {{ page.variable }}.

Example:

--
var: 'value'
---
The value of `var` is {{ page.var }}.

Experimental

Shortcodes

Shortcodes are helpers to create dynamic content.

Experimental

Built-in shortcodes

2 shortcodes are available by default:

YouTube
{{ shortcode.youtube(id) }}
  • id: YouTube video ID

Example:

{{ shortcode.youtube('NaB8JBfE7DY') }}
GitHub Gist
{{ shortcode.gist(user, id) }}
  • user: GitHub user name
  • id: Gist ID

Example:

{{ shortcode.gist('ArnaudLigny', 'fbe791e05b93951ffc1f6abda8ee88f0') }}

Custom shortcode

A shortcode is a Twig macro you must add in a template named shortcodes.twig.

Example:

shortcodes.twig:

{% extends 'extended/macros.twig' %}

{% block macros %}

{# the "foo" shortcode #}
{% macro foo(bar = 'bar') %}
<strong>{{ bar }}</strong>
{% endmacro %}

{% endblock %}

Suggest a modification