FEATURE #1427: add homepage functionality.
Displaying homepage now depends on module handler
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
/resources/views/modules
|
||||||
|
**/views/**/custom/*
|
||||||
|
!**/views/**/custom/.gitkeep
|
||||||
/public/uploads/*
|
/public/uploads/*
|
||||||
!/public/uploads/.gitkeep
|
!/public/uploads/.gitkeep
|
||||||
/resources/views/vendor
|
/resources/views/vendor
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
<?php
|
||||||
|
namespace App\Helpers;
|
||||||
|
|
||||||
|
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
||||||
|
|
||||||
|
class Template
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Getter for real template name
|
||||||
|
*
|
||||||
|
* @param $template
|
||||||
|
*
|
||||||
|
* @return null|string
|
||||||
|
*/
|
||||||
|
public static function name($template)
|
||||||
|
{
|
||||||
|
|
||||||
|
$namespace = null;
|
||||||
|
if (strpos($template, '::')) {
|
||||||
|
list($namespace, $template) = explode('::', $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
$theme = config('app.theme');
|
||||||
|
|
||||||
|
// list of prefixes
|
||||||
|
$prefixes = [$theme . '.custom.', $theme . '.', ''];
|
||||||
|
|
||||||
|
$view = null;
|
||||||
|
foreach ($prefixes as $prefix) {
|
||||||
|
if (view()->exists($namespace . 'visitor.' . $prefix . $template)) {
|
||||||
|
$view = $namespace . 'visitor.' . $prefix . $template;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_null($view)) {
|
||||||
|
throw new InvalidArgumentException('Cannot find template for ' . $namespace . $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
return $view;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,10 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
use Illuminate\Foundation\Bus\DispatchesJobs;
|
use App\Helpers\Template;
|
||||||
use Illuminate\Routing\Controller as BaseController;
|
|
||||||
use Illuminate\Foundation\Validation\ValidatesRequests;
|
|
||||||
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
|
||||||
|
use Illuminate\Foundation\Bus\DispatchesJobs;
|
||||||
|
use Illuminate\Foundation\Validation\ValidatesRequests;
|
||||||
|
use Illuminate\Routing\Controller as BaseController;
|
||||||
|
|
||||||
class Controller extends BaseController
|
class Controller extends BaseController
|
||||||
{
|
{
|
||||||
@@ -16,15 +17,16 @@ class Controller extends BaseController
|
|||||||
*
|
*
|
||||||
* This method will be used for switching among templates.
|
* This method will be used for switching among templates.
|
||||||
*
|
*
|
||||||
* @todo add template support
|
* @param $template
|
||||||
*
|
|
||||||
* @param null $view
|
|
||||||
* @param array $data
|
* @param array $data
|
||||||
* @param array $mergeData
|
* @param array $mergeData
|
||||||
*
|
*
|
||||||
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
|
||||||
*/
|
*/
|
||||||
protected function view($view = null, $data = [], $mergeData = []) {
|
public static function VisitorsView($template, $data = [], $mergeData = [])
|
||||||
|
{
|
||||||
|
$view = Template::name($template);
|
||||||
|
|
||||||
return view($view, $data, $mergeData);
|
return view($view, $data, $mergeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,11 +9,28 @@ use Illuminate\Support\Facades\Auth;
|
|||||||
|
|
||||||
class ContentPage extends Controller
|
class ContentPage extends Controller
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var Content
|
||||||
|
*/
|
||||||
|
protected $content;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param Content $content
|
||||||
|
*/
|
||||||
|
function __construct(Content $content)
|
||||||
|
{
|
||||||
|
|
||||||
|
$this->content = $content;
|
||||||
|
}
|
||||||
|
|
||||||
public function getPage($url)
|
public function getPage($url)
|
||||||
{
|
{
|
||||||
$page = Content::where('url', $url)
|
$page = $this->content->getByURL($url);
|
||||||
->where('status', '!=', Content::STATUS_DELETED)
|
|
||||||
->first();
|
// no page available
|
||||||
|
if (!$page) {
|
||||||
|
abort(404);
|
||||||
|
}
|
||||||
|
|
||||||
return $this->renderPage($page);
|
return $this->renderPage($page);
|
||||||
}
|
}
|
||||||
@@ -38,6 +55,5 @@ class ContentPage extends Controller
|
|||||||
|
|
||||||
// render page
|
// render page
|
||||||
return $handler->render($page, '');
|
return $handler->render($page, '');
|
||||||
// return call_user_func([$handler, 'render'], $page);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,24 +3,24 @@
|
|||||||
namespace App\Http\Controllers\Visitor;
|
namespace App\Http\Controllers\Visitor;
|
||||||
|
|
||||||
use App\Http\Requests;
|
use App\Http\Requests;
|
||||||
use App\Models\Content;
|
|
||||||
use Symfony\Component\Process\Exception\InvalidArgumentException;
|
|
||||||
|
|
||||||
class Homepage extends ContentPage
|
class Homepage extends ContentPage
|
||||||
{
|
{
|
||||||
public function getIndex()
|
public function getIndex()
|
||||||
{
|
{
|
||||||
// try to find some homepage
|
// try to find some homepage
|
||||||
$page = Content::where('is_homepage', 1)
|
$page = $this->content->getHomepage();
|
||||||
->where('status', '!=', Content::STATUS_DELETED)
|
|
||||||
->first();
|
|
||||||
|
|
||||||
// test if we have any homepage
|
// test if we have any homepage
|
||||||
if (!$page) {
|
if (!$page) {
|
||||||
throw new InvalidArgumentException('Cannot load home page!');
|
return view('errors.homepageNotAvailable');
|
||||||
}
|
}
|
||||||
|
|
||||||
// render page
|
// render page
|
||||||
return $this->renderPage($page);
|
try {
|
||||||
|
return $this->renderPage($page);
|
||||||
|
} catch (\Exception $e) {
|
||||||
|
return view('errors.homepageNotAvailable');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+28
-15
@@ -4,21 +4,8 @@
|
|||||||
* This routing groups is used for routing along public part of website
|
* This routing groups is used for routing along public part of website
|
||||||
*/
|
*/
|
||||||
|
|
||||||
Route::group(['middleware' => ['web']], function () {
|
Route::pattern('id', '\d+');
|
||||||
|
Route::pattern('url', '[0-9\-a-z]+');
|
||||||
Route::get('/', 'Visitor\Homepage@getIndex')
|
|
||||||
->name('page.index');
|
|
||||||
|
|
||||||
// display login form
|
|
||||||
Route::get('login', function () {
|
|
||||||
return view('admin.loginForm.form');
|
|
||||||
})
|
|
||||||
->name('loginForm');
|
|
||||||
|
|
||||||
// handle login
|
|
||||||
Route::post('login', 'Admin\Login@postLogin')
|
|
||||||
->name('login');
|
|
||||||
});
|
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
|
|
||||||
@@ -193,3 +180,29 @@ Route::group([
|
|||||||
})
|
})
|
||||||
->name('logout');
|
->name('logout');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/**************************************************************************************/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This section must be specified as last one
|
||||||
|
*/
|
||||||
|
|
||||||
|
Route::group(['middleware' => ['web']], function () {
|
||||||
|
|
||||||
|
Route::get('', 'Visitor\Homepage@getIndex')
|
||||||
|
->name('page.index');
|
||||||
|
|
||||||
|
// display login form
|
||||||
|
Route::get('login', function () {
|
||||||
|
return view('admin.loginForm.form');
|
||||||
|
})
|
||||||
|
->name('loginForm');
|
||||||
|
|
||||||
|
// handle login
|
||||||
|
Route::post('login', 'Admin\Login@postLogin')
|
||||||
|
->name('login');
|
||||||
|
|
||||||
|
// route for all content pages. This rule must be specified last (because it matches every route)
|
||||||
|
Route::get('{url}', 'Visitor\ContentPage@getPage')
|
||||||
|
->name('page.content');
|
||||||
|
});
|
||||||
@@ -31,6 +31,41 @@ class Content extends Model
|
|||||||
const STATUS_PROTECTED = 'protected';
|
const STATUS_PROTECTED = 'protected';
|
||||||
const STATUS_PUBLIC = 'public';
|
const STATUS_PUBLIC = 'public';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for query with setup filter for non-deleted and non-draft pages
|
||||||
|
*/
|
||||||
|
protected function getPageQuery()
|
||||||
|
{
|
||||||
|
return Content::where('status', '!=', Content::STATUS_DELETED)
|
||||||
|
->where('status', '!=', Content::STATUS_DRAFT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for homepage content page
|
||||||
|
*
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function getHomepage()
|
||||||
|
{
|
||||||
|
return $this->getPageQuery()
|
||||||
|
->where('is_homepage', 1)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Getter for any page specified by its url.
|
||||||
|
*
|
||||||
|
* @param $url
|
||||||
|
*
|
||||||
|
* @return Content
|
||||||
|
*/
|
||||||
|
public function getByURL($url)
|
||||||
|
{
|
||||||
|
return $this->getPageQuery()
|
||||||
|
->where('url', $url)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Getter for overview of all content pages of given handler (module type)
|
* Getter for overview of all content pages of given handler (module type)
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -16,6 +16,14 @@ class GlobalViewDataProvider extends ServiceProvider
|
|||||||
{
|
{
|
||||||
view()->share('vendorName', 'ja s.r.o.');
|
view()->share('vendorName', 'ja s.r.o.');
|
||||||
|
|
||||||
|
// extend Blade "@extends" macro - with this macro allows to use "hierarchy" in templates
|
||||||
|
Blade::extend(function ($view) {
|
||||||
|
$pattern = $this->createPattern('extendVisitor');
|
||||||
|
$code = '@extends(\App\Helpers\Template::name($2))';
|
||||||
|
|
||||||
|
return preg_replace($pattern, $code, $view);
|
||||||
|
});
|
||||||
|
|
||||||
// register extension for rendering widget areas
|
// register extension for rendering widget areas
|
||||||
Blade::extend(function ($view) {
|
Blade::extend(function ($view) {
|
||||||
$pattern = $this->createPattern('widgetArea');
|
$pattern = $this->createPattern('widgetArea');
|
||||||
@@ -37,11 +45,8 @@ class GlobalViewDataProvider extends ServiceProvider
|
|||||||
?>
|
?>
|
||||||
';
|
';
|
||||||
|
|
||||||
|
|
||||||
return preg_replace($pattern, $code, $view);
|
return preg_replace($pattern, $code, $view);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -51,8 +56,9 @@ class GlobalViewDataProvider extends ServiceProvider
|
|||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function createPattern($function){
|
private function createPattern($function)
|
||||||
return '/(?<!\w)(\s*)@'.$function.'\(\s*(.*)\)/';
|
{
|
||||||
|
return '/(?<!\w)(\s*)@' . $function . '\(\s*(.*)\)/';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ return [
|
|||||||
*/
|
*/
|
||||||
'upload_url' => env('UPLOAD_URL', PHP_SAPI === 'cli' ? '' : url('uploads')),
|
'upload_url' => env('UPLOAD_URL', PHP_SAPI === 'cli' ? '' : url('uploads')),
|
||||||
'thumbnail_url' => env('THUMBNAIL_URL', PHP_SAPI === 'cli' ? '' : url('uploads/thumbnails')),
|
'thumbnail_url' => env('THUMBNAIL_URL', PHP_SAPI === 'cli' ? '' : url('uploads/thumbnails')),
|
||||||
|
|
||||||
|
'theme' => 'default_theme',
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
| Logging Configuration
|
| Logging Configuration
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<?php
|
||||||
|
return [
|
||||||
|
'welcome' => 'Welcome to my page'
|
||||||
|
];
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
@extendVisitor("errorLayout")
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div class="title">Home is not available at the moment.. Sorry for any inconvenience.</div>
|
||||||
|
@endsection
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
@yield('head_meta')
|
||||||
|
<title>@yield('pageName', @trans('visitor/common.welcome')) | {{$vendorName}}</title>
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/foundation.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/font-awesome.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/admin.css')}}" />
|
||||||
|
@yield('head_stylesheets')
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: #B0BEC5;
|
||||||
|
display: table;
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 72px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
|
||||||
|
<h1>Default theme template</h1>
|
||||||
|
<div class="content">
|
||||||
|
@yield('content')
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
@yield('head_meta')
|
||||||
|
<title>@yield('pageName', @trans('visitor/common.welcome')) | {{$vendorName}}</title>
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/foundation.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/font-awesome.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/admin.css')}}" />
|
||||||
|
@yield('head_stylesheets')
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: #B0BEC5;
|
||||||
|
display: table;
|
||||||
|
font-weight: 100;
|
||||||
|
font-family: 'Lato';
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 72px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
@yield('content')
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8" />
|
||||||
|
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
@yield('head_meta')
|
||||||
|
<title>@yield('pageName', @trans('visitor/common.welcome')) | {{$vendorName}}</title>
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/foundation.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/font-awesome.min.css')}}" />
|
||||||
|
<link rel="stylesheet" href="{{asset('../resources/assets/css/admin.css')}}" />
|
||||||
|
@yield('head_stylesheets')
|
||||||
|
|
||||||
|
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css">
|
||||||
|
|
||||||
|
<style>
|
||||||
|
html, body {
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
width: 100%;
|
||||||
|
color: #B0BEC5;
|
||||||
|
display: table;
|
||||||
|
font-weight: 100;
|
||||||
|
font-family: 'Lato';
|
||||||
|
}
|
||||||
|
|
||||||
|
.container {
|
||||||
|
text-align: center;
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.content {
|
||||||
|
text-align: center;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 72px;
|
||||||
|
margin-bottom: 40px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div class="container">
|
||||||
|
<div class="content">
|
||||||
|
@yield('content')
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user