Cecil logo Cecil
What's on this page

Generate pages from data files

Data files are a convenient way to manage structured content (team members, products, events, etc.) outside of pages, then display it with templates.

Add a data file

Store your files in the data directory. Supported formats are YAML, JSON, XML and CSV.

# data/team.yml
- name: Ada
  role: Developer
- name: Grace
  role: Designer

Display data in a template

The file is available in templates with site.data.<filename>, e.g. layouts/team.html.twig:

{% extends 'page.html.twig' %}

{% block content %}
  <h1>{{ page.title }}</h1>
  <ul>
  {% for member in site.data.team %}
    <li>{{ member.name }}, {{ member.role }}</li>
  {% endfor %}
  </ul>
{% endblock %}

Files in sub-directories are nested: data/galleries/gallery-1.json is available with site.data.galleries['gallery-1'].

Create the page

The page that uses this template doesn’t need any content, so declare it as a default page in cecil.yml, indexed by ID:

pages:
  default:
    team:
      path: team
      title: Our team
      layout: team

You can also create a pages/team.md file with layout: team in its front matter.

Generate one page per item

To generate a page per entry, create a pages generator. Data loaded from data files is available with $this->builder->getData():

<?php
// extensions/MySite/Generator/Team.php
namespace MySite\Generator;

use Cecil\Collection\Page\Page;
use Cecil\Collection\Page\Type;
use Cecil\Generator\AbstractGenerator;
use Cecil\Generator\GeneratorInterface;
use Cecil\Util\Slugifier;

class Team extends AbstractGenerator implements GeneratorInterface
{
    public function generate(): void
    {
        $data = $this->builder->getData($this->config->getLanguageDefault());
        foreach ($data['team'] ?? [] as $member) {
            $slug = Slugifier::slugify($member['name']);
            $page = (new Page("team/$slug"))
                ->setType(Type::PAGE)
                ->setPath("team/$slug")
                ->setSection('team')
                ->setBodyHtml('<p>' . htmlspecialchars($member['role']) . '</p>')
                ->setVariable('title', $member['name']);
            $this->generatedPages->add($page);
        }
    }
}

Then register it:

pages:
  generators:
    Team: { class: MySite\Generator\Team, priority: 25 }