Pages plugin

Manages standalone pages (an “about us”, a landing page, changelog, etc.), including .html.twig files in addition to Markdown. Same content model and format negotiation (HTML/Markdown/PDF/JSON) as Docs/FAQ, just without a listing/tag view — pages are meant to be linked directly, not browsed.

Route and the /pages prefix

Route Path Description
pages_page GET /pages/{uri} Shows a page. Format negotiated the same way as every other content plugin (Accept header, or .md/.pdf/.json suffix).

The route is registered under /pages on purpose, not at the root (/about instead of /pages/about). The {page:.+} pattern is a catch-all, and the router tries routes with parameters before it tries file-based routes (Derafu\Routing\Parser\FileSystemParser, used for standalone Twig pages placed directly in templates/pages/ by the website itself, with no content model). A catch-all with no prefix would shadow every one of those file-based pages: the router would never even get to ask the file-system parser about a URI this route already claims, since it checks parsers in order and stops at the first one that matches.

We verified this in practice: with the plugin enabled and content under resources/content/pages/, every existing hand-written route (static ones, and file-based ones from templates/pages/) kept working exactly as before — only URIs actually starting with /pages/ are affected.

If a website wants pages at the root anyway, it can register its own route pointing at the same handler instead of importing this one:

pages_page:
  path: /{page:.+}
  handler: 'Derafu\Content\Plugin\Pages\PagesController::show'

Registering that before any route that relies on FileSystemParser’s auto-discovery turns this trade-off off for that whole website: from then on, every flat page must be a content item (title/tags/draft/etc. via frontmatter), not a hand-authored Twig template dropped into templates/pages/. Pick one mechanism per website, not both, once this is unprefixed.

Configuration (services.yaml)

Enabled under derafu.content.config.plugins.pages:

parameters:
    derafu.content.config:
        plugins:
            pages:
              path: 'resources/content/pages'
Option Type Default Description
path string resources/content/pages Directory scanned for pages, relative to the website root.
include array of glob patterns ['**.{markdown,md,html.twig}'] Files considered content, relative to path. Unlike other plugins, this also matches .html.twig files.
exclude array of glob patterns [] Files excluded even if matched by include.
showLastUpdateAuthor bool false Whether to show who last updated the page.
showLastUpdateTime bool false Whether to show when the page was last updated.

Content frontmatter

Pages use exactly the generic content frontmatter, nothing added.

On this page

Last updated on 21/08/2026 by Anonymous