Building themes
This skill provides guidance and standard workflows for developing custom themes for Concrete CMS, including directory structure, page templates, asset management, and v9+ features like containers. Use this when creating or modifying Concrete CMS themes.From its SKILL.md
npx -y skills add MacareuxDigital/concretecms-skills --skill building-themesAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
One thing to look at
- 9 stars9 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
7.2 KB, ~1.5k tokens by cl100k_base, as published. Nobody here has run it
Building Themes
Overview
This skill enables the development of professional, feature-rich themes for Concrete CMS. It covers the essential components like page_theme.php, page templates, asset registration, and advanced features such as grid support and containers.
For the most up-to-date best practices and implementation examples, refer to the concrete/themes/atomik directory in the core. It serves as the primary reference for modern theme development in Concrete CMS.
Workflow
1. Setup Theme Directory
Themes should be placed within a package for better portability. Otherwise, they can be stored in the application directory.
- Path:
packages/your_package_handle/themes/your_theme_handle/ - Path:
application/themes/your_theme_handle/
2. Create Core Files
Every theme requires at least:
page_theme.php: The main configuration class for the theme.default.php: The default page template.view.php: Required for single pages. Should include thesystem_errorselement and$innerContent.elements/header.php&elements/footer.php: Shared header and footer.- Recommended: Sub-divide elements for simplicity (e.g.,
elements/header_top.php,elements/header.php,elements/footer.php,elements/footer_bottom.php).
3. Configure page_theme.php
- Define namespace:
Concrete\Package\YourPackageHandle\Theme\YourThemeHandle - Required Methods:
getThemeName(): Return the localized name of the theme.getThemeDescription(): Return the localized description of the theme.
- Implement
getThemeSupportedFeatures()to optimize asset loading.- JS Library Themes: If the theme includes a full-featured JavaScript library (e.g., Bootstrap 5 JS, jQuery), list all supported features (e.g.,
FeatureConstants::NAVIGATION,FeatureConstants::FORMS) to avoid conflicts with Concrete's internal asset loading. - No-JS Themes: If the theme does not include any JavaScript, it is recommended not to implement this method.
- JS Library Themes: If the theme includes a full-featured JavaScript library (e.g., Bootstrap 5 JS, jQuery), list all supported features (e.g.,
- Configure grid support via
$pThemeGridFrameworkHandle.- Core Frameworks: If using a supported framework (e.g.,
bootstrap5,bootstrap4), set this property to the corresponding handle. - Custom Frameworks: If the theme uses a custom or unsupported CSS framework (e.g., Tailwind, Bulma), do not set this property.
- Supported Handles: Find available frameworks in
concrete/src/Page/Theme/GridFramework/Type(e.g.,bootstrap5,foundation,nine_sixty).
- Core Frameworks: If using a supported framework (e.g.,
4. Implement Templates
- Use
$view->inc('elements/header.php')to include shared elements. For more modularity, use multiple includes like$view->inc('elements/header_top.php')and$view->inc('elements/header.php'). - Ensure
header_requiredandfooter_requiredelements are present.- Note on
header_required: It is recommended to pass metadata variables to this element. See the header_required snippet for the recommended implementation.
- Note on
- Use
Areafor editable regions. - Single Page Templates (
view.php): Must include thesystem_errorselement andecho $innerContent;to display system messages and single page content. See the system_errors snippet for the recommended implementation. - Wrap the main theme content in a
divelement with$c->getPageWrapperClass(). Do not apply this class to thebodyelement.
5. Manage Assets
- Use
registerAssets()inPageThemeto require core assets or provide theme-specific ones. - Prefer Core Assets: Always require core assets (e.g.,
jquery,bootstrap,vue) even if the theme directory contains the same libraries. This avoids conflicts and ensures compatibility with Concrete CMS's internal logic. - Minimize redundant CSS/JS by declaring what the theme provides.
6. Register Theme in Package
- Update the package
controller.phpor use a CIF XML file to install the theme.
Guidelines
- Namespacing: Always follow Concrete CMS PSR-4 naming conventions.
- Reference: Use
concrete/themes/atomikas the gold standard for implementation details. Other bundled themes may be legacy or for internal use. - Security: Include
defined('C5_EXECUTE') or die("Access Denied.");at the top of every PHP file. - Localization: Use
t()for all user-facing strings. - Modular Elements: For complex themes, it is recommended to split header and footer elements (e.g.,
header_top.phpfor metadata/scripts andheader.phpfor navigation) to keep individual files simple and maintainable. - Page Wrapper: Always use
$c->getPageWrapperClass()on a wrapperdivimmediately inside thebodytag, rather than on thebodyitself. This ensures that Concrete CMS's UI and dialogs work correctly within the theme's layout. - Asset Management:
- Core Libraries: Always prefer core assets over bundling your own for common libraries like jQuery, Bootstrap, moment.js, vue.js, and FullCalendar.
- Check Bundled Assets: To see which libraries are bundled in the core, check the
assetsarray inconcrete/config/app.php. - Conflict Prevention: Using core assets prevents multiple versions of the same library from being loaded, which can cause significant JavaScript errors.
- Theme Features:
- Use
getThemeSupportedFeatures()to declare what your theme provides. This prevents Concrete CMS from loading redundant or conflicting core assets. - If your theme is a "fully featured" theme with its own JS bundle, you should return an array containing all relevant
FeatureConstants. - If your theme is simple/static and has no JavaScript, omitting this method allows Concrete CMS to handle asset injection more predictably.
- Use
- Grid Framework:
- The
$pThemeGridFrameworkHandleproperty enables the built-in Layout system to use your theme's grid classes. - Only use this if your theme is compatible with one of the core grid frameworks found in
concrete/src/Page/Theme/GridFramework/Type. - Common handles include
bootstrap5,bootstrap4,bootstrap3,foundation, andnine_sixty. - If your theme uses a different CSS framework (like Tailwind CSS) or a custom grid system, do not define
$pThemeGridFrameworkHandle.
- The
- Modern Features: Favor Containers over hardcoded areas for flexible layouts in Concrete CMS v9+.
- Containers:
- Naming: Always ask the user for clarification before naming a container if the name is not explicitly provided.
- Element Path:
themes/your_theme_handle/elements/containers/your_container_handle.php - Implementation: Use
Concrete\Core\Area\ContainerAreato define editable regions within the container. - Registration: Define containers in the package's
config/install.xmlfile using the<containers>tag. - Usage: Containers are added to areas in the CMS by users, providing structured, reusable layouts.
What ships with it: 1 file
949 B alongside SKILL.md
references/
- code_snippets.md949 B