Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Redkite Labs Theme Engine Bundle Laravel Package

redkite-labs/redkite-labs-theme-engine-bundle

RedKite Labs Theme Engine Bundle is a Symfony bundle for adding theme support to PHP applications. It helps organize and switch themes, manage templates, assets, and configuration, making customizable multi-theme projects easier to build and maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

Reality check first. This is a Symfony2-era bundle with 2 stars and 0 dependents. Before writing a line of code, open the repository's composer.json and read the symfony/symfony, symfony/framework-bundle, and php constraints. If you are on Symfony 4+ (or even Symfony 3), the bundle almost certainly will not boot — it will reference AppKernel-era APIs, getContainerExtension() conventions, and possibly @Template/templating services. Treat this package as either (a) a legacy maintenance job on a Symfony 2.x app, or (b) a design reference you copy ideas from, not a dependency you install.

Three files to read, in this order, before anything else:

  1. README.md — if it exists and is non-empty, it is the only authoritative usage doc; expect it to be thin.
  2. DependencyInjection/Configuration.php — the real config schema. Do not trust config keys you see in blog posts or in this assessment; the tree definition is the ground truth.
  3. Resources/config/services.xml (or .yml) — the service ids and the class that actually resolves a theme. That class is your API.

Install (legacy app only).

composer require redkite-labs/redkite-labs-theme-engine-bundle:dev-master

If Composer cannot satisfy constraints against your Symfony version, pin a specific commit and plan to fork:

"repositories": [{ "type": "vcs", "url": "https://github.com/redkite-labs/ThemeEngineBundle" }]

Enable it in app/AppKernel.php, alongside every theme bundle:

$bundles = [
    // ...
    new RedKiteLabs\ThemeEngineBundle\RedKiteLabsThemeEngineBundle(),
    new Acme\Theme\CorporateThemeBundle\AcmeCorporateThemeBundle(),
];

Configure in app/config/config.yml. The shape will be close to this, but verify key names against Configuration.php:

red_kite_labs_theme_engine:
    themes:
        corporate:
            bundle: AcmeCorporateThemeBundle
            # path / enabled / slots depending on the version

First use case — the smallest thing that proves the wiring works: create a theme as an ordinary bundle with only Resources/views/index.html.twig, register it, point the config at it, then render through the engine's service instead of $this->render():

$engine = $this->get('red_kite_labs_theme_engine.theme'); // confirm the id
$engine->setTheme('corporate');

If that renders your theme's template, the plumbing works. Only then invest in slots, pages, and asset publishing.

Implementation Patterns

A theme is a bundle — lean on that. Do not invent a parallel directory layout. Themes go under src/Acme/Theme/FooThemeBundle/ with the standard Resources/views, Resources/public, and DependencyInjection/ structure. Everything you already know about bundle registration, Twig namespacing (@AcmeFooTheme/...), and assets:install applies unchanged. This is the single biggest ergonomic win of the bundle and the reason to use it over a hand-rolled "theme directory" switcher.

Config-driven registry, not hard-coded names. Keep every theme name in config.yml (or parameters.yml per environment) and read it via a parameter or the engine. Hard-coding 'corporate' in a controller is the fastest way to make the theme un-swappable later.

Runtime switching via a request listener. The usual production pattern is: resolve a theme from the hostname, a user preference, or a route parameter in a kernel.request listener, then set it on the engine before any controller runs.

class ThemeListener
{
    public function onKernelRequest(GetResponseEvent $event)
    {
        $theme = $this->resolver->resolve($event->getRequest()); // host, cookie, etc.
        $this->engine->setTheme($theme);
    }
}

Register it with a priority below RouterListener. This keeps controllers theme-agnostic.

Template fallback chain. The value of a theme engine is the lookup order. Establish it deliberately and document it: theme bundle template → application override (app/Resources/views) → engine default. Confirm the actual order by dumping the Twig loader chain ($container->get('twig.loader')->getPaths('@AcmeCorporate')), because the bundle may register theme paths ahead of the app, which inverts the usual Symfony override convention.

Multiple environments, one theme per env. For staging vs. production variants, override the theme parameter in config_staging.yml rather than adding conditional logic. This is cheaper than any runtime branching and matches how Symfony devs already think.

Testing. For functional coverage, boot the kernel with a test config that registers a throwaway theme bundle under tests/Fixtures/ and assert that a known template resolves. For unit coverage, mock the registry/engine and assert that your listener picks the right theme name for a given Request — that is the part with real logic; the engine itself you should not be testing.

Integration with controllers. If the bundle ships a base controller or a Twig extension (likely, given the CMS lineage), prefer the Twig function for template-level theme introspection (theme_name(), asset paths) and keep PHP-side switching in the listener. Mixing both leads to two sources of truth for "which theme am I in."

Fork discipline. With 0 dependents, you are the maintainer. Fork the repo into your org, tag a version, pin the VCS entry, and keep a CHANGELOG of your local patches. Do not depend on dev-master of an unmaintained repository — a force-push or branch rename will break your build with no warning.

Gotchas and Tips

The theme bundle must be registered in the kernel. The engine resolves a theme to a bundle, and a bundle that is not in registerBundles() does not exist to the container. The failure mode is a confusing "theme not found" rather than a clear bundle error. Check AppKernel.php first whenever a theme "disappears."

Bundle short name vs. FQCN. Config values are matched against the bundle's name (AcmeCorporateThemeBundle) or its logical name (AcmeCorporateThemeBundle:) depending on the version. Acme\Theme\CorporateThemeBundle\AcmeCorporateThemeBundle as a config value will not match. When in doubt, bin/console container:debug (or debug:container) and look at how the registry was compiled.

Clear the cache after touching themes. Theme discovery typically happens at container compile time. Adding, removing, or renaming a theme without cache:clear gives you stale results that look like a resolution bug but aren't. In dev, verify var/cache/dev (or app/cache/dev) is actually being rebuilt.

Assets are not automatic. Theme bundles' Resources/public still need assets:install --symlink (and, in Symfony2, Assetic filters for anything preprocessed). A theme that renders but has no CSS is almost always an unpublished-assets problem, not a template-resolution problem.

Template name collisions are silent. If the theme and the app both define index.html.twig, whichever loader path wins is invisible until something looks wrong in production. Prefer explicit namespaced references (@AcmeCorporate/index.html.twig) in layout code and reserve bare names for the override mechanism you actually want.

Config validation is your friend. Symfony's Configuration.php will reject unknown keys with a stack trace naming the offending key. If you get a cryptic error at boot, comment out the whole red_kite_labs_theme_engine block and re-add keys one at a time — faster than reading the DI extension.

Debugging resolution. When the wrong template renders, do not guess. Dump the resolved theme from the service, then dump the Twig loader paths for that theme's namespace. The bug is always in one of those two places: the engine has the wrong theme set (listener priority, or a controller overwriting it), or the loader paths are ordered differently than you assumed.

Extension points, if you need them. The two realistic customisations are (1) decorating the theme registry/resolver to support a theme source the bundle does not know about (database-driven themes, a themes/ directory outside src/), and (2) a compiler pass that injects your own theme list. Both are safer than editing vendored code — but with a forked, pinned repo, editing vendor code is an acceptable option as long as it lives in your fork, not in vendor/.

Do not ship this on anything new. No security maintenance, no PHP 8 compatibility work from upstream, and 0 dependents means no collective bug-fixing. If you are choosing an architecture today, a Twig loader-path switch plus a themes/ directory gets you 90% of this bundle's value in about 40 lines with zero abandonment risk.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log