Implemented theming. A default "base" theme is provided that all themes can extend and override parts of if necessary without having to define every single screen.
Renamed Photo Perfect to Blue Twilight.
This commit is contained in:
parent
932f7017dc
commit
8baa0b06e7
4
.idea/webServers.xml
generated
4
.idea/webServers.xml
generated
@ -2,8 +2,8 @@
|
||||
<project version="4">
|
||||
<component name="WebServers">
|
||||
<option name="servers">
|
||||
<webServer id="b14a34b0-0127-4886-964a-7be75a2281ac" name="Development" url="http://photoperfect-dev.andys.eu">
|
||||
<fileTransfer host="photoperfect-dev.andys.eu" port="22" privateKey="C:\Users\andyheathershaw\.ssh\id_rsa" rootFolder="/srv/www/photoperfect" accessType="SFTP" passphrase="dff4dfcbdfc2df98df92dfe0dfe2df98df9adfdddfcedfdddf8e" username="root" keyPair="true">
|
||||
<webServer id="b14a34b0-0127-4886-964a-7be75a2281ac" name="Development" url="http://blue-twilight-dev.andys.eu">
|
||||
<fileTransfer host="andyhaa1.miniserver.com" port="22" privateKey="C:\Users\andyheathershaw\.ssh\id_rsa" rootFolder="/srv/www/blue-twilight-dev" accessType="SFTP" keyPair="true">
|
||||
<advancedOptions>
|
||||
<advancedOptions dataProtectionLevel="Private" />
|
||||
</advancedOptions>
|
||||
|
35
app/Configuration.php
Normal file
35
app/Configuration.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace App;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Notifications\Notifiable;
|
||||
|
||||
class Configuration extends Model
|
||||
{
|
||||
use Notifiable;
|
||||
|
||||
/**
|
||||
* The attributes that are mass assignable.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $fillable = [
|
||||
'key', 'value'
|
||||
];
|
||||
|
||||
/**
|
||||
* The attributes that should be hidden for arrays.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $hidden = [
|
||||
];
|
||||
|
||||
/**
|
||||
* The table associated with the model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $table = 'configuration';
|
||||
}
|
18
app/Facade/Theme.php
Normal file
18
app/Facade/Theme.php
Normal file
@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
namespace App\Facade;
|
||||
|
||||
use Illuminate\Support\Facades\Facade;
|
||||
|
||||
class Theme extends Facade
|
||||
{
|
||||
/**
|
||||
* Get the registered name of the component.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected static function getFacadeAccessor()
|
||||
{
|
||||
return 'theme';
|
||||
}
|
||||
}
|
79
app/Helpers/ThemeHelper.php
Normal file
79
app/Helpers/ThemeHelper.php
Normal file
@ -0,0 +1,79 @@
|
||||
<?php
|
||||
|
||||
namespace App\Helpers;
|
||||
|
||||
use App\Configuration;
|
||||
|
||||
class ThemeHelper
|
||||
{
|
||||
const DEFAULT_THEME = 'base';
|
||||
|
||||
public function current()
|
||||
{
|
||||
return $this->getThemeName();
|
||||
}
|
||||
|
||||
public function info()
|
||||
{
|
||||
$themeName = $this->getThemeName();
|
||||
$jsonFile = sprintf('%s/%s/theme.json', $this->getThemeBasePath(), $this->sanitiseThemeName($themeName));
|
||||
if (file_exists($jsonFile))
|
||||
{
|
||||
return json_decode(file_get_contents($jsonFile), true);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function render($viewPath, array $viewData = array())
|
||||
{
|
||||
$themeName = $this->getThemeName();
|
||||
|
||||
// First see if the current theme has the specified file
|
||||
$requestedViewFilename = $this->getRealFilePath($themeName, $viewPath);
|
||||
|
||||
if (!file_exists($requestedViewFilename))
|
||||
{
|
||||
// If it doesn't, revert to the base theme
|
||||
// TODO allow themes to specify another theme as the parent, and traverse up the theme tree to find the
|
||||
// relevant file - this allows for sub-themes
|
||||
$themeName = ThemeHelper::DEFAULT_THEME;
|
||||
}
|
||||
|
||||
return view(sprintf('themes.%s.%s', $themeName, $viewPath), $viewData);
|
||||
}
|
||||
|
||||
private function getRealFilePath($themeName, $viewPath)
|
||||
{
|
||||
return sprintf(
|
||||
'%s/%s/%s.blade.php',
|
||||
$this->getThemeBasePath(),
|
||||
$themeName,
|
||||
str_replace('.', DIRECTORY_SEPARATOR, $viewPath)
|
||||
);
|
||||
}
|
||||
|
||||
private function getThemeBasePath()
|
||||
{
|
||||
return sprintf('%s/resources/views/themes', dirname(dirname(__DIR__)));
|
||||
}
|
||||
|
||||
private function getThemeName()
|
||||
{
|
||||
$themeName = ThemeHelper::DEFAULT_THEME;
|
||||
|
||||
$currentTheme = Configuration::all()->where('key', 'theme')->first();
|
||||
if (!is_null($currentTheme))
|
||||
{
|
||||
$themeName = $currentTheme->value;
|
||||
}
|
||||
|
||||
return $this->sanitiseThemeName($themeName);
|
||||
}
|
||||
|
||||
private function sanitiseThemeName($themeName)
|
||||
{
|
||||
// Ensure nasty people can't try and trick us into traversing the directory tree
|
||||
return preg_replace('/[\\\.\/]/', '', strtolower($themeName));
|
||||
}
|
||||
}
|
@ -3,6 +3,7 @@
|
||||
namespace app\Http\Controllers\Admin;
|
||||
|
||||
use App\Album;
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Http\Requests;
|
||||
use Illuminate\Http\Request;
|
||||
@ -21,7 +22,7 @@ class AlbumController extends Controller
|
||||
|
||||
$albums = Album::all()->sortBy('name');
|
||||
|
||||
return view('admin.list_albums', [
|
||||
return Theme::render('admin.list_albums', [
|
||||
'albums' => $albums
|
||||
]);
|
||||
}
|
||||
@ -35,7 +36,7 @@ class AlbumController extends Controller
|
||||
{
|
||||
$this->authorize('admin-access');
|
||||
|
||||
return view('admin.create_album');
|
||||
return Theme::render('admin.create_album');
|
||||
}
|
||||
|
||||
public function delete($id)
|
||||
@ -44,7 +45,7 @@ class AlbumController extends Controller
|
||||
|
||||
$album = $this->loadAlbum($id);
|
||||
|
||||
return view('admin.delete_album', ['album' => $album]);
|
||||
return Theme::render('admin.delete_album', ['album' => $album]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,7 +76,7 @@ class AlbumController extends Controller
|
||||
|
||||
$album = $this->loadAlbum($id);
|
||||
|
||||
return view('admin.show_album', ['album' => $album]);
|
||||
return Theme::render('admin.show_album', ['album' => $album]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,7 +91,7 @@ class AlbumController extends Controller
|
||||
|
||||
$album = $this->loadAlbum($id);
|
||||
|
||||
return view('admin.edit_album', ['album' => $album]);
|
||||
return Theme::render('admin.edit_album', ['album' => $album]);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,7 +108,7 @@ class AlbumController extends Controller
|
||||
$album = $this->loadAlbum($id);
|
||||
$album->fromRequest($request)->save();
|
||||
|
||||
return view('admin.show_album', ['album' => $album]);
|
||||
return Theme::render('admin.show_album', ['album' => $album]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3,6 +3,7 @@
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Album;
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
|
||||
@ -14,7 +15,7 @@ class DefaultController extends Controller
|
||||
|
||||
$albumCount = Album::all()->count();
|
||||
|
||||
return view('admin.index', [
|
||||
return Theme::render('admin.index', [
|
||||
'album_count' => $albumCount
|
||||
]);
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\SendsPasswordResetEmails;
|
||||
|
||||
@ -29,4 +30,14 @@ class ForgotPasswordController extends Controller
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the form to request a password reset link.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showLinkRequestForm()
|
||||
{
|
||||
return Theme::render('auth.passwords.email');
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\AuthenticatesUsers;
|
||||
|
||||
@ -36,4 +37,14 @@ class LoginController extends Controller
|
||||
{
|
||||
$this->middleware('guest', ['except' => 'logout']);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application's login form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showLoginForm()
|
||||
{
|
||||
return Theme::render('auth.login');
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\User;
|
||||
use Validator;
|
||||
use App\Http\Controllers\Controller;
|
||||
@ -68,4 +69,14 @@ class RegisterController extends Controller
|
||||
'password' => bcrypt($data['password']),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the application registration form.
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showRegistrationForm()
|
||||
{
|
||||
return Theme::render('auth.register');
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers\Auth;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Foundation\Auth\ResetsPasswords;
|
||||
|
||||
@ -29,4 +30,20 @@ class ResetPasswordController extends Controller
|
||||
{
|
||||
$this->middleware('guest');
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the password reset view for the given token.
|
||||
*
|
||||
* If no token is present, display the link request form.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param string|null $token
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function showResetForm(Request $request, $token = null)
|
||||
{
|
||||
return Theme::render('auth.passwords.reset')->with(
|
||||
['token' => $token, 'email' => $request->email]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,12 +2,13 @@
|
||||
|
||||
namespace App\Http\Controllers\Gallery;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Http\Controllers\Controller;
|
||||
|
||||
class DefaultController extends Controller
|
||||
{
|
||||
public function index()
|
||||
{
|
||||
return view('gallery.index');
|
||||
return Theme::render('gallery.index');
|
||||
}
|
||||
}
|
@ -2,6 +2,9 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use App\Facade\Theme;
|
||||
use App\Helpers\ThemeHelper;
|
||||
use Illuminate\Support\Facades\View;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
class AppServiceProvider extends ServiceProvider
|
||||
@ -13,7 +16,12 @@ class AppServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
//
|
||||
$this->app->singleton('theme', function($app)
|
||||
{
|
||||
return new ThemeHelper();
|
||||
});
|
||||
|
||||
$this->addThemeInfoToView();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,4 +33,23 @@ class AppServiceProvider extends ServiceProvider
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
private function addThemeInfoToView()
|
||||
{
|
||||
$themeInfo = Theme::info();
|
||||
$themeInfoKeys = array('name', 'version');
|
||||
|
||||
// Add each valid theme info element to the view - prefixing with theme_
|
||||
// e.g. $themeInfo['name'] becomes $theme_name in the view
|
||||
foreach ($themeInfoKeys as $key)
|
||||
{
|
||||
if (isset($themeInfo[$key]))
|
||||
{
|
||||
View::share('theme_' . $key, $themeInfo[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
// Also add a theme_url key
|
||||
View::share('theme_url', sprintf('themes/%s', Theme::current()));
|
||||
}
|
||||
}
|
||||
|
@ -14,7 +14,7 @@ return [
|
||||
| any other location as required by the application or its packages.
|
||||
*/
|
||||
|
||||
'name' => 'Photo Perfect',
|
||||
'name' => 'Blue Twilight',
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -168,7 +168,6 @@ return [
|
||||
/*
|
||||
* Package Service Providers...
|
||||
*/
|
||||
|
||||
Collective\Html\HtmlServiceProvider::class,
|
||||
|
||||
/*
|
||||
@ -227,8 +226,10 @@ return [
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
// Additional aliases added by AH
|
||||
'Form' => Collective\Html\FormFacade::class,
|
||||
'Html' => Collective\Html\HtmlFacade::class,
|
||||
'Theme' => App\Facade\Theme::class,
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
|
||||
class CreateConfigTable extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function up()
|
||||
{
|
||||
Schema::create('configuration', function (Blueprint $table) {
|
||||
$table->increments('id');
|
||||
$table->string('key');
|
||||
$table->text('value');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function down()
|
||||
{
|
||||
Schema::drop('configuration');
|
||||
}
|
||||
}
|
6
public/bootstrap/css/bootstrap.min.css
vendored
6
public/bootstrap/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
4
public/font-awesome/css/font-awesome.min.css
vendored
4
public/font-awesome/css/font-awesome.min.css
vendored
File diff suppressed because one or more lines are too long
6
public/themes/base/bootstrap/css/bootstrap.min.css
vendored
Normal file
6
public/themes/base/bootstrap/css/bootstrap.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 106 KiB After Width: | Height: | Size: 106 KiB |
4
public/themes/base/font-awesome/css/font-awesome.min.css
vendored
Normal file
4
public/themes/base/font-awesome/css/font-awesome.min.css
vendored
Normal file
File diff suppressed because one or more lines are too long
Before Width: | Height: | Size: 382 KiB After Width: | Height: | Size: 382 KiB |
@ -1,5 +1,6 @@
|
||||
<?php
|
||||
return [
|
||||
'app_name' => 'Blue Twilight',
|
||||
'nav_admin' => 'Manage',
|
||||
'nav_admin_control' => 'Control Panel',
|
||||
'nav_admin_albums' => 'Albums'
|
||||
|
@ -1,2 +0,0 @@
|
||||
@extends('layouts.app')
|
||||
@section('title', 'Welcome')
|
@ -1,29 +0,0 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="generator" content="{{ config('app.name') }} v{{ config('app.version') }} (framework v{{ App::VERSION() }})">
|
||||
|
||||
<title>@yield('title') | {{ config('app.name') }}</title>
|
||||
<base href="{{ url('/') }}">
|
||||
|
||||
<link href="bootstrap/css/bootstrap.min.css?v={{ urlencode(config('app.version')) }}" rel="stylesheet">
|
||||
<link href="font-awesome/css/font-awesome.min.css?v={{ urlencode(config('app.version')) }}" rel="stylesheet">
|
||||
<link href="css/app.css?v={{ urlencode(config('app.version')) }}" rel="stylesheet">
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body>
|
||||
@include('partials.navbar')
|
||||
|
||||
<div class="container-fluid">
|
||||
@yield('content')
|
||||
</div>
|
||||
|
||||
<script src="js/jquery.min.js?v={{ urlencode(config('app.version')) }}"></script>
|
||||
<script src="bootstrap/js/bootstrap.min.js?v={{ urlencode(config('app.version')) }}"></script>
|
||||
<script src="js/app.js?v={{ urlencode(config('app.version')) }}"></script>
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', trans('admin.delete_album', ['name' => $album->name]))
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', 'Gallery Admin')
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
@section('title', $album->name)
|
||||
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
|
||||
<!-- Main Content -->
|
||||
@section('content')
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
@ -1,4 +1,4 @@
|
||||
@extends('layouts.app')
|
||||
@extends('themes.base.layout')
|
||||
|
||||
@section('content')
|
||||
<div class="container">
|
2
resources/views/themes/base/gallery/index.blade.php
Normal file
2
resources/views/themes/base/gallery/index.blade.php
Normal file
@ -0,0 +1,2 @@
|
||||
@extends('themes.base.layout')
|
||||
@section('title', 'Welcome')
|
31
resources/views/themes/base/layout.blade.php
Normal file
31
resources/views/themes/base/layout.blade.php
Normal file
@ -0,0 +1,31 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<meta name="generator" content="{{ config('app.name') }} v{{ config('app.version') }} (framework v{{ App::VERSION() }})">
|
||||
|
||||
<title>@yield('title') | @lang('global.app_name')</title>
|
||||
<base href="{{ url('/') }}">
|
||||
|
||||
{{-- Cannot use $theme_url here: if a theme uses the base layout, it would also have to provide all these dependencies! --}}
|
||||
<link href="themes/base/bootstrap/css/bootstrap.min.css?v={{ urlencode($theme_version) }}" rel="stylesheet">
|
||||
<link href="themes/base/font-awesome/css/font-awesome.min.css?v={{ urlencode($theme_version) }}" rel="stylesheet">
|
||||
<link href="themes/base/css/app.css?v={{ urlencode($theme_version) }}" rel="stylesheet">
|
||||
@stack('styles')
|
||||
</head>
|
||||
<body>
|
||||
@include('themes.base.partials.navbar')
|
||||
|
||||
<div class="container-fluid">
|
||||
@yield('content')
|
||||
</div>
|
||||
|
||||
{{-- Cannot use $theme_url here: if a theme uses the base layout, it would also have to provide all these dependencies! --}}
|
||||
<script src="themes/base/js/jquery.min.js?v={{ urlencode($theme_version) }}"></script>
|
||||
<script src="themes/base/bootstrap/js/bootstrap.min.js?v={{ urlencode($theme_version) }}"></script>
|
||||
<script src="themes/base/js/app.js?v={{ urlencode($theme_version) }}"></script>
|
||||
@stack('scripts')
|
||||
</body>
|
||||
</html>
|
@ -8,7 +8,7 @@
|
||||
<span class="icon-bar"></span>
|
||||
<span class="icon-bar"></span>
|
||||
</button>
|
||||
<a class="navbar-brand" href="{{ route('home') }}">{{ config('app.name') }}</a>
|
||||
<a class="navbar-brand" href="{{ route('home') }}">@lang('global.app_name')</a>
|
||||
</div>
|
||||
|
||||
<!-- Collect the nav links, forms, and other content for toggling -->
|
0
resources/views/themes/bootstrap3/.gitkeep
Normal file
0
resources/views/themes/bootstrap3/.gitkeep
Normal file
5
resources/views/themes/bootstrap3/README.txt
Normal file
5
resources/views/themes/bootstrap3/README.txt
Normal file
@ -0,0 +1,5 @@
|
||||
The "base" theme is actually using Bootstrap3, however in the UI the "base" theme is not visible - it's used to provide
|
||||
other themes a sensible default so they don't have to override every single view file.
|
||||
|
||||
Therefore this folder exists to allow users to select a theme called "bootstrap3" to get the default look-and-feel, but
|
||||
in actual fact, it's driven by the "base" theme.
|
6
resources/views/themes/bootstrap3/theme.json
Normal file
6
resources/views/themes/bootstrap3/theme.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"name": "Bootstrap 3",
|
||||
"version": "1.0",
|
||||
"author": "Andy Heathershaw",
|
||||
"author_email": "andy@andys.eu"
|
||||
}
|
Loading…
Reference in New Issue
Block a user