make themable

execute php artisan migrate to get theme_settings table
new commande available = create:theme-settings {theme_name?} Initialise les settings pour un nouveau theme
positionnement des blades dans un dossier défini par la nouvelle variable d'environnement APP_THEME (default : basic)
positionnement des ressources js et sass dans le dossier des blades du theme (pour mettre toute l'arboresence necessaire au thème sous une seule racine gitable)
This commit is contained in:
Olivier Legat 2021-03-05 11:37:13 +01:00
parent d2ad79ab1a
commit 421fe33763
35 changed files with 30621 additions and 53 deletions

View file

@ -3,6 +3,7 @@ APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
APP_THEME=basic
LOG_CHANNEL=stack
LOG_LEVEL=debug

1
.gitignore vendored
View file

@ -3,6 +3,7 @@
/public/storage
/storage/*.key
/vendor
/integration/
.env
.env.backup
.phpunit.result.cache

View file

@ -0,0 +1,60 @@
<?php
namespace App\Console\Commands;
use App\Models\ThemeSettings;
use Illuminate\Console\Command;
class CreateThemeSettings extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'create:theme-settings {theme_name?}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Initialise les settings pour un nouveau theme';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return int
*/
public function handle()
{
$theme_name = $this->argument('theme_name');
if(!$theme_name) {
$theme_name = $this->ask('theme name ?');
}
$bSettingExists = ThemeSettings::where('theme_name','=',$theme_name)->exists();
if($bSettingExists) {
$this->info('Settings for '.$theme_name. ' already exists.');
} else {
$theme_setting = new ThemeSettings();
$theme_setting->theme_name = $theme_name;
$theme_setting->site_name = "Nom du site";
$theme_setting->company = "Société";
$theme_setting->save();
$this->info('Settings created for '.$theme_name);
}
}
}

View file

@ -0,0 +1,12 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class ThemeSettings extends Model
{
use HasFactory;
protected $table = "theme_settings";
}

View file

@ -2,6 +2,9 @@
namespace App\Providers;
use App\Models\ThemeSettings;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\View;
use Illuminate\Support\ServiceProvider;
class AppServiceProvider extends ServiceProvider
@ -23,6 +26,12 @@ class AppServiceProvider extends ServiceProvider
*/
public function boot()
{
//
// On ramène le nom du site et autres infos cross pages
$settingsGlobal = Cache::get('settingsGlobal');
if (!$settingsGlobal) {
$settingsGlobal = ThemeSettings::find(1)->select('site_name', 'company', 'analytics')->where('theme_name','=',config('app.theme'))->first();
Cache::put('settingsGlobal', $settingsGlobal);
}
View::share('settingsGlobal', $settingsGlobal);
}
}

View file

@ -15,6 +15,17 @@ return [
'name' => env('APP_NAME', 'Laravel'),
/*
|--------------------------------------------------------------------------
| Application Front Views Folder
|--------------------------------------------------------------------------
|
| This value is the folder where blades will be found
|
*/
'theme' => env('APP_THEME','basic'),
/*
|--------------------------------------------------------------------------
| Application Environment

View file

@ -15,6 +15,7 @@ return [
'paths' => [
resource_path('views'),
resource_path('views/front/'.config('app.theme')),
],
/*

View file

@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class CreateThemeSettings extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('theme_settings', function (Blueprint $table) {
$table->id();
$table->string('theme_name');
$table->string('site_name');
$table->string('company');
$table->text('analytics')->nullable();
$table->timestamps();
$table->collation = 'utf8mb4_unicode_ci';
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('theme_settings');
}
}

View file

@ -16,5 +16,6 @@ class DatabaseSeeder extends Seeder
$this->call(ContentSeeder::class);
$this->call(SettingsSeeder::class);
$this->call(OrdersStatusSeeder::class);
$this->call(ThemeSettingsSeeder::class);
}
}

View file

@ -0,0 +1,22 @@
<?php
namespace Database\Seeders;
use Illuminate\Database\Seeder;
class ThemeSettings extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$settings = new Settings();
$settings->theme_name = "basic";
$settings->site_name = "Nom du site";
$settings->company = "Société";
$settings->save();
}
}

6
package-lock.json generated
View file

@ -5245,9 +5245,9 @@
}
},
"jquery": {
"version": "3.5.1",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.5.1.tgz",
"integrity": "sha512-XwIBPqcMn57FxfT+Go5pzySnm4KWkT1Tv7gjrpT1srtf8Weynl6R273VJ5GjkRb51IzMp5nbaPjJXMWeju2MKg==",
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/jquery/-/jquery-3.6.0.tgz",
"integrity": "sha512-JVzAR/AjBvVt2BmYhxRCSYysDsPcssdmTFnzyLEts9qNwmjmu4JTAMYubEfwVOSwpQ1I1sKKFcxhZCI2buerfw==",
"dev": true
},
"js-tokens": {

View file

@ -13,7 +13,7 @@
"axios": "^0.19",
"bootstrap": "^4.5.0",
"cross-env": "^7.0",
"jquery": "^3.2",
"jquery": "^3.6",
"laravel-mix": "^5.0.1",
"lodash": "^4.17.19",
"popper.js": "^1.12",

4
public/basic/css/app.css vendored Normal file
View file

@ -0,0 +1,4 @@
nav ol {
list-style: none;
}

30336
public/basic/js/app.js vendored Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,6 @@
{
"/b-o/js/app.js": "/b-o/js/app.js",
"/b-o/css/app.css": "/b-o/css/app.css"
"/b-o/css/app.css": "/b-o/css/app.css",
"/basic/css/app.css": "/basic/css/app.css",
"/basic/js/app.js": "/basic/js/app.js"
}

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Se connecter</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Inscription</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Mot de passe oublié ?</h1>

View file

@ -22,6 +22,14 @@
</ul>
</div>
@endif
<div class="form-group">
<label class="col-form-label">
Nom du site
<input type="text" name="site_name" class="form-control" value="{{$settingsToPrint['site_name']}}">
</label>
</div>
<div class="form-group">
<label class="col-form-label">
<input type="checkbox" name="has_costs" value="1" @if ($settingsToPrint['has_costs'] == "1") checked @endif>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Mon panier</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Contact</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>FAQ</h1><br/>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Home</h1>

7
resources/views/front/basic/js/app.js vendored Normal file
View file

@ -0,0 +1,7 @@
//front JS for the theme
require('./bootstrap');
$(document).ready(function() {
console.log('basic theme on');
});

View file

@ -0,0 +1,39 @@
window._ = require('lodash');
/**
* We'll load jQuery.
* This code may be modified to fit the specific needs of your application.
*/
try {
window.$ = window.jQuery = require('jquery');
} catch (e) {}
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Echo exposes an expressive API for subscribing to channels and listening
* for events that are broadcast by Laravel. Echo and event broadcasting
* allows your team to easily build robust real-time web applications.
*/
// import Echo from 'laravel-echo';
// window.Pusher = require('pusher-js');
// window.Echo = new Echo({
// broadcaster: 'pusher',
// key: process.env.MIX_PUSHER_APP_KEY,
// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
// forceTLS: true
// });

View file

@ -0,0 +1,38 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title') - {{$settingsGlobal->site_name}}</title>
<!-- Styles -->
<link href="{{ asset(config('app.theme').'/css/app.css') }}" rel="stylesheet">
</head>
<body>
<nav>
<ol>
<li><a href="{{ route('home') }}">Accueil</a></li>
<li><a href="{{ route('contact') }}">Contact</a></li>
<li><a href="{{ route('legal-notice') }}">Mentions Légales</a></li>
<li><a href="{{ route('terms') }}">CGV</a></li>
<li><a href="{{ route('privacy') }}">Politique de confidentialité</a></li>
<li><a href="{{ route('faq') }}">FAQ</a></li>
<li>-</li>
@auth
<li><a href="{{ route('auth.logout') }}">Se déconnecter</a></li>
@else
<li><a href="{{ route('auth.login') }}">Se connecter</a></li>
<li><a href="{{ route('auth.register') }}">Inscription</a></li>
<li><a href="{{ route('auth.reset-password') }}">Mot de passe oublié ?</a></li>
@endif
<li>-</li>
<li><a href="{{ route('basket') }}">Mon Panier</a></li>
<li>-</li>
<li><a href="{{ route('ranges') }}">Gammes de produits</a></li>
</ol>
</nav>
@yield('content')
<script src="{{ asset(config('app.theme').'/js/app.js') }}"></script>
@yield('scripts')
</body>
</html>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Mentions Légales</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Politique de confidentialité</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Produit "{{$product->name}}"</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Gamme de produits "{{$range->name}}"</h1>

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>Gammes de produits</h1>

View file

@ -0,0 +1,6 @@
//Front CSS for theme
nav {
ol {
list-style: none;
}
}

View file

@ -1,4 +1,4 @@
@extends('layouts.front-layout')
@extends('layouts.layout')
@section('content')
<h1>CGV</h1>

View file

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Laravel</title>
</head>
<body>
<nav>
<ol>
<li><a href="{{ route('home') }}">Accueil</a></li>
<li><a href="{{ route('contact') }}">Contact</a></li>
<li><a href="{{ route('legal-notice') }}">Mentions Légales</a></li>
<li><a href="{{ route('terms') }}">CGV</a></li>
<li><a href="{{ route('privacy') }}">Politique de confidentialité</a></li>
<li><a href="{{ route('faq') }}">FAQ</a></li>
<li>-</li>
@auth
<li><a href="{{ route('auth.logout') }}">Se déconnecter</a></li>
@else
<li><a href="{{ route('auth.login') }}">Se connecter</a></li>
<li><a href="{{ route('auth.register') }}">Inscription</a></li>
<li><a href="{{ route('auth.reset-password') }}">Mot de passe oublié ?</a></li>
@endif
<li>-</li>
<li><a href="{{ route('basket') }}">Mon Panier</a></li>
<li>-</li>
<li><a href="{{ route('ranges') }}">Gammes de produits</a></li>
</ol>
</nav>
@yield('content')
</body>
</html>

8
webpack.mix.js vendored
View file

@ -13,3 +13,11 @@ const mix = require('laravel-mix');
mix.js('resources/js/app.js', 'public/b-o/js')
.sass('resources/sass/app.scss', 'public/b-o/css');
//add front theme mix
//replace <theme> with you theme folder
// mix.js('resources/views/front/<theme>/js/app.js', 'public/<theme>/js')
// .sass('resources/views/front/<theme>/app.scss', 'public/<theme>/css');
mix.js('resources/views/front/basic/js/app.js', 'public/basic/js')
.sass('resources/views/front/basic/sass/app.scss', 'public/basic/css');