Install Laravel Themes Manager
masterInstall the package using Composer. This package requires PHP 7.4 and Laravel 7.0 or higher. The service provider is registered automatically upon installation.
composer require hexadog/laravel-themes-managerrepository·master·Indexed 41 days ago
https://github.com/hexadog/laravel-themes-managerA package for developing multi-theme Laravel applications. It provides tools for theme scaffolding via `theme:make`, theme discovery through `ThemeFinder`, and a `ThemeLoader` middleware to apply active themes to requests. Includes Blade components and directives for resolving theme-specific assets, styles, scripts, and page titles, as well as facades for managing active themes.
Install the package using Composer. This package requires PHP 7.4 and Laravel 7.0 or higher. The service provider is registered automatically upon installation.
composer require hexadog/laravel-themes-managerTo customize the package behavior, publish the configuration file to config/themes-manager.php using the Artisan vendor publish command.
php artisan vendor:publish --provider="Hexadog\ThemesManager\Providers\PackageServiceProvider"To customize the package behavior or override default views, you can publish the assets using the following Artisan commands:
To publish the configuration file:
php artisan vendor:publish --tag=configTo publish the default views:
php artisan vendor:publish --tag=viewsThe ThemeFinder uses the themes-manager.directory configuration key to determine where to look for theme packages. If this key is not set, it defaults to the themes directory at the root of your Laravel application (base_path('themes')).
// In config/themes-manager.php
return [
'directory' => 'custom_themes_folder', // Defaults to 'themes'
];The <x-script> Blade component is used to render script tags with URLs resolved through the ThemesManager. It automatically handles asset path resolution based on the active theme.
Pass the relative path to the script as the src attribute. By default, the component generates an absolute URL. You can toggle this behavior using the absolute boolean attribute.
{{-- Renders an absolute URL to the script --}}
<x-script src="js/app.js" />
{{-- Renders a relative URL to the script --}}
<x-script src="js/app.js" :absolute="false" />The ThemeFinder::find() method scans the configured themes directory to identify and instantiate available theme packages. It looks for directories containing a composer.json file (up to 2 levels deep) and ignores node_modules and vendor directories.
For each discovered package, it extracts metadata from composer.json to create a Theme object. The following metadata is mapped:
name: The unique identifier for the theme.version: The theme version (defaults to 0.1).description: A brief description of the theme.extra.theme.parent: The parent theme identifier.extra.theme: An array of additional theme configuration.extra.theme.screenshot: A path or URL to a theme screenshot.The method returns an Illuminate Support\ Collection of Theme objects, keyed by the theme's name.
use Hexadog\ThemesManager\ThemeFinder;
// Returns a collection of Theme objects keyed by their name
$themes = ThemeFinder::find();
foreach ($themes as $name => $theme) {
echo "Found theme: " . $name . " (Version: " . $theme->getVersion() . ")\n";
}The ThemesManager class is the primary entrypoint for controlling which theme is currently active in your Laravel application. You can retrieve all available themes, check for existence, or switch the active theme.
all(): Returns a Collection of all scanned themes.has(?string $name): Checks if a theme with the specified name exists.get(?string $name): Retrieves a specific Theme instance by name. If no name is provided, it returns all themes.set(string $name): Sets a new active theme. This method disables the current theme before enabling the new one. It throws a ThemeNotFoundException if the theme does not exist.current(): Returns the currently enabled Theme instance.enable(string $name, bool $withEvent = true): Enables a specific theme by name.disable(string $name, bool $withEvent = true): Disables a specific theme by name.// Get all themes
$themes = $themesManager->all();
// Check if a theme exists
if ($themesManager->has('my-theme')) {
// Switch to the theme
$themesManager->set('my-theme');
}
// Get the currently active theme
$currentTheme = $themesManager->current();The ThemeLoader middleware is responsible for detecting and applying the active theme to an incoming HTTP request.
Behavior:
$request->expectsJson()) or if the application is running in the console (app()->runningInConsole()).ThemesManager::set($theme).themes-manager.fallback_theme configuration key.To use it, register the middleware in your app/Http/Kernel.php or within your route definitions.
// Example: Applying a specific theme to a route group
Route::middleware(['theme:dark'])->group(function () {
// Routes in this group will use the 'dark' theme
});The <x-style /> Blade component is used to render theme-specific style URLs. It automatically resolves the provided source path to the correct asset URL using the ThemesManager::asset() method.
Pass the relative path to the asset as the src attribute. By default, the component resolves the path as an absolute URL (absolute = true).
{{-- Render an absolute theme asset URL --}}
<link rel="stylesheet" href="<x-style src="css/theme.css" />">
{{-- Render a relative theme asset URL --}}
<link rel="stylesheet" href="<x-style src="css/theme.css" :absolute="false" />">The findByName method allows you to locate a specific theme. It handles name normalization by stripping -theme or theme- suffixes.
It supports finding themes using:
/ (e.g., vendor/name), it treats the part before the slash as the vendor and the part after as the theme name.$vendor string to the method to narrow the search.// Find by simple name
$theme = $themesManager->findByName('my-theme');
// Find by vendor/name syntax
$theme = $themesManager->findByName('hexadog/default');
// Find by name with explicit vendor parameter
$theme = $themesManager->findByName('default', 'hexadog');The ThemesManager provides helper methods to generate HTML tags for assets (CSS, JS, Images) belonging to the currently active theme. This ensures that paths are correctly resolved to the theme's directory.
asset(string $asset, bool $absolute = true): Returns the URL for a theme asset.style(string $asset, bool $absolute = true): Returns a <link> HTML tag for a CSS stylesheet.script(string $asset, string $mode = '', bool $absolute = true, string $type = 'text/javascript', string $level = 'functionality'): Returns a <script> HTML tag. Includes data-type and data-level attributes.image(string $asset, string $alt = '', string $class = '', array $attributes = [], bool $absolute = true): Returns an <img> HTML tag with support for alt text, classes, and custom attributes.mix(string $asset, string $manifestDirectory = ''): Returns the path to a versioned asset using Laravel Mix, resolved against the current theme's URL.// CSS link tag
echo $themesManager->style('css/app.css');
// JavaScript script tag
echo $themesManager->script('js/app.js', '', true, 'module', 'core');
// Image tag
echo $themesManager->image('images/logo.png', 'Company Logo', 'img-fluid', ['id' => 'logo']);
// Laravel Mix integration
$url = $themesManager->mix('js/app.js');The @pagetitle directive generates a <title> tag using the page_title() helper. It accepts two arguments:
$with_app_name (boolean): Whether to include the application name in the title. Defaults to true if not provided or if a truthy value is passed.$separator (string): The character used to separate the page title from the app name. Defaults to '-' if not provided.Note: The first argument must be a boolean literal or a string that can be validated as a boolean.
{{-- Default: includes app name with '-' separator --}}
@pagetitle
{{-- Custom: no app name, using ' | ' separator --}}
@pagetitle(false, ' | ')