I am developing an application with Laravel 4, I am developing package for admin panel for it, now I need to have some some kind of settings to be shared in the whole package, in this case need an array that holds the whole models' names.
Question:
Where is the best location to store this setting? and if it is in the config.php file how do I have to use the variables stored in that in application, because it's simply a PhP file which returns an array and I have no idea how to access this file and retrieve its data
You can put your configuration in a php file inside the app/config or package src/config directory.
For example, you can have a myconfig.php with the following contents:
<?php
return array(
'config_name' => array('value1', 'value2', 'value3')
);
?>
You can get the value of 'config_name' with the following code:
Config::get('myconfig.config_name')
Related
I've an unusual and interesting problem that I am trying to solve.
We had to put some of our blade views to S3 storage and render them from S3 url with passed variables.
For example:
view('page.user.show', ['user' => User::first()])->render();
Now, since we have our page.user.show blade file stored in S3 storage on the path "/views/pages/user/show.blade.php"
We somehow need to make Laravel get that view from s3 URL path instead from resource_path
So we need something like this:
view('s3url.com/views/pages/user/show.blade.php', ['user' => User::first()])->render();
Is there any way we can do this in Laravel ? Or, at least read content of blade file from S3 path and render that string content with variables?
To achieve something like this, you'll need to implement a custom version of the Laravel Illuminate\View\ViewFinderInterface. Your best bet is to create a new view finder that can load blade templates from S3 and move them to the local filesystem temporarily.
You can probably just extend the FileViewFinder class, and add some custom logic to the find() method. In there, try something like:
if (Str::startsWith($name, 's3::')) {
// This gets a temp file that PHP will clean up for you
$name = stream_get_meta_data(tmpfile())['uri'];
// Download the Blade template from S3 and store it temporarily
file_put_contents($name, Storage::disk('s3')->get(Str::after($name, 's3::')));
// Return the path
return $name;
}
Then you'll need to swap in your new finder using View::setFinder.
The major downside of this approach is that you'll need to download views from S3 every time you render them. You probably want to at least add some caching to the system so that you're not hitting S3 every time a page loads.
I have two folder in view file. like:
template1
template2
I want to see all the file list from specific folder. and check there is any specific blade file have or not. So i dont know how to do this.
thanks.
If you want to list all views, you could use the File facade to get an array of all the files included in your views folder. This will not show vendor views unless they have been published.
use Illuminate\Support\Facades\File;
$views = collect(File::allFiles(resource_path('views')))
->map->getPathName()
// ->filter(fn ($pathName) => ... ) // additional filtering
;
If you want to check if a specific view exists or not, the View facade has an exists method.
use Illuminate\Support\Facades\View;
View::exists('template1.some-view'); // returns true if template1/some-view.blade.php exists.
I solved my problem from here.
https://laravel.com/docs/9.x/views#determining-if-a-view-exists
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.
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');
});
});
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.