Atomic theme runtime is implemented by Engine\Atomic\Theme\Theme.
use Engine\Atomic\Theme\Theme;
Theme::instance(); // first call uses THEME.envname or "default"
Theme::instance('marketing'); // replaces the current singleton and boots that theme
Theme::reset(); // clears the singletonRuntime behavior:
- Reads the UI root from
ENQ_UI_FIX. - Resolves the theme name from the explicit argument or
THEME.envname. - Sets
UIto<ENQ_UI_FIX>/<theme_name>/. - Logs an error if that directory does not exist.
- Loads
functions.atom.phpthroughTheme::include(...). - Parses
theme.json. - Publishes theme metadata into the hive as
THEME.*.
Notes:
- A no-argument
Theme::instance()reuses the existing singleton once one has been created. - To switch themes after boot, call
Theme::instance('name')orTheme::reset()first.
Recommended layout:
app/UI/
default/
functions.atom.php
theme.json
partials/
head.atom.php
head.custom.atom.php
header.atom.php
footer.atom.php
sidebar.atom.php
Only functions.atom.php and theme.json are loaded directly by Theme. Partials are rendered later through View.
If theme.json exists and contains valid JSON, its keys are exposed as THEME.<key>.
Built-in metadata added by Theme::parse():
THEME._file: absolute path totheme.jsonTHEME._dir: active theme directoryTHEME._url: base themes URL, currently<public_url>themes/THEME._theme: active theme nameTHEME._url_public: public base URL fromMethods::get_public_url()THEME._dir_public: public base directory fromMethods::get_public_dir()
Example:
{
"title": "Default Theme",
"author": "Atomic Team",
"version": "1.2.0",
"color": "#f7f7f7"
}Becomes:
THEME.titleTHEME.authorTHEME.versionTHEME.color
If theme.json is missing, unreadable, or invalid, boot continues and a warning is logged.
Theme methods render exact partial paths under partials/:
Theme::get_head();
Theme::get_custom_head();
Theme::get_header();
Theme::get_footer();
Theme::get_sidebar();
Theme::get_section('hero', ['title' => 'Atomic']);Resolution:
get_head()->partials/head.atom.phpget_custom_head()->partials/head.custom.atom.phpif the file existsget_header('header')->partials/header.atom.phpget_footer('footer')->partials/footer.atom.phpget_sidebar('sidebar')->partials/sidebar.atom.phpget_section('hero')->partials/hero.atom.php
Global helpers from helpers.php:
get_head()get_custom_head()get_header()get_footer()get_sidebar()get_section()
Use Theme::include(...) for PHP files that live inside the active theme:
$theme = Theme::instance();
$ok = $theme->include('inc/hooks.php');Behavior:
- Relative paths are resolved inside the active theme directory.
- Absolute paths are allowed only when they still resolve inside the theme directory.
- Escaping the theme root is rejected and logged.
- Only readable regular files are included.
- Files are loaded with
include_once.
$theme = Theme::instance();
$meta = $theme->get_theme_meta();
$themeDir = $theme->get_theme_dir();
$themeUrl = $theme->get_theme_url();
$themeName = $theme->get_theme_name();
$publicUrl = $theme->get_public_url();
$publicDir = $theme->get_public_dir();Getter details:
get_theme_dir()returns the active theme directory with a trailing directory separator.get_theme_url()returns<public_url>themes/<theme_name>without an added trailing slash.get_public_url()andget_public_dir()are the generic public paths, not theme-specific paths.
Color helpers:
get_theme_color()returnstheme.jsoncolorwhen present, otherwise#ffffff.set_theme_color($fallback)returnsPAGE.colorwhen it exists, otherwise the provided fallback.
- Put shared theme bootstrap code in
functions.atom.php. - Keep
theme.jsonfor metadata only; it is copied into the hive unchanged except for the built-inTHEME._*keys. - Use
Theme::instance('name')when a controller must force a specific theme. - Use
Theme::include(...)instead of raw includes for theme-local PHP files. - Keep partial names aligned with the helper that renders them.