Cecil logo

Content

There is different kinds of content in Cecil:

  • Pages (Markdown or plain text files in content/)
  • Assets files (images, CSS, scripts, etc. in assets/)
  • Static files (videos, PDF, etc. in static/)
  • Data files (custom variables collections in data/)

Files organization

Your content should be organized in a manner that reflects the rendered website.

File system tree

<mywebsite>
├─ content
|  ├─ blog            <- Section
|  |  ├─ post-1.md    <- Page in Section
|  |  └─ post-2.md
|  ├─ projects
|  |  └─ project-1.md
|  └─ about.md        <- Page in the root
├─ assets
|  ├─ styles.scss     <- Asset file
|  └─ logo.png
├─ static
|  └─ video.mp4       <- Static file
└─ data
   └─ authors.yml     <- Data collection

Notes:

  • Each folder in the root of content/ is called a Section (e.g.: “Blog“, “Project“, etc.)
  • You can override Section’s default variables by creating an index.md file in its directory (e.g.: blog/index.md)
  • Files in assets/ are handled with the asset() function
  • Files in static/ are copied as is in the root of the built website (e.g.: static/video.mp4 -> video.mp4)
  • Content of files in data/ is exposed in templates with {{ site.data }}

Built website tree

<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            <- Generated list of projects
   |  └─ project-1/index.html
   ├─ about/index.html
   ├─ styles.css
   ├─ logo.png
   └─ video.mp4

By default each Page is generated as filename-slugified/index.html to get a “beautiful“ URL like https://mywebsite.tld/blog/post-1/. To get an “ugly” URL (like 404.html instead of 404/), set uglyurl: true in front matter.

File VS URL structure

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

Page anatomy

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

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

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, in Markdown Extra or in plain text.

Cecil also provides extra features to enhance your content: table of contents, text excerpt, image manipulation (caption, lazy loading, resizing, responsive) and notes).

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
**Tip:** This is an advice.
:::

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.

Images

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">
Caption

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

Example:

![](/images/img.jpg "Optional title")

Is converted to:

<figure>
  <img src="/image.jpg" title="Title">
  <figcaption>Title</figcaption>
</figure>
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"
>
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>

Notes

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

Example:

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

Is converted to:

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

Variables

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

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

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 creation date of the Page, and must be a valid date format (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 (e.g.: blog/index.md).

sortby

The order of Pages can be changed in a Section.

Available values are:

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

Example:

---
sortby: title
---

pagination

Global pagination configuration can be overridden in a Section.

Example:

---
pagination:
  max: 2
  path: "p"
---

cascade

Any values in cascade will be merged into 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’s name to pagesfrom to use pages collection from this section.

exclude

Set exclude to true to hide the Page from lists (like Home page, Section, Sitemap, etc.).

Example:

---
exclude: true
---

Multilingual

If your content is available in multiple languages there is 2 ways to define it:

Language in the file name

Defines the page’s language by adding the language code as a suffix in the file name.

Example:

about.fr.md

Language in the front matter

Defines the page’s language by setting the language variable with language code as value in the front matter.

Example:

---
language: fr
---

Dynamic content

You can use variables and shortcodes in the body content.

To do this you must include a specific template instead of {{ page.content }}:

{% include page.content_template %}

Experimental

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

Shortcodes

Shortcodes are helpers to create dynamic content.

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('Narno', 'fbe791e05b93951ffc1f6abda8ee88f0') }}

Custom shortcode

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

Example:

shortcodes.twig:

{% extends 'macros.twig' %}

{% block macros %}

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

{% endblock %}

Suggest a modification