覆盖 Laravel 刀片模板中的部分,抛出未定义的变量错误

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19379079/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 08:34:06  来源:igfitidea点击:

Override section in a laravel blade template throwing undefined variable errors

phplaravellaravel-4blade

提问by Wizzard

I am using Laravel 4 and blade templates, and running into an issue when I try and extend a template.

我正在使用 Laravel 4 和刀片模板,并在尝试扩展模板时遇到问题。

In my layout I have

在我的布局中,我有

@yield('content')

and in my page I have

在我的页面中,我有

@section('content')
    Welcome {{ $name }}
@stop

which works fine, I've created another page very similar to my first, and just want to change override the admin content section. The other sections in the template are fine.

效果很好,我创建了另一个与我的第一个页面非常相似的页面,并且只想更改覆盖管理内容部分。模板中的其他部分很好。

so I extend my page, and do

所以我扩展我的页面,然后做

@section('content')
    Hello!
@stop

I get an undefined notice with the $name variable.

我收到一个带有 $name 变量的未定义通知。

I tried

我试过

@section('content')
    Hello!
@overwrite

and same deal, I get the notice error. I checked my controller and it IS using the correct template. I am not calling @parent so I don't understand, how can I overwrite a section in a template with out notice errors?

同样的交易,我收到通知错误。我检查了我的控制器,它使用了正确的模板。我没有打电话给@parent 所以我不明白,我怎样才能在没有通知错误的情况下覆盖模板中的一个部分?

回答by David Barker

Blade layouts work their way up the tree to the route or master view before rendering any of the children. Thus, nested views that extend others must always have their parent rendered before they are. As a result, parent views that contain sections will always be rendered prior to the child.

在渲染任何子级之前,刀片布局会沿着树向上移动到路线或主视图。因此,扩展其他视图的嵌套视图必须始终先渲染其父视图。因此,包含部分的父视图将始终在子视图之前呈现。

To overcome the problem you are experiencing it is a good idea to only ever nest pages that don't overwrite parents sections that contain variables, as the parents content will always be rendered before the child.

为了克服您遇到的问题,最好只嵌套不覆盖包含变量的父部分的页面,因为父内容将始终在子内容之前呈现。

As the above ideal can't always be adhered to or a parents section content is still required, a good alternative method would be to use view composers. View composers give you an opportunity to declare variables for any specific view whenever they are rendered.

由于无法始终坚持上述理想或仍然需要父部分内容,因此一个很好的替代方法是使用视图作曲家。视图编辑器让您有机会在渲染任何特定视图时为它们声明变量。

View::composer(array('pages.admin'), function($view)
{
    $view->with('name', Auth::user()->username);
});

Another alternative would be to use a view creator. Creators are fired the moment a view is instantiated rather than rendered. This method allows you to overwrite the variable should you so wish prior to the view being rendered.

另一种选择是使用视图创建者。创建者在视图被实例化而不是渲染的那一刻被解雇。如果您愿意,此方法允许您在呈现视图之前覆盖变量。

View::creator(array('pages.admin'), function($view)
{
    $view->with('name', Auth::user()->username);
});

You can read up more about these methods in the documentation here. (Or herefor the Laravel 5 documentation.)

您可以在此处的文档中阅读有关这些方法的更多信息。(或者在这里查看 Laravel 5 文档。)

回答by Glad To Help

I am not sure if this is a bug or intentional, but it seems like Laravel renders the variables before interpreting blade instructions. The workaround would be this:

我不确定这是一个错误还是故意的,但 Laravel 似乎在解释刀片指令之前呈现变量。解决方法是这样的:

views/layouts/testlayout.blade.php:

视图/布局/testlayout.blade.php:

    <html>
    <body>
        @yield('sidebar', 'This is the master sidebar. {{ $name }}' )

        <div class="container">
            @yield('content')
        </div>
    </body>
   </html>

actual view: views/test.blade.php

实际视图:views/test.blade.php

@extends('layouts.testlayout')


@section('sidebar')
   No variable in the child
@stop

@section('content')
    This is a child content
@stop

This prevents the variable $nameto get rendered if there is a section with that name in the actual view. It seems like this is the approach if the content in the layout file contains a variable

$name如果在实际视图中存在具有该名称的部分,这将防止该变量被呈现。如果布局文件中的内容包含变量,则似乎是这种方法

回答by Lauren

I can't guarantee support for Laravel 4 but for those looking for a solution that works in Laravel 5.5 (and probably a fair bit further back –?hard to check) is to define the variables you need when @extending.

我不能保证对 Laravel 4 的支持,但对于那些正在寻找适用于 Laravel 5.5 的解决方案的人来说(可能还有一点点——?很难检查)是在@extending时定义你需要的变量。

E.g. in the example in the question:

例如在问题的例子中:

@extend('my.parent.view', ['name' => ''])

This approach can be especially useful if the data needed isavailable to the child-view, but under a different name.

如果需要的数据这种方法可以是特别有用的提供给儿童的观点,但以不同的名称。

E.g. if a parent-view needed a $parentvariable, but the child view only has a $childvariable which has a property referencing the parent, you might do:

例如,如果父视图需要一个$parent变量,但子视图只有一个$child具有引用父视图的属性的变量,您可以这样做:

@extend('my.parent.view', ['parent' => $child->parent])

回答by Pablo Ezequiel Leone

I found an easy solution for this problem :)

我为这个问题找到了一个简单的解决方案:)

Just add the @symbol before the variable/method you call in the parent view. If there is an error (notice/warning) PHP will ignore that and continue the execution.

只需在父视图中调用的变量/方法之前添加@符号。如果出现错误(通知/警告),PHP 将忽略该错误并继续执行。

It's not perfect, but save us to code view/composers.

它并不完美,但将我们保存到代码视图/编写器中。

Hope this help!

希望这有帮助!