thelia/flexy-cms

Thelia 3 front-office theme for content sites, built on the Flexy design system

Maintainers

Package info

github.com/thelia-templates/flexy-cms

Language:Twig

Type:thelia-frontoffice-template

pkg:composer/thelia/flexy-cms

Transparency log

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-08 00:43 UTC

This package is auto-updated.

Last update: 2026-08-08 00:44:06 UTC


README

Front-office theme for Thelia 3 content sites. It is the Flexy design system with the pages, the menus and the language switcher of TheliaCMS wired in.

Tailwind CSS v4, Twig components, Stimulus and the Symfony asset mapper. No build step to deploy: the CSS is compiled by a command, the JavaScript is served as ES modules through an importmap.

Alpha. The theme renders CMS pages, contents, folders, the contact form, the customer account and the checkout screens. It has no product and no category view yet, so it cannot run a shop on its own. See What is missing.

Requirements

  • Thelia 3.0 with the Twig engine
  • PHP 8.4, because symfony/ux-twig-component v3 requires it
  • TheliaCMS installed and active. The theme calls cms_menu() and cms_page_alternates(), and an unknown Twig function fails at template compilation, not at render time: with the module off, the whole front answers 500. This is a deliberate dependency, not an accident.

Installation

composer require thelia/flexy-cms:dev-main
php Thelia template:set frontOffice flexy-cms
php Thelia cache:clear

Composer installs the theme into templates/frontOffice/flexy-cms (the directory name comes from extra.installer-name) and pulls in the modules it needs, Front, TwigEngine, TheliaLibrary, TheliaBlocks, HeaderHighlights, RecentlyViewed and SEOne among them.

Then compile the stylesheet:

php bin/console tailwind:build --watch   # development
php bin/console tailwind:build --minify  # deployment

What the theme gives the CMS

Where What
components/Layouts/Footer/Base.html.twig renders cms_menu('footer') as soon as the menu holds an entry, and falls back to the contents of the information folder
components/Organisms/LangSelect/Base.html.twig sends the visitor to the page they are reading in the language they pick, from cms_page_alternates(), and falls back to the home page of that language
base.html.twig emits the six layout hooks below, and points the favicon at the icon uploaded in Configuration > Store when there is one
cmspage.html.twig a CMS page, in the wrapper its layout asks for
cms-search.html.twig the results of the front-office search

A CMS page carries no heading of its own here: the content the editor composed holds the h1, and the theme adds the breadcrumb and the reading column around it. landing pages are rendered without header or footer.

Layout hooks

Restored on the Tailwind v4 base, which had none. They are where modules inject consent banners, measurement tags and anything that belongs to the page shell.

Hook Rendered
layout.head.top first thing in <head>, before any tag
layout.head.bottom end of <head>, receives the breadcrumb
layout.body.top opening of <body>
layout.header.bottom under the header
layout.footer.top above the footer
layout.body.bottom end of <body>

Layout

base.html.twig          the page shell, and the six hooks
*.html.twig             one file per Thelia view (index, content, folder, checkout…)
components/             Twig components: Atoms, Molecules, Organisms, Layouts, Fields, Forms
blocks/                 TheliaBlocks renderers
partials/               fragments included by the views
form/                   form themes
assets/                 app.js, Stimulus controllers, styles, icons, favicons
config/packages/        LiipImagine filter sets and the Tailwind extras
src/                    the FlexyBundle, its Twig extensions and the toolkit controller
translations/           theme strings

Every component holds its own template, its CSS and its Stimulus controller in one directory, and assets/styles/app.css imports them. /toolkit renders the gallery of components with real data, which is the fastest way to see what the theme already has before writing anything new.

Working on the theme

  • Tailwind scans only what assets/styles/app.css declares through @source. A new top-level directory is invisible to it until it is listed there.
  • symfony/ux-twig-component is pinned in practice to 3.3.0: 3.4 breaks the this.x pattern inside a {% block %}, silently rendering empty components.
  • The Flex recipe of symfonycasts/tailwind-bundle writes a binary_version that can be older than the theme needs. Keep it at 4.3 or above, or delete the file, otherwise the @utility rules of the theme do not compile and the utilities they define go missing.
  • Images go through LiipImagine. Filter sets live in config/packages/liip_imagine_thelia.yaml, and WebP is generated by default.
  • The fonts are files of the theme, under assets/fonts, declared in assets/styles/fonts.css. bin/update-fonts.py downloads them again after a change of family or weight, and keeps only the latin and latin-ext subsets.

What is missing

The Tailwind v4 base this theme derives from is not a complete shop yet: there is no product view and no category view, and a few catalogue partials are still to be written. Content sites work today. A shop needs those views, which is tracked with the Flexy design system rather than here.

A page also has no automated accessibility test yet. The shell was gone over by hand (a skip link first in the tab order, a label on each nav, a focus ring, one h1 per page), and the blocks of the catalogue were written for it, but nothing checks a page as it is published.

Licence

LGPL-3.0-or-later, like the Flexy design system it derives from. See LICENSE, and LICENSE.GPL for the GPL-3 text the LGPL builds on.