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

Theme Bundle Laravel Package

stgbundle/theme-bundle

stgbundle/theme-bundle is a Symfony/PHP theme management bundle that lets applications register multiple themes, resolve templates and assets per theme, and switch themes through configuration. It simplifies building customizable, themeable web interfaces.

View on GitHub
Deep Wiki
Context7

Getting Started

Before writing a single line of integration code, confirm the package is actually installable — with 5 stars and 0 dependents this is an internal Santa Fe government bundle, not a community-vetted one. Treat it as "vendor code to audit" rather than "dependency to trust."

  1. Check the README and composer.json first. Look specifically for:
    • The Symfony version constraint (symfony/framework-bundle, symfony/http-kernel). A theme bundle usually hooks into kernel.request, Twig, and the asset pipeline — all of which changed significantly across Symfony 4/5/6/7.
    • PHP version constraint.
    • Required sibling stgbundle/* packages. Bundles from the same publisher often reference each other; you may need to pull several in.
  2. Install into a throwaway Symfony skeleton before touching a real app:
    composer require stgbundle/theme-bundle
    
    If Composer resolves, run bin/console debug:container --tags and bin/console debug:config stg_theme (or whatever the extension alias is) to see what got registered.
  3. Look for the bundle class and extension. Typically src/StgThemeBundle.php plus DependencyInjection/Configuration.php. The config tree is your real documentation — moreso than any README.
  4. First use case: given the name and origin, the intended use is almost certainly server-side theme resolution per request — picking a Twig template path / asset set based on a domain, tenant, or route. On a fresh install, register the bundle in config/bundles.php, add the minimal config block, and try rendering one page through the theme layer before wiring anything else.

If composer require fails or the bundle targets Symfony ≤ 4.x, stop here — you're likely looking at an abandoned internal package, and forking is a better strategy than depending on it.

Implementation Patterns

The patterns below are what a "theme bundle" from a government department typically encodes. Verify each against the actual source before committing to it — the point is that you should be reading the source, because there is no downstream usage to learn from.

1. Per-request theme selection. The core pattern is a request listener that resolves a theme identifier (from hostname, a header, a user attribute, or a route parameter) and stores it in a request attribute or a service. Wire your controllers/templates to pull from that resolver rather than hardcoding:

$theme = $request->attributes->get('stg_theme');

2. Template path injection. Most theme bundles prepend a Twig path loader (e.g. templates/themes/{theme}/) ahead of the default templates/ directory, letting the theme override templates by filename. Test the fallback chain explicitly: a template missing from the theme should fall through to the base, not 500.

3. Asset handling. Themes almost always ship their own CSS/JS. Check whether the bundle uses assets:install into public/bundles/... or an AssetMapper/encore-style path. Government bundles often assume the old web/ directory — a red flag on Symfony 5+.

4. Config-driven theme registry. Define available themes in config/packages/stg_theme.yaml rather than in code:

stg_theme:
    default: base
    themes:
        base:  { path: '%kernel.project_dir%/templates/themes/base' }
        santa_fe: { path: '%kernel.project_dir%/templates/themes/santafe' }

Then let the bundle expose a ThemeManager/ThemeResolver service. Inject that service into controllers and Twig extensions rather than re-implementing resolution logic.

5. Multi-tenant / subdomain integration. If you're using this in a multi-tenant app, the cleanest integration is to implement its resolver interface (if it defines one) and register your resolver as a tagged service, so tenant lookup stays in your code and theming stays in the bundle. Do not fork the resolution listener just to add subdomain logic — check for a tag/interface hook first.

6. Twig extension for template-level branching. Expect a theme_asset() or theme_path() Twig function. Use it everywhere rather than building paths in PHP:

<link rel="stylesheet" href="{{ theme_asset('css/app.css') }}">

Gotchas and Tips

Symfony version drift is the #1 risk. A Santa Fe government bundle from a few years ago is likely pinned to Symfony 3.4/4.4 conventions: AppBundle, web/ public dir, @Route annotations, getRootDir(). On Symfony 5+ you'll hit deprecations or hard failures in the compiler pass. Read composer.json and the bundle's Resources/config/services.xml before installing.

Zero dependents means zero battle-testing. There is no StackOverflow answer, no GitHub issue thread from another team, no example app. Budget time for source-reading. Clone the repo into vendor/ and read EventListener/, Twig/, and DependencyInjection/ in that order — that's ~80% of the bundle's behavior.

Cache is your enemy during setup. Theme path prepending is usually done via a compiler pass or a prepend on the Twig loader. bin/console cache:clear after every config tweak; if template resolution "doesn't change," you probably have a stale container. Use bin/console debug:twig to confirm which paths are actually registered and in what order.

Watch for hardcoded absolute paths. Internal bundles frequently reference __DIR__.'/../../../../app/... or expect a specific directory layout. If paths look odd, grep for __DIR__ and %kernel.root_dir% (old parameter) — %kernel.project_dir% is the modern equivalent and a quick rename may be needed.

Config quirks to check explicitly:

  • Extension alias (is it stg_theme or theme? — affects your YAML root key).
  • Whether default is required or assumed.
  • Type coercion on the resolver strategy (e.g. resolver: hostname vs a service id).

Run bin/console config:dump-reference <alias> once it installs — it will tell you more than the README.

Debugging template resolution. When a theme renders the wrong template, drop a dump() into the Twig loader's getSourceContext() or temporarily add a tagged Twig extension that prints theme_name and theme_path. Compare against debug:twig output. Nine times out of ten the issue is loader precedence, not the resolver.

Extension points to look for (and prefer):

  • A ThemeResolverInterface you can implement and tag — cleanest way to add your own resolution strategy (subdomain, header, feature flag) without forking.
  • A ThemeEvent dispatched on resolution — lets you override per-request without touching the bundle.
  • A Twig namespace convention (e.g. @theme/...) you can reuse in your app's own theme code.

Fork-first decision criteria. If any of these are true, fork into your own src/ or a packages/ monorepo path rather than requiring it:

  • No release tag in the last 18 months.
  • Requires Symfony < 5.
  • Has no tests in tests/.
  • Hardcodes web/ or AppBundle.

A theme resolver is ~200 lines of code; vendoring a fork is often cheaper than fighting an abandoned internal bundle, and you keep the ability to patch paths and Symfony compatibility yourself. Note in your fork's README where it came from (Secretaría de Tecnologías, Santa Fe) — attribution to a public-sector source is both courteous and useful for the next maintainer.

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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings