anomaly/appearance-module
Appearance module for the Anomaly CMS on Laravel. Adds theme and layout management so you can switch looks and customize your site's front end through a modular addon built for the Anomaly streams platform.
anomaly/appearance-module is not a standalone Laravel package — it is a PyroCMS module (part of the anomaly/* / pyrocms/* ecosystem) that provides the admin UI and repository layer for managing admin themes and public themes. Install it inside a PyroCMS application, not in a bare Laravel app.
Minimal steps:
Require both Pyro and the module:
composer require anomaly/appearance-module
It is normally already pulled in transitively by pyrocms/pyrocms, so check composer show anomaly/appearance-module first.
Ensure the addon is discovered. Pyro auto-discovers addons in vendor/ via config/streams/addons.php / addons.paths. If it isn’t, add the service provider to config/app.php:
Anomaly\AppearanceModule\AppearanceModuleServiceProvider::class,
Install the module (registers its Streams, permissions, and settings):
php artisan addon:install anomaly/appearance-module
Look first at src/AppearanceModuleServiceProvider.php, src/Theme/ThemeRepository.php, and src/Http/Controller/Admin/* — those are the entry points you’ll touch most.
First use case: log into /admin/appearance, pick an admin theme and a standard (public) theme from the dropdown, and customize exposed theme variables. This is the primary flow — most day-to-day work is registering themes and extending their customization options, not editing this module.
Registering a theme. Themes are registered through the ThemeRepository. Composer-installed themes under vendor/*/*-theme/* are auto-registered from their theme.php / composer.json metadata; local themes live under themes/{vendor}/{theme} in the project root. To support a bespoke theme, provide:
// themes/acme/agency/agency.php (or theme.php)
return [
'name' => 'Agency',
'description' => '...',
'version' => '1.0.0',
'author' => 'Acme',
'type' => 'standard', // or 'admin'
'support' => [/* asset paths */],
];
Reading theme values in Blade. Customization values are stored as Streams entries tied to the active theme, and read via the standard helpers:
{{ theme_value('acme.agency', 'primary_color', '#4f46e5') }}
Use the fallback argument so templates degrade gracefully when a fresh theme has no customization yet.
Extending customization options. Theme settings are just a Streams form. To add a new configurable option for a theme, add a field binding (in the theme’s streams/ bindings or via a small module) using the theme namespace, then reinstall/migrate that theme’s stream. Avoid editing the DB schema by hand — the Streams installer recreates fields on reinstall and will wipe manual changes.
Integrating at the layout level. Both admin and public layouts call into this module to resolve ADMIN_THEME and STANDARD_THEME and to inject published assets. When overriding layouts, keep the theme_assets() / theme_value() calls intact or the theme switcher in the admin will silently stop affecting output.
Workflow tip. Build a theme locally: scaffold under themes/acme/agency, iterate with the switcher in /admin/appearance, then composer-package it only once it’s stable. Local themes are hot-reload friendly; vendor themes are not (assets must be re-published on change).
ADMIN_THEME vs STANDARD_THEME). Switching one does not affect the other. php artisan env:set or the Appearance UI writes them; a stale .env value will override the UI in some setups — check .env before debugging why the admin UI “isn’t sticking”.php artisan cache:clear && php artisan view:clear
and re-publish assets (php artisan addon:publish). If the CSS looks unchanged, it’s almost always the asset cache, not the module.default_theme_* stream tables are lost. Keep custom options in bindings, not manual SQL.public/{vendor}/{theme}/…. If a theme was installed as a composer package with a different vendor layout, CSS 404s even when the theme “activates”. Verify the path in the theme’s support.assets map before blaming the module.type to admin in a theme’s metadata but installing it as a standard theme (or vice versa) will make it invisible in the wrong picker. It’s a type collision, not a permissions bug.composer.json rather than relying on ^ — the appearance module’s Streams schema historically changed between Pyro majors without a migration path.ThemeRepository events / extends the form builder over forking this one — the repository is the stable seam; the controllers are not.How can I help you explore Laravel packages today?