felixfrey/laravel-theme
Theme support for Laravel
This package is a fork of yaap/theme, which in turn was inspired by bigecko/laravel-theme, a theme manager for Laravel 4.
Themes are stored in the themes folder of your project by default (see path in the package config).
Introduction
This package provides a simple way to manage themes in Laravel applications.
For example, you can develop multiple themes for your application and easily switch between themes for different purposes.
Requirements
This version requires PHP 8.1 and supports Laravel 10.39 and newer, up to Laravel 13.
This package also provides support for Laravel Mix and Vite configurations.
| Package Version | Laravel 10 | Laravel 11 | Laravel 12 | Laravel 13 |
|---|---|---|---|---|
| 1 | :white_check_mark: (10.39+) | :white_check_mark: | :white_check_mark: | :white_check_mark: |
Installation
To get the latest version, simply require the project using Composer:
composer require "felixfrey/laravel-theme:^1.0.0"
or manually add line to composer.json
{
"require": {
"felixfrey/laravel-theme": "^1.0.0"
}
}
Optionally, publish config using artisan CLI (if you want to overwrite default config).
php artisan vendor:publish --provider="FelixFrey\LaravelTheme\ThemeServiceProvider"
Configuration
Package config
Config in config/theme.php file.
return [
/*
|--------------------------------------------------------------------------
| Path to directory with themes
|--------------------------------------------------------------------------
|
| The directory with your themes.
|
*/
'path' => base_path('themes'),
/*
|--------------------------------------------------------------------------
| Path to directory with assets build
|--------------------------------------------------------------------------
|
| The directory with assets build in public directory.
|
*/
'assets_path' => 'themes',
/*
|--------------------------------------------------------------------------
| A pieces of theme collections
|--------------------------------------------------------------------------
|
| Inside a theme path we need to set up directories to
| keep "layouts", "assets" and "partials".
|
*/
'containerDir' => [
'assets' => 'assets',
'lang' => 'lang',
'layout' => 'views/layouts',
'partial' => 'views/partials',
'view' => 'views',
],
];
Theme config
Config in theme folder. Placeholder %theme_name% will be replaced with theme name on creation.
return [
/*
|--------------------------------------------------------------------------
| Theme name
|--------------------------------------------------------------------------
|
| Use in assets publishing etc.
|
*/
'name' => '%theme_name%',
/*
|--------------------------------------------------------------------------
| Inherit from another theme
|--------------------------------------------------------------------------
|
| Set up inherit from another if the file is not exists.
|
*/
'inherit' => null,
];
Usage
Create theme with artisan CLI
Create command
The first time you have to create theme default structure, using the artisan command:
php artisan theme:create default
By default, it will use vite as assets builder. If you want to use laravel mix instead, pass mix as the second argument:
php artisan theme:create default mix
The assets builder must be vite or mix.
Theme names may contain letters, numbers, dashes, underscores and spaces. They are converted to snake case, so My Theme creates the folder themes/my_theme. If you run the command without a name, it asks for one.
If the theme already exists, the command asks whether to overwrite it. The files the command generates are then written again, and other files in the theme folder stay as they are. To overwrite without the question, add --force:
php artisan theme:create default --force
Destroy command
To delete an existing theme, use the command:
php artisan theme:destroy default
The command asks for confirmation and exits with an error if you decline. To delete the theme without the question, for example in a script, add --force:
php artisan theme:destroy default --force
Structure
Here is an example of the folder structure of project with theme
project-root
├── app/
<...>
├── public/
| ├── index.php
| └── themes/
| └── default/
| ├── js/
| | └── app.js
| ├── css/
| | └── styles.css
| └── images/
| └── icon.png
├── resources/
<...>
├── themes/
| ├── default/
| | ├── assets/
| | ├── lang/
| | ├── views/
| | | ├── layouts/
| | | ├── partials/
| | | └── hello.blade.php
| | └── config.php
| └── admin/
| ├── views/
| | ├── emails/
| | | └── notify.blade.php
| | └── hello.blade.php
| └── config.php
Init theme
To init and use theme in your application, add the following code to any boot method in application service provider (e.g. AppServiceProvider):
use FelixFrey\LaravelTheme\Facades\ThemeLoader;
class AppServiceProvider extends ServiceProvider
{
public function boot()
{
ThemeLoader::init('default');
}
}
This will add to views find path:
themes/{$name}(for layouts such aslayouts.master)themes/{$name}/views
Views in your application's own view paths, such as resources/views, take precedence over theme views with the same name.
Lang files will be added as well:
themes/{$name}/lang
They are registered under the theme name, so you use them with the theme name as namespace:
__('default::labels.intro');
Theme inheritance
Set inherit in the config.php of a theme to the name of another theme. Views that are missing in the child theme are then loaded from the parent theme, and the parent theme can inherit from another theme in turn.
Translations are not inherited. Only the lang folder of the theme passed to init() is registered.
Errors
ThemeLoader::init() throws a FelixFrey\LaravelTheme\Exceptions\ThemeException when:
- the theme name is empty
- the folder of the theme or of a parent theme does not exist
- the name of the theme or of a parent theme is not a single folder inside the themes path, for example
../sharedorclients/acme - the inheritance is circular, for example two themes that inherit from each other
If init() throws, no view paths of the failed theme are registered.
Making view
View::make('hello');
View::make('emails.notify');
// or
view('hello');
view('emails.notify');
Assets
Vite
If you use Vite, ensure vite.config.js have specified the input path for theme
import {defineConfig} from 'vite';
import laravel from 'laravel-vite-plugin';
export default defineConfig({
plugins: [
laravel({
input: [
'themes/default/assets/js/app.js', // for default theme
// ...
],
refresh: true,
}),
],
});
Because app.js includes app.scss you can use the following code to include assets in your views:
<head>
<!--...-->
@vite([
'themes/default/assets/js/app.js',
])
</head>
Laravel Mix
If you use Laravel Mix, ensure webpack.mix.js have specified mix configuration for theme
const mix = require('laravel-mix');
mix.disableNotifications();
mix.browserSync({
open: true,
proxy: 'localhost:8000',
files: [
'app/**/*',
'routes/**/*',
'themes/**/*', // manually add this line
]
});
// other configurations...
// mix for default theme
mix.copyDirectory('themes/default/assets/img', 'public/themes/default/img');
mix.copyDirectory('themes/default/assets/fonts', 'public/themes/default/fonts');
// js
mix.js(['themes/default/assets/js/app.js'], 'public/themes/default/js/app.min.js')
// sass
mix.sass('themes/default/assets/sass/app.scss', 'public/themes/default/css/app.min.css')
Then you can use the following code to include assets in your views:
in the <head> tag
<head>
<!--...-->
<link rel="stylesheet" href="{{ mix('/themes/default/css/app.min.css') }}"/>
</head>
and before </body> tag
<body>
<!--...-->
<script type="text/javascript" src="{{ mix('/themes/default/js/app.min.js') }}"></script>
</body>
To use images, you can use the following code:
<img src="{{ mix('themes/default/img/icon.png') }}" alt="icon">
Building layouts
Layouts using Components
Layouts using template inheritance
To build layouts we use template inheritance.
You can use @extends directive to specify a parent layout.
@extends('layouts.master')
@include('partials.header')
@section('content')
<section id="main">
<h1>HOME</h1>
</section>
@stop
@include('partials.footer')
Fallback capability
You still able to use default View::make('emails.notify') which is stored outside the themes directory.
Testing
composer test
License
MIT license.
Related Packages
Theme will help you organize your themes inside Laravel projects easily and main...
Theme will help you organize your themes inside Laravel projects easily and main...
Theme will help you organize your themes inside Laravel projects easily and main...
Version History
| Version | Released | PHP | Laravel | License |
|---|---|---|---|---|
| v1.1.0 | ^8.1 | ^10.0| | MIT | |
| 1.0.0 | ^8.1 | ^10.0| | MIT |