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

Themes Laravel Package

caffeinated/themes

Caffeinated Themes brings flexible, configurable theme support to Laravel apps. Organize views, assets, and settings into switchable themes, then render them cleanly through Blade with a simple, expressive API. It supports multiple themes and clean separation of layout and assets for multi-theme pro...

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install with Composer: composer require caffeinated/themes. On Laravel 5.5+ the ThemesServiceProvider and Theme facade are auto-discovered; on older versions add Caffeinated\Themes\ThemesServiceProvider::class and 'Theme' => Caffeinated\Themes\Facades\Theme::class to config/app.php.
  2. Publish the config: php artisan vendor:publish --provider="Caffeinated\Themes\ThemesServiceProvider" --tag=config. Open config/themes.php and note the two values that matter: path (defaults to base_path('themes')) and default (the theme name used when nothing else is set).
  3. Create a theme directory, e.g. themes/default/, with the conventional subfolders: views/, assets/, lang/, and config/. Drop a views/welcome.blade.php in it.
  4. First use case: set the theme and render. Theme::set('default'); return Theme::render('welcome'); — or reference the theme namespace directly with view('default::welcome'). In tinker, run Theme::all() and Theme::current() to confirm the package sees your folder.

Look first at the facade (Caffeinated\Themes\Facades\Theme), the manager class it resolves to, and the published config. Those three files explain 90% of the package.

Implementation Patterns

  • Per-request theme selection via middleware. Resolve the theme from subdomain, user preference, or locale in a middleware that runs before the controller, then call Theme::set($name). Keep the selection logic out of controllers so it applies globally.
  • Theme-aware rendering. For controller output, prefer Theme::render('home', $data) so the current theme is honored without hardcoding a namespace. Use view('mytheme::home') only when you intentionally want a specific theme.
  • Fallback pattern. Before rendering an optional view, check Theme::has('partials.hero') (or Theme::find($name)->getViewPath(...)) and fall back to a base theme. This is the cleanest way to ship a minimal theme and let a richer one override selectively.
  • Theme-local config. Each theme can carry its own config/ files, read through Theme::config('key') or the theme's getConfig(). Good place for per-theme branding, colors, and feature flags so code doesn't branch on theme name.
  • Admin/theme switcher. Theme::all() gives you the collection of discovered themes — iterate it to build a back-office picker, store the chosen name in user/settings, and apply it with Theme::set() on the next request.
  • Assets. Build URLs with Theme::asset('css/app.css') so links follow the active theme. For cache-busting, append your own version query string (the package doesn't do manifest/mix-style resolution per theme for you).
  • Caffeinated Modules integration. If you use caffeinated/modules, mirror a module's view namespace inside a theme's views/ directory to override module views per theme. This is the main reason to pick this package over rolling your own view-path swapping: it understands module namespaces.
  • Layout convention. Keep one views/layout.blade.php per theme and have all pages @extends('layout'). Because the theme's view path is prepended, the same template name resolves per theme without conditionals in Blade.

Gotchas and Tips

  • Assets are outside public/. The default path is base_path('themes'), so Theme::asset() produces a URL your web server likely can't serve. Either symlink themes/*/assets into public/themes, publish assets on deploy, or point the config at a directory inside public/. This is the #1 source of "styles are 404ing" reports.
  • Last release was March 2021. Verify against your Laravel version before committing — the service provider and facade may need a fork or a composer.json override for Laravel 10/11 (signature changes in ServiceProvider, container bindings, etc.). Budget an afternoon to smoke-test, not a sprint.
  • View cache. After adding or moving theme views, run php artisan view:clear. Namespaced views are cached by resolved path, and stale compiled files will silently serve the old theme's markup.
  • Order matters. Theme::set() must run before the response is built. Calling it from a view composer or a controller that has already returned a view has no effect. Put it in middleware.
  • Octane/long-running workers. The current theme is process state. If you run Octane, reset it at the start of every request in middleware; otherwise theme selection leaks between requests.
  • Namespace collisions. Don't name a theme the same as a Composer package's view namespace (errors, pagination, etc.) — the prepended theme path will shadow the framework's views in confusing ways.
  • config:cache is safe, but keep logic out of it. The default theme value is cached; runtime Theme::set() still works. Don't try to compute the default dynamically inside the config file.
  • Debugging checklist: Theme::exists($name), Theme::current(), Theme::all()->keys(), and confirm config('themes.path').'/'.$name.'/views' actually exists. Most "view not found" issues are a misnamed folder or a missing .blade.php extension.
  • Extension point: themes are discovered from the filesystem at boot, so adding a theme at runtime means adding the directory and clearing the view cache — there's no registration step. If you need custom theme behavior, subclass or wrap the theme class rather than editing vendor code.
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.
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent
sierratecnologia/media-manager