Color Themes
Chamilo 2.0 uses a database-driven color theme system. Themes are managed through the admin UI, stored in the database, and written to disk as CSS files. They can be customized per access URL, allowing multi-URL installations to have different visual identities.
Data Model
Two entities drive the theme system:
ColorTheme (src/CoreBundle/Entity/ColorTheme.php)
id
int
Primary key
title
string
Human-readable name
slug
string
Auto-generated from title (e.g. "My Theme" → my-theme); used as the directory name in var/themes/
variables
array (JSON)
Map of CSS custom property name → value (e.g. {"--color-primary-base": "46 117 163"})
AccessUrlRelColorTheme (src/CoreBundle/Entity/AccessUrlRelColorTheme.php)
Associates a ColorTheme with an AccessUrl. The active boolean flag marks which theme is currently active for that URL. Only one theme can be active per access URL at a time.
How Themes Are Stored
When a theme is created or updated via the API, ColorThemeStateProcessor generates the CSS file and writes it to the Flysystem themes_filesystem (backed by var/themes/):
var/themes/
└── {slug}/
└── colors.css ← generated from ColorTheme.variablesThe generated colors.css wraps all variables in a :root block:
Values are space-separated RGB channel triplets (not rgb()), which allows Tailwind to compose opacity variants such as bg-primary/50 without additional configuration.
Theme Resolution Precedence
ThemeHelper::getVisualTheme() resolves which theme slug to apply on any given page, in this order:
Active theme for the current AccessUrl — the
AccessUrlRelColorThemerecord withactive = trueUser-selected theme — the theme stored on the
Userentity, if theprofile.user_selected_themeplatform setting is enabledCourse theme — the
course_themecourse setting, if thecourse.allow_course_themeplatform setting is enabledLearning path theme — the LP's
$lp_theme_cssvalue, if theallow_learning_path_themecourse setting is enabledTHEME_FALLBACKenv var — set in.envasTHEME_FALLBACK='chamilo'Default —
chamilo(hardcoded asThemeHelper::DEFAULT_THEME)
Asset Serving
Theme assets are served by ThemeController (src/CoreBundle/Controller/ThemeController.php) under the /themes prefix.
GET /themes/{name}/{path}
Serve any theme asset (CSS, JS, images); falls back to chamilo theme if not found in the requested theme
GET /themes/{slug}/logo/{type}
Serve the preferred logo (header or email), with SVG → PNG fallback
POST /themes/{slug}/logos
Upload header/email logos (SVG and/or PNG)
DELETE /themes/{slug}/logos/{type}
Delete a specific logo
The general asset route (/{name}/{path}) automatically falls back to the chamilo default theme when a file is missing from the requested theme, so themes only need to include files they actually override.
How Themes Are Loaded in Templates
The head.html.twig layout template loads the active theme's assets via Twig helper functions:
The three Twig functions (registered in ChamiloExtension) resolve the asset path through ThemeHelper, applying the same fallback chain as above:
theme_asset('path')
URL to the asset in the resolved theme
theme_asset_link_tag('path')
Full <link rel="stylesheet"> tag
theme_asset_script_tag('path')
Full <script src="..."> tag
theme_asset_base64('path')
Base64-encoded data URI of the asset
theme_logo('header'|'email')
URL to the best available logo
API Endpoints
Theme management is exposed via the API Platform REST API (admin-only):
POST
/api/color_themes
Create a new theme
PUT
/api/color_themes/{id}
Update an existing theme
POST
/api/access_url_rel_color_themes
Associate/activate a theme for an access URL
GET
/api/access_url_rel_color_themes
List theme associations for the current access URL
Creating a Custom Theme
The standard workflow is through the admin UI (Admin → Color Themes), which calls the API endpoints above. To create a theme programmatically:
POST /api/color_themeswith a JSON body:
This persists the entity and writes var/themes/my-theme/colors.css.
POST /api/access_url_rel_color_themesto associate and activate it for the current access URL:
To add custom images (logo, favicon, backgrounds), upload them via POST /themes/{slug}/logos or place them directly in var/themes/{slug}/images/.
Color Variable Reference
All variables expected by the default Tailwind configuration:
--color-primary-base
Primary brand color
--color-primary-gradient
Darker gradient stop for primary
--color-primary-button-text
Text color on primary buttons
--color-primary-button-alternative-text
Alternative text color on primary buttons
--color-secondary-base
Secondary accent color
--color-secondary-gradient
Gradient stop for secondary
--color-secondary-button-text
Text color on secondary buttons
--color-tertiary-base
Tertiary color
--color-tertiary-gradient
Gradient stop for tertiary
--color-tertiary-button-text
Text color on tertiary buttons
--color-success-base
Success state color
--color-success-gradient
Gradient stop for success
--color-success-button-text
Text color on success buttons
--color-info-base
Info state color
--color-info-gradient
Gradient stop for info
--color-info-button-text
Text color on info buttons
--color-warning-base
Warning state color
--color-warning-gradient
Gradient stop for warning
--color-warning-button-text
Text color on warning buttons
--color-danger-base
Danger/error state color
--color-danger-gradient
Gradient stop for danger
--color-danger-button-text
Text color on danger buttons
--color-form-base
Form element accent color
Last updated
Was this helpful?