Laravel views folder structure for different designs - laravel

I need some help - I want to change the whole design of my website, but I want to have the option to switch back to the old design.
My current folder structure is:
resources/views/frontend/...
I want to have the following folder structure:
resources/views/frontend/v1/...
resources/views/frontend/v2/...
In my config files I want to have a variable version, which will hold the active template version.
The problem is that now I need to use this variable in all Controllers and Views, which is a lot of work. I want to change the variable only in the Views. Does anybody have faced that situation and have a better solution for it ?

If you don't need to be able to switch the theme/design from an admin page, you can simply setup the path to your views in your config/view.php file:
/*
|--------------------------------------------------------------------------
| View Storage Paths
|--------------------------------------------------------------------------
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => [
resource_path('views'),
resource_path('theme/v1/views'),
],
Views in resources/theme/views/ will be loaded as well as the ones in the resources/views directory.
Beware of the order: the first path defined will have a higher priority if two files share the same name.
Another solution, to prevent file name collision, is to use namespaced views. In you AppServiceProvider, add this to the boot() method:
$this->loadViewsFrom(resource_path('theme2/views'), 'theme2');
See https://laravel.com/docs/6.x/packages#views
In both cases, you can use a variable in your configuration. For example, in your config/app.php:
return [
// Leave the configuration and add:
'theme' => 'v1',
];
Then, in config/view.php:
'paths' => [
resource_path('views'),
resource_path('theme/'.config('app.theme').'/views'),
],
If you want to use an environment variable (to have a different theme in local environment and production):
'paths' => [
resource_path('views'),
resource_path('theme/'.env('APP_THEME').'/views'),
],
and in your .env:
APP_THEME=v1

I've found a solution:
I've added namespaces in app\Providers\AppServiceProvider.php, in the boot method:
$this->app['view']->addNamespace('theme', base_path().'/resources/views/frontend/.config('version'));
Than I need in all Controllers and Views make some changes, but this is only one time.
In any Controller I changed from:
return view('frontend.partials.banner')->withBanner($banner);
to:
return view('theme::partials.banner')->withBanner($banner);
and in any view from:
#include('frontend.standing.partials.shorttable')
to:
#include('theme::standing.partials.shorttable')

Related

CS-Cart new template for Product Filters block

I want to add a new template option for the product filters block.
So far, I have copied the existing original.tpl from:
templates\blocks\product_filters
and put it into:
templates\addons\my_changes\blocks\product_filters
then I've renamed the file to: example.tpl and edited the top line of the file to be:
{** block-description:example **}
This basic process has worked for other blocks but not for this product filters one. The only options available in the template list are 'Original', and 'Horizontal filters'.
Is there something special I need to do to make my new template show up?
Templates available to be used by blocks are defined at schema, which is located at "app/schemas/block_manager/blocks.php" file.
Usually schema contains a path to a directory containing all templates that can be used by a block, like it's done for the "products" block:
'templates' => 'blocks/products',
Which makes block manager search templates at design/themes/[theme name]/templates/blocks/products directory.
Unfortunately, by some reasons the schema of the "product_filters" block is inconsistent compared to other block schemas - it contains the list of a concrete templates to be used:
'templates' => array(
'blocks/product_filters/original.tpl' => array(),
'blocks/product_filters/selected_filters.tpl' => array(),
'blocks/product_filters/horizontal_filters.tpl' => array(),
),
Because of that, no directory scan is being performed at a moment of determining a list of templates available for a block.
This is why the approach you're using worked for other blocks but not for "product_filters".
The solution for you is simple - you should create a "app/addons/my_changes/schemas/block_manager/blocks.post.php" file with the following content:
<?php
$schema['product_filters']['templates'] = 'blocks/product_filters';
return $schema;
After that please clear the cache and make sure that the "my_changes" add-on is installed and enabled.
Thanks for pointing out this problem, we'll fix it in an upcoming releases.

Laravel: best way to get locale time in my language in whole admin section?

I'm new to Laravel 5 (and to OOP in general) and I'm trying to switch from my old procedural code. In the whole admin section, I need to set the locale time to Italian for viewing purposes (i.e. show dates like "martedì 8 dicembre 2015" instead of "Tuesday 8 December 2015").
So far, I set 'locale' => 'it' in config/app.php and changed the routes.php file like this:
Route::group(['prefix' => 'admin'], function(){
setlocale(LC_TIME, config('app.locale'));
// here go all my routes
});
It works, but is this a correct approach (I mean, set a config in routes file)? Is there some more elegant way to keep routes separated from custom configs? Or is it better to keep simplicity like this?
More, I still don't know if this can affect the way dates are stored into database (at the moment I deal only with list of records, not with store or updates) - of course my dates should be stored as ISO
Thanks a lot
Don't forget that you canalso set this in your App/config/app.php file:
/*
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'Europe/Amsterdam',

How to set view file path in laravel?

I have a directory structure for laravel app like this:
app/
admin/
controllers/
views/ -> for admin views
...
views/ -> for frontend views
How can I set the view path for controllers in admin? I don't want to use View::addLocation or View::addNamespace because I might have the same view file name for admin and frontend, and don't want to add a namespace for every View::make('namespace::view.file').
I see in http://laravel.com/api/4.2/Illuminate/View/View.html there is a setPath method, but how do I call it? View::setPath raised undefined method error.
You have two ways to accomplish your goal. First, let's have a look at app/config/view.php. That's where the path(s) for view loading are defined.
This is the default:
'paths' => array(__DIR__.'/../views'),
Method 1: Load both directories
You can easily add the admin directory to the array
'paths' => array(
__DIR__.'/../views',
__DIR__.'/../admin/views
),
Now the big disadvantage of this: view names have to be unique. Otherwise the view in the path specified first will be taken.
Since you don't want to use a view namespace I suppose you don't want a syntax like admin.viewname either. You'll probably like method 2 more ;)
Method 2: Change the view page at runtime
Every Laravel config can be changed at runtime using the Config::set method.
Config::set('view.paths', array(__DIR__.'/../admin/views'));
Apparently setting the config won't change anything because it is loaded when the application bootstraps and ignored afterwards.
To change the path at runtime you have to create a new instance of the FileViewFinder.
Here's how that looks like:
$finder = new \Illuminate\View\FileViewFinder(app()['files'], array(app_path().'/admin/views'));
View::setFinder($finder);
Method 3: Use addLocation but without default path
You could also remove the default path in app/config/view.php
'paths' => array(),
And then use View::addLocation in any case (frontend and admin)
View::addLocation(app_path().'/views');
View::addLocation(app_path().'/admin/views');
In the latest version 6 i am doing it this ways:
View::getFinder()
->setPaths([
base_path('themes/frontend/views'),
base_path('themes/admin/views')]
)
In Laravel 5.5, other solutions did not work. In boot method of a service provider
View::getFinder()->prependLocation(
resource_path('views') . '/theme'
);
try it like this
View::addNamespace('admin', app_path() . '/admin/views');
Route::group(['prefix' => 'admin'], function() {
Route::get('/', function() {
return view('admin::index');
});
});

Laravel: How to find the right blade master template?

To extend a blade template you have to write
#extends('folder.template_name')
This works for standard installation.
I've created a module for the backend and now I can't use my module template because Laravel catches the first record and that is the standard view folder.
My structure looks like this:
app
-- modules
-- modules\backend
-- modules\backend\views
-- modules\backend\views\layouts\master.blade.php
-- views
-- views\layouts\master.blade.php
So when I'm in the backend and try to display my template:
// app\modules\backend\views\page\index.blade.php
#extends('layouts.master')
Laravel renders the app\views\layouts\master.blade.php instead of
app\modules\backend\views\layouts\master.blade.php
I've tried many names inside that #extends e.g.
#extends('app\modules\backend\views\layouts\master')
#extends('app.modules.backend.views.layouts.master')
#extends(base_path(). '\app\modules\backend\views\\' . 'layouts.master')
Nothing works.
While using a package or autoloaded module, referring to it's resources is done using the double colon notation. In your case, to access the module's master template you need to use
#extends('backend::layouts.master')
These conventions are described in the docs, for further info please refer to
Laravel 4 package conventions
Make sure /app/config/view.php has a path entry for where those views are located.
I.E.
'paths' => array(__DIR__.'/../views'),
To
'paths' => array(
__DIR__.'/../views',
__DIR__.'/../modules/backend/views'
),
or whatever represents your actual path.
From here you might want to look into doing the view folder loading via another mechanism if your views are in dynamically generated folders. Maybe a module::boot event that adds the module path to the view paths array? Just an idea.

Separate layouts and namespaces for frontend/backend in Zend application

I had to develop a CMS using Zend Framework and I used the default namespace defined in my boostrap for my backend:
autoloaderNamespaces[] = "Application_"
Now I want to develop the frontend, but I don't know how to do it, since I have access to my backend from the /public/ directory.
Then I would like to use a different layout for my frontend than the one I use for the backend access. So I found this post but I don't know if I have to change/add (and then how to change) the module of my backend, or if I have to create a second module that I will use for my frontend
my file tree is like this :
So if I create a frontend module, shall I create a frontend directory next to the applicationdirectory ?
EDIT : I created 2directories pub and frontend next to the application directory. In pub/index.php I instanciated the bootstrap with the application/configs/application.ini file with a different APPLICATION_FRONT_ENV :
[frontprod : production]
bootstrap.path = APPLICATION_FRONT_PATH "/bootstrap.php"
bootstrap.class = "Bootstrap"
resources.frontController.controllerDirectory = APPLICATION_FRONT_PATH "/controllers"
autoloaderNamespaces[] = "Frontend_"
resources.layout.layout = "layout"
resources.layout.layoutPath = APPLICATION_FRONT_PATH "/layouts/scripts"
[frontdev: frontprod]
phpSettings.display_startup_errors = 1
phpSettings.display_errors = 1
resources.frontController.params.displayExceptions = 1
and in the frontend/bootstrap.php I loaded models from applicationdirectory :
public function _initAutoloader(){
$baseAutoload = new Zend_Loader_Autoloader_Resource(array(
'namespace' => 'Application',
'basePath' => realpath(dirname(__FILE__).'/../application')
)
);
}
And it seems to be working fine =)
thank you !
In Zend Framework you can organise your app in modules, wich suits very well to your needs. Unfortunately the doc doesn't emphasize enough the importance of this concept, and how you should implement it from day one.
Modules allows you to regroup under a same module folder everything that is related to this module only, and this way to isolate "parts" of your app in logical groups.
In your case it would be "back" and "front", but you could also have a "forum" module or let's say a "shop" module.
In the urls point of view, the default routing of a modular structure is example.com/module/controller/action, but using hostname routes you can also have www.example.com pointing to your "front" module and admin.example.com pointing to your backend.
Have a look at the poor documentation section about modules, and don't panic, you won't have to rename everything if you move your current controllers, views and models in the "default" module.
There is an other alternative that could suit well for a backend/frontend logic, but not if you want to split your code in more logical parts (forum, blog, shop,...). You just create a second application folder (you would name 'frontend') next to the 'application' folder, and a second public directory (where you can symlink your assets folder if you use the sames), and a different namespace.
To be able to autoload your 'Application_' classes in your frontend code, just add and configure a Module Autoloader in your frontend bootstrap. The code is quite simple :
//in your frontend/Bootstrap.php
public function _initAutoloader(){
new Zend_Loader_Autoloader_Resource( array(
'namespace' => 'Application_',
'path' => realpath(dirname(__FILE__).'/../application'
)
);
}
For the application.ini config file i would recommend, instead of duplicating it, that you create a section [frontprod : production] section where you override your backend settings (and a matching [frontdev: frontprod] for your local settings).
I hope this helped. There is so much to say about all the topics introduced here that you should first have a look at this, then comment this answer with more specific questions about the problems you may encounter, and i'll extend the answer.

Resources