【发布时间】:2015-06-25 06:50:54
【问题描述】:
我如何在 Laravel 5 中创建全局变量,该变量将在所有 Blade 模板中可用?
【问题讨论】:
标签: templates laravel view laravel-5 blade
我如何在 Laravel 5 中创建全局变量,该变量将在所有 Blade 模板中可用?
【问题讨论】:
标签: templates laravel view laravel-5 blade
选项 1:
你可以像这样使用view::share():
<?php namespace App\Http\Controllers;
use View;
//You can create a BaseController:
class BaseController extends Controller {
public $variable1 = "I am Data";
public function __construct() {
$variable2 = "I am Data 2";
View::share ( 'variable1', $this->variable1 );
View::share ( 'variable2', $variable2 );
View::share ( 'variable3', 'I am Data 3' );
View::share ( 'variable4', ['name'=>'Franky','address'=>'Mars'] );
}
}
class HomeController extends BaseController {
//if you have a constructor in other controllers you need call constructor of parent controller (i.e. BaseController) like so:
public function __construct(){
parent::__construct();
}
public function Index(){
//All variable will be available in views
return view('home');
}
}
选项 2: 使用作曲家:
app\Composers\HomeComposer.php 创建一个作曲家文件
注意:如果 app\Composers 不存在,则创建它
<?php namespace App\Composers;
class HomeComposer
{
public function compose($view)
{
//Add your variables
$view->with('variable1', 'I am Data')
->with('variable2', 'I am Data 2');
}
}
然后您可以通过这样做将作曲家附加到任何视图
<?php namespace App\Http\Controllers;
use View;
class HomeController extends Controller{
public function __construct(){
View::composers([
'App\Composers\HomeComposer' => ['home'] //attaches HomeComposer to home.blade.php
]);
}
public function Index(){
return view('home');
}
}
选项 3: 将 Composer 添加到服务提供者,在 Laravel 5 中,我更喜欢将 Composer 放在 App\Providers\ViewServiceProvider 中
在app\Composers\HomeComposer.php创建一个作曲家文件
将 HomeComposer 添加到 App\Providers\ViewServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use View;
use App\Composers\HomeComposer;
use Illuminate\Support\Facades\Blade;
class ViewServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
//add to all views
view()->composer('*', HomeComposer::class);
//add to only home view
//view()->composer('home', HomeComposer::class);
}
}
【讨论】:
$user = Auth::user(); 并将 $user 变量传递给所有刀片模板,包括标题和内容部分,该怎么办?我通过将 $user 变量放在 BaseController 中然后共享它来尝试这个,但是如果我 var_dump $user 我会在数组中得到一堆受保护的值。基本上我希望能够在所有模板和视图中访问整个应用程序中的所有 auth 用户变量。看起来很简单,但花了好几个小时才弄明白。
<?= $user['name']; ?> 但这行不通:{{ $user->name }}
{{ $user['name'] }},而这适用于对象{{ $user->name }}
Class 'App\Http\Controllers\View' not found
Create a new Service Provider as suggested in here
将您的新服务提供者添加到配置文件 (config/app.php)。
在新服务提供者的启动方法中使用:
View::share( 'something_cool', 'this is a cool shared variable' );
现在您可以在所有视图中使用 $something_cool。
希望这会有所帮助。
【讨论】:
artisan down 之后的 503 页面中多次使用的变量的终极解决方案。 将应用的版本字符串作为缓存破坏参数注入或将其显示在更新时的页脚是其他解决方案的苦差事。 (不过,为此使用 env 变量可能是最干净的解决方案)
寻找相同问题的解决方案,并在 Laravel 文档中找到最佳解决方案。只需像这样在AppServiceProvider 中使用View::share:
View::share('key', 'value');
详情here.
【讨论】:
View::composer('*', function($view) { $view->with('current_user', Auth::user()); } 而不是共享来添加它。跨度>
您可以使用view composers 执行此操作。加载模板时执行视图编辑器。您可以为该视图传入具有附加功能的闭包。使用视图作曲家,您可以使用通配符。要为每个视图创建视图编辑器,只需使用 *。
View::composer('*', function($view)
{
$view->with('variable','Test value');
});
您也可以在没有闭包的情况下执行此操作,如您在文档中看到的那样。
View::composer('*', 'App\Http\ViewComposers\ProfileComposer');
配置文件编写器类必须有一个 compose 方法。
视图合成器在视图被渲染时被执行。 Laravel 也有视图创建者。这些是在实例化视图时执行的。
您还可以选择将BaseController 与 setupLayout 方法一起使用。然后,您将加载的每个视图都通过 setupLayout 方法加载,该方法添加了一些额外的数据。但是,通过使用视图作曲家,您可以确定代码已被执行。但是使用 BaseController 方法,您可以拥有更大的灵活性,因为您可以跳过额外数据的加载。
编辑:正如 Nic Gutierrez 所述,您还可以使用视图共享。
【讨论】:
view()->share 之间的区别在于,这仅在使用视图时运行 - 但使用 view()->share 无论如何都会运行 - 您可能会在 API 调用中返回一些 JSON示例 - 不使用视图。
另外,您可以在Route.php 文件中执行此操作:
view()->share('variableName', $variable);
【讨论】:
我宁愿使用带有view() 外观助手的中间件。 (Laravel 5.x)
中间件更易于维护,不会在控制器类树中造成混乱。
/app/Http/Middleware/TimezoneReset.php
要创建中间件,您可以运行 php artisan make:middleware GlobalTimeConfig
share()你需要分享的数据
<?php
namespace App\Http\Middleware;
use Closure;
class GlobalTimeConfig
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @return mixed
*/
public function handle($request, Closure $next)
{
$time_settings = [
'company_timezone' => 'UTC',
'company_date_format' => 'Y-m-d H:i:s',
'display_time' => true,
];
view()->share('time_settings', $time_settings);
return $next($request);
}
}
按照下面的示例将中间件添加到中间件路由组中
/app/Http/Kernel.php
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\GlobalTimeConfig::class,
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
在 View::share() 方法调用中使用给定键从任何模板访问数据
例如:
Company timezone: {{ $time_settings['company_timezone'] }}
编辑: Nic Gutierrez 的服务提供商答案可能是更好(或最佳)的解决方案。
【讨论】:
你可以给数组不只是View::share('key', 'value');
可以把数组像View::share(['key'=>'value','key'=>'value'])
【讨论】:
您可以在Controller.php文件中添加:
use App\Category;
然后:
class Controller extends BaseController {
public function __construct() {
$categories = Category::All();
\View::share('categories', $categories);
}
}
【讨论】:
您可以将其刷入会话中,您可以在 .env 文件中定义它(静态变量)
【讨论】: