name: cecil description: Build and configure Cecil static sites, with focused guidance for content, templates, and site generation.
Cecil Site Builder
You are an expert Cecil developer capable of creating and generating static websites with Cecil, a PHP-based static site generator powered by Symfony components and Twig.
When to Use This Skill
Use this skill when:
- Creating or scaffolding a new Cecil site
- Building and generating static websites with Cecil
- Configuring site settings, taxonomies, and content organization
- Creating or updating Twig templates and layouts
- Managing assets, including images and stylesheets
- Deploying Cecil-generated static sites
- Troubleshooting build issues or optimizing the performance of the generated site and build process
- Working with Cecil's plugin/extension system
Project Structure
Directory Layout
my-site/
├── cecil.yml # Main configuration file (or config.yml)
├── pages/ # Markdown pages
├── layouts/ # Twig templates
├── assets/ # Processed files (CSS, JS, images)
├── static/ # Static files copied as-is
└── data/ # Data collections (YAML/JSON/...)
Key Directories
- pages/ - Markdown content files organized into sections
- layouts/ - Twig templates and partials
- assets/ - Files handled by Cecil (Sass compilation, minification, image handling)
- static/ - Files copied to output without transformation
- data/ - Data files exposed in templates via
site.data
Cecil Fundamentals
Architecture
Cecil follows a build pipeline:
Builder → Steps → Generators → Renderer → Output
Steps (
Step/): Sequential build phases- Pages: Parse markdown content
- Data: Load data files
- Assets: Process assets
- Taxonomies: Generate taxonomy pages
- Menus: Build navigation structures
- Optimize: Optimize output
- StaticFiles: Copy static files
Generators (
Generator/): Page generators executed via priority queue- Lower numeric priority executes first
- DefaultPages (10) → VirtualPages (20) → ExternalBody (30) → Section (40) → Taxonomy (50) → Homepage (60) → Pagination (70) → Alias (80) → Redirect (90)
Renderer (
Renderer/): Twig-based rendering with custom extensionsOutput: Built static site in
_site/directory
Content Model
- Pages: Markdown files composed of front matter and body
- Front matter: Metadata surrounded by separators (
---,+++, or<!-- -->) - Section: Root folder in
pages/(e.g.pages/blog/post-1.md-> sectionblog) - File-based routing: Files under
pages/define generated paths - Collections: Pages, taxonomies, data and static files are exposed to templates
Configuration
Configuration is defined in cecil.yml or config.yml at project root:
- Core options are top-level keys such as
title,baseurl,description,taxonomies,menus - Dot notation in templates applies to
sitevariable access (for examplesite.title) - Defaults are defined in
config/default.phpand base pipeline inconfig/base.php
Building a Cecil Site
Step 1: Download Cecil
Download Cecil using curl:
curl -LO https://cecil.app/cecil.phar
chmod +x cecil.phar
Verify the download:
php cecil.phar --version
Step 2: Create a New Site
Use the new:site command to scaffold a new website:
php cecil.phar new:site
Step 3: Configure the Site
Edit cecil.yml:
title: My Site
baseurl: https://example.com/
description: My awesome static site
taxonomies:
categories: category
tags: tag
Step 4: Create Content
Create a page with:
php cecil.phar new:page
Then edit the generated file in pages/:
---
title: My First Post
description: Welcome to my blog
date: 2024-05-14
tags: [Welcome, "First post"]
---
# My First Post
This is my first post content.
Step 5: Create Templates
Create Twig templates in layouts/ (for example layouts/page.html.twig):
<!DOCTYPE html>
<html>
<head>
<title>{{ page.title }} - {{ site.title }}</title>
</head>
<body>
<header>
<h1>{{ site.title }}</h1>
</header>
<main>
{{ page.content }}
</main>
<footer>
<p>© {{ site.title }}</p>
</footer>
</body>
</html>
Step 6: Build the Site
php cecil.phar build
Output is generated in _site/ directory.
CLI Commands
| Command | Purpose |
|---|---|
php cecil.phar new:site |
Create a new website |
php cecil.phar new:page |
Create a new page |
php cecil.phar build |
Build the static site |
php cecil.phar serve |
Start local server with live reload |
php cecil.phar show:config |
Display effective configuration |
php cecil.phar cache:clear |
Clear all cache files |
php cecil.phar self-update |
Update Cecil |
php cecil.phar clear |
Remove generated files |
php cecil.phar util:templates:extract |
Extract built-in templates into layouts |
Template Development
Twig templates live in layouts/ and follow Cecil naming conventions.
Naming Convention
Use this pattern:
layouts/(<section>/)<type>|<layout>.<format>(.<language>).twig
Examples:
layouts/page.html.twig- default page templatelayouts/list.html.twig- section/home/term listing templatelayouts/blog/list.rss.twig- RSS template forblogsectionlayouts/page.html.fr.twig- French page templatelayouts/_default/page.html.twig- fallback template
Lookup Rules (How Cecil Chooses a Template)
- Identify the page kind and check section-specific or explicit
layouttemplates first. - Apply the matching fallback chain for that page kind:
| Page Kind | Step 1 | Step 2 | Step 3 | Step 4 |
|---|---|---|---|---|
| Homepage | index.* |
home.* |
list.* |
_default/* |
| Standard page | page.* |
_default/page.* |
- | - |
| Section page | section-specific list.* or explicit layout.* |
list.* |
_default/* |
- |
| Taxonomy page | taxonomy template or explicit layout.* |
list.* |
_default/* |
- |
In practice, you usually need only:
layouts/page.html.twiglayouts/list.html.twig- optional overrides in
layouts/_default/or per section
Template Variables
Most useful variables in Twig:
site.title,site.baseurl,site.descriptionsite.pages- pages collection (current language)site.allpages- pages in all languagessite.taxonomies- vocabularies and termssite.menus.<name>- menu entriespage.title,page.date,page.content,page.path,page.type,page.section
Multilingual Sites
Configure languages in cecil.yml:
language: en
languages:
- code: en
name: English
locale: en_US
- code: fr
name: Francais
locale: fr_FR
Use suffixed filenames for translations:
pages/about.md
pages/about.fr.md
You can render a language switcher in templates with:
{% include 'partials/languages.html.twig' %}
Useful collection helpers:
site.pages.showableto skip draft/virtual/excluded pagessort_by_weightfilter for menu entries
Example Template
{# layouts/page.html.twig #}
<!DOCTYPE html>
<html lang="{{ site.language }}">
<head>
<meta charset="utf-8">
<title>{{ page.title }} - {{ site.title }}</title>
{{ include('partials/metatags.html.twig') }}
</head>
<body>
<header>
<h1><a href="{{ url('/') }}">{{ site.title }}</a></h1>
{% if site.menus.main is defined %}
<nav>
<ul>
{% for entry in site.menus.main|sort_by_weight %}
<li><a href="{{ url(entry.url) }}">{{ entry.name }}</a></li>
{% endfor %}
</ul>
</nav>
{% endif %}
</header>
<main>
<article>
<h2>{{ page.title }}</h2>
{% if page.date %}
<time datetime="{{ page.date|date('c') }}">{{ page.date|date('Y-m-d') }}</time>
{% endif %}
{{ page.content }}
</article>
</main>
</body>
</html>
Built-in Partials and Utilities
partials/metatags.html.twig- SEO/social tagspartials/navigation.html.twig- navigation helperpartials/paginator.html.twig- pagination linkspartials/languages.html.twig- language switcher
If needed, extract built-in templates to customize them:
php cecil.phar util:templates:extract
Pagination
Pagination is configured globally under pages.pagination, and can be overridden in section front matter.
pages:
pagination:
max: 5
path: page
---
pagination:
max: 10
path: page
---
In list templates, include paginator links with:
{% include 'partials/paginator.html.twig' %}
Custom Filters and Functions
Core Twig helpers commonly used in Cecil templates:
url()- generate internal/absolute URLs depending on configasset()- reference and process assetsinclude()- compose templates with partials/components
Build Optimization
Asset Processing
Configure asset optimization:
assets:
minify: true
fingerprint: true
compile:
style: compressed
images:
optimize: true
Performance Tips
- Use
draft: trueto exclude non-published content from builds - Enable asset minification and fingerprinting in production
- Use output and format settings adapted to your pages types
- Use responsive image options and image optimization when needed
Extension & Plugins
Custom Generators
Extend Cecil by creating custom generators:
<?php
namespace MyProject\Generator;
use Cecil\Generator\AbstractGenerator;
class CustomGenerator extends AbstractGenerator
{
public function generate(): void
{
// Custom generation logic
}
}
Then register it in configuration with pages.generators.
pages:
generators:
100: MyProject\\Generator\\CustomGenerator
Custom Commands
Create CLI commands by extending AbstractCommand:
<?php
namespace MyProject\Command;
use Cecil\Command\AbstractCommand;
class MyCommand extends AbstractCommand
{
// Implementation
}
You can also extend Twig (via layouts.extensions) and post-process output (via output.postprocessors).
layouts:
extensions:
MyExtension: MyProject\\Twig\\MyExtension
The Twig extension class should implement Twig\Extension\ExtensionInterface (or extend Twig\Extension\AbstractExtension).
output:
postprocessors:
MyProcessor: MyProject\\Renderer\\PostProcessor\\MyProcessor
Post-processors should implement Cecil\Renderer\PostProcessor\PostProcessorInterface.
Deployment
Static Site Hosting
Cecil generates pure static HTML, compatible with:
- GitHub Pages
- Netlify
- Vercel
- AWS S3
- Any web server
Build & Deploy Workflow
# Build
php cecil.phar build
# Deploy output directory (_site/)
# to your hosting platform
GitHub Pages Example
php cecil.phar build
# Commit _site/ directory and push to gh-pages branch
Code Quality Standards
When extending or contributing to Cecil:
- Follow PSR-12 coding standards
- Use
declare(strict_types=1);in all PHP files - Prefix native function calls with
\(e.g.,\count()) - Include proper PHPDoc blocks for all classes and methods
- Use 4-space indentation for PHP, 2-space for YAML/Twig
- Include the following header comment only when contributing to the Cecil core repository itself. For user project extensions, omit it or replace the copyright line with
(c) [Your Name]:
<?php
/**
* This file is part of Cecil.
*
* (c) Arnaud Ligny <arnaud@ligny.fr>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
Useful Resources
- Official Documentation: https://cecil.app
- GitHub Repository: https://github.com/Cecilapp/Cecil
- Issue Tracker: https://github.com/Cecilapp/Cecil/issues
- Documentation: https://cecil.app/documentation/
Common Workflows
Create a Blog
- Create
pages/blog/index.mdfor blog section - Add individual posts in
pages/blog/post-*.md - Configure taxonomy for tags/categories
- Create templates for listing and individual posts
- Build with
php cecil.phar build
Add Custom Pages
- Create markdown files in
pages/directory - Add frontmatter with title and template
- Create corresponding template in
layouts/ - Reference template in page frontmatter
- Build to generate output
Implement Search
- Create
pages/search.json.mdwith front matteroutput: json - Use JavaScript library (e.g., Lunr.js) on frontend
- Create
layouts/search.json.twigthat iteratessite.pages.showableand emits a JSON array of{title, url, content}objects - Add search functionality to templates
Troubleshooting
When a user reports unexpected behavior or asks about a specific feature, ask them to run php cecil.phar doctor and include the output, then qualify guidance with the Cecil version range where the feature is available.
Common Issues
- Site not generating: Check
cecil.ymlsyntax and configuration - Missing pages: Ensure content files are in
pages/directory - Template not loading: Verify template path in frontmatter and layouts directory
- Build errors: Run
php cecil.phar build -vvfor verbose output - Cache issues: Clear cache with
php cecil.phar cache:clear
Debug Output
Get detailed build information:
php cecil.phar build -v # Verbose
php cecil.phar build -vv # Very verbose
php cecil.phar build -vvv # Debug