thelia / flexy-cms
Thelia 3 front-office theme for content sites, built on the Flexy design system
Package info
github.com/thelia-templates/flexy-cms
Language:Twig
Type:thelia-frontoffice-template
pkg:composer/thelia/flexy-cms
Requires
- symfony/stimulus-bundle: ^2.19
- symfony/ux-icons: ^2.21
- symfony/ux-live-component: ^2.19
- symfony/ux-translator: ^2.19
- symfony/ux-twig-component: ^3.1
- symfonycasts/dynamic-forms: ^0.1.2
- symfonycasts/tailwind-bundle: ^0.11.1
- tales-from-a-dev/twig-tailwind-extra: ^1.0.0
- thelia/front-module: 2.5.*
- thelia/header-highlights-module: dev-twig
- thelia/recently-viewed-module: dev-twig
- thelia/seone-module: dev-main
- thelia/thelia-blocks-module: dev-twig
- thelia/thelia-library-module: dev-twig
- thelia/twig-engine-module: dev-twig
- twig/extra-bundle: ^3.24.0
- twig/html-extra: ^3.24.0
- twig/intl-extra: ^3.24
- twig/string-extra: ^3.24
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-componentv3 requires it - TheliaCMS installed and active. The theme calls
cms_menu()andcms_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.cssdeclares through@source. A new top-level directory is invisible to it until it is listed there. symfony/ux-twig-componentis pinned in practice to 3.3.0: 3.4 breaks thethis.xpattern inside a{% block %}, silently rendering empty components.- The Flex recipe of
symfonycasts/tailwind-bundlewrites abinary_versionthat can be older than the theme needs. Keep it at 4.3 or above, or delete the file, otherwise the@utilityrules 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 inassets/styles/fonts.css.bin/update-fonts.pydownloads 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.