Skip to content

Commit

Permalink
feat: better templates handling
Browse files Browse the repository at this point in the history
  • Loading branch information
ArnaudLigny committed Nov 12, 2023
1 parent 936faa2 commit 035ea9b
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 32 deletions.
64 changes: 45 additions & 19 deletions docs/3-Templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,19 +29,41 @@ Cecil is powered by the [Twig](https://twig.symfony.com) template engine, so ple

## Files organization

There is two kinds of templates: _layouts_ and _others templates_.
There is two kinds of templates, **_layouts_** and **_others templates_**: _layouts_ are used to render [pages](2-Content.md#pages), and each of them can [include templates](https://twig.symfony.com/doc/templates.html#including-other-templates).

_Layouts_ are used to render [pages](2-Content.md#pages), and each of them can [include](https://twig.symfony.com/doc/templates.html#including-other-templates) templates.

_Layouts_ files are stored in the `layouts/` directory and must be named according to the following convention:
Files are stored in the `layouts/` directory and must be named according to the following convention:

```plaintext
<layout>.<format>.twig
layouts/(<section>/)<type>|<layout>(.<language>).<format>.twig
```

- `<layout>` is the name of the layout, the same as the one defined in [front matter](2-Content.md#front-matter) of a page (e.g.: `layout: my-layout`) or the name of a generic layout (i.e.: `index`, `page`, `list`, etc. See below for details)
- `<format>` of the [output](4-Configuration.md#formats) of the generated page (e.g.: `html`, `rss`, `json`, `xml`, etc.)
- `.twig` is the mandatory file extension
`<section>` (optional)
: The section of the page (e.g.: `blog`).

`<type>`
: The page type: `home` (or `index`) for _homepage_, `list` for section list, `page` for page, etc. (See below for details).

`<layout>`
: The custom layout name defined in the [front matter](2-Content.md#front-matter) of the page (e.g.: `layout: my-layout`).

`<language>` (optional)
: The language of the page (e.g.: `fr`).

`<format>`
: The [output format](4-Configuration.md#formats) of the rendered page (e.g.: `html`, `rss`, `json`, `xml`, etc.).

".twig"
: The mandatory file extension.

_Examples:_

```plaintext
layouts/home.html.twig # home page (`type` is "home")
layouts/my-layout.html.twig # custom layout (`layout` is "my-layout")
layouts/page.fr.html.twig # page in french (`language` is "fr")
layouts/blog/list.html.twig # blog posts list (`section` is "blog")
layouts/blog/list.rss.twig # blog RSS feed (`format` is "rss")
```

```plaintext
<mywebsite>
Expand All @@ -53,7 +75,7 @@ _Layouts_ files are stored in the `layouts/` directory and must be named accordi
| ├─ list.rss.twig <- Used by types "homepage", "section" and "term", for RSS output format
| ├─ page.html.twig <- Used by type "page"
| ├─ ...
| ├─ _default <- Default layouts, that can be easily extended by "root" layouts
| ├─ _default <- Default layouts, that can be easily extended
| | ├─ list.html.twig
| | ├─ page.html.twig
| | └─ ...
Expand All @@ -68,33 +90,37 @@ _Layouts_ files are stored in the `layouts/` directory and must be named accordi

## Lookup rules

In most of cases **you don’t need to specify a layout name** (in the [front matter](2-Content.md#front-matter) of the page) : **Cecil selects the most appropriate layout**, according to the page _type_.
In most of cases **you don’t need to specify the layout**: Cecil selects the most appropriate layout, according to the page _type_.

For example, the HTML output of _home page_ will be rendered in the following order:

1. with `my-layout.html.twig` if the `layout` variable is set to "my-layout" in the front matter of `index.md`
2. if not, with `index.html.twig` if the file exists
3. if not, with `list.html.twig` if the file exists
4. etc.
2. if not, with `home.html.twig` if the file exists
3. if not, with `index.html.twig` if the file exists
4. if not, with `list.html.twig` if the file exists
5. etc.

All rules are detailed below, for each page type, in the priority order.

### Type _homepage_

1. `<layout>.<format>.twig`
2. `index.<format>.twig`
3. `list.<format>.twig`
4. `_default/index.<format>.twig`
5. `_default/list.<format>.twig`
6. `_default/page.<format>.twig`
2. `home.<format>.twig`
3. `index.<format>.twig`
4. `list.<format>.twig`
5. `_default/home.<format>.twig`
6. `_default/index.<format>.twig`
7. `_default/list.<format>.twig`
8. `_default/page.<format>.twig`

### Type _page_

1. `<section>/<layout>.<format>.twig`
2. `<layout>.<format>.twig`
3. `<section>/page.<format>.twig`
4. `page.<format>.twig`
5. `_default/page.<format>.twig`
5. `_default/<layout>.<format>.twig`
6. `_default/page.<format>.twig`

### Type _section_

Expand Down
35 changes: 22 additions & 13 deletions src/Renderer/Layout.php
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ public static function finder(CollectionPage $page, string $format, Config $conf
// take the first available layout
foreach ($layouts as $layout) {
$layout = Util::joinFile($layout);
// is it in layouts/ dir?
// is it in `layouts/` dir?
if (Util\File::getFS()->exists(Util::joinFile($config->getLayoutsPath(), $layout))) {
return [
'scope' => 'site',
'file' => $layout,
];
}
// is it in <theme>/layouts/ dir?
// is it in `<theme>/layouts/` dir?
if ($config->hasTheme()) {
$themes = $config->getTheme();
foreach ($themes as $theme) {
Expand All @@ -60,7 +60,7 @@ public static function finder(CollectionPage $page, string $format, Config $conf
}
}
}
// is it in resources/layouts/ dir?
// is it in `resources/layouts/` dir?
if (Util\File::getFS()->exists(Util::joinPath($config->getInternalLayoutsPath(), $layout))) {
return [
'scope' => 'cecil',
Expand Down Expand Up @@ -88,15 +88,17 @@ protected static function fallback(CollectionPage $page, string $format): array
case PageType::HOMEPAGE:
$layouts = [
// "$layout.$format.$ext",
"home.$format.$ext",
"index.$format.$ext",
"list.$format.$ext",
"_default/home.$format.$ext",
"_default/index.$format.$ext",
"_default/list.$format.$ext",
"_default/page.$format.$ext",
];
if ($page->hasVariable('layout')) {
$layouts = array_merge(
[sprintf('%s.%s.%s', $layout, $format, $ext)],
["$layout.$format.$ext"],
$layouts
);
}
Expand All @@ -112,17 +114,17 @@ protected static function fallback(CollectionPage $page, string $format): array
if ($page->getPath()) {
$section = $page->getSection();
$layouts = array_merge(
[sprintf('section/%s.%s.%s', $section, $format, $ext)],
["section/$section.$format.$ext"],
$layouts
);
$layouts = array_merge(
[sprintf('%s/list.%s.%s', $section, $format, $ext)],
["$section/list.$format.$ext"],
$layouts
);
}
if ($page->hasVariable('layout')) {
$layouts = array_merge(
[sprintf('%s.%s.%s', $layout, $format, $ext)],
["$layout.$format.$ext"],
$layouts
);
}
Expand All @@ -134,7 +136,7 @@ protected static function fallback(CollectionPage $page, string $format): array
];
if ($page->hasVariable('plural')) {
$layouts = array_merge(
[sprintf('taxonomy/%s.%s.%s', $page->getVariable('plural'), $format, $ext)],
["taxonomy/{$page->getVariable('plural')}.$format.$ext"],
$layouts
);
}
Expand All @@ -148,13 +150,13 @@ protected static function fallback(CollectionPage $page, string $format): array
];
if ($page->hasVariable('term')) {
$layouts = array_merge(
[sprintf('taxonomy/%s.%s.%s', $page->getVariable('term'), $format, $ext)],
["taxonomy/{$page->getVariable('term')}.$format.$ext"],
$layouts
);
}
if ($page->hasVariable('singular')) {
$layouts = array_merge(
[sprintf('taxonomy/%s.%s.%s', $page->getVariable('singular'), $format, $ext)],
["taxonomy/{$page->getVariable('singular')}.$format.$ext"],
$layouts
);
}
Expand All @@ -165,26 +167,33 @@ protected static function fallback(CollectionPage $page, string $format): array
// "$layout.$format.$ext",
// "$section/page.$format.$ext",
// "page.$format.$ext",
// "_default/$layout.$format.$ext",
"_default/page.$format.$ext",
];
if ($page->hasVariable('layout')) {
$layouts = array_merge(
["_default/$layout.$format.$ext"],
$layouts
);
}
$layouts = array_merge(
["page.$format.$ext"],
$layouts
);
if ($page->getSection()) {
$layouts = array_merge(
[sprintf('%s/page.%s.%s', $page->getSection(), $format, $ext)],
["{$page->getSection()}/page.$format.$ext"],
$layouts
);
}
if ($page->hasVariable('layout')) {
$layouts = array_merge(
[sprintf('%s.%s.%s', $layout, $format, $ext)],
["$layout.$format.$ext"],
$layouts
);
if ($page->getSection()) {
$layouts = array_merge(
[sprintf('%s/%s.%s.%s', $page->getSection(), $layout, $format, $ext)],
["{$page->getSection()}/$layout.$format.$ext"],
$layouts
);
}
Expand Down

0 comments on commit 035ea9b

Please sign in to comment.