在laravel的blade模板中,@yield('name')是视图继承(extend)中一个非常有用的功能。它能让开发者在开发模板的时候预留出大量的占位空间供其它视图模板继承使用。
同时,@yield('name')还能设置默认值,代码为@yield('name','default'),当继承模板的视图没有为@yield('name')指定版块赋值时,模板就会直接将默认值渲染到页面上。
不过,@yield('name', 'default')中的默认值只接受字符串类型。这个默认值如果是html标签,它则会对它进行转义,让默认字符串原样输出在浏览器上,而不是将字符串内容直接渲染出来。
比如:
@yield('header', '<div>这是网页头部</div>')
你可能是想让浏览器将<div>这是网页头部</div>
这段内容作为一个html标签渲染到页面上,然用户只看到
这是网页头部
但事实上,用户在浏览器上看到的将会是
<div>这是网页头部</div>
原因正如前面所说的,@yield('header', '<div>这是网页头部</div>')方法在接收到默认值参数['<div>这是网页头部</div>'] 后,它会首先将字符串转义,然后再发送给浏览器。
【解决方案】
【方案一】
其实,要解决这个问题也不难,常规的方法是自己在模板中先定义一个同名区块@section('name'),并在区块中写入你想要设置的html标签。
@section('header')
<div>这是网页头部</div>
@stop
@yield('header')
这样,@yield('header')在继承视图中如果没有找到相应的区块,就会回到自己模板视图中寻找同名区块@section('header'),并将它作为一个完整的html标签渲染出来。
【注意】@yield('header') 在自己模板中寻找区块时只会往前找,所以@section('header') 一定要早于 @yield('header') 定义出来。
【方案二】
另外,有人还有其他方法也能解决这个问题,比如有人就用view()方法解决了这个问题。
首先,定义一个模板视图模块[header.blade.php]存放默认值html标签
<div>这是网页头部</div>
然后,在定义 @yield('header') 的时候,使用view()方法将模板引入
@yield('v-header', view('header'))
或者
@yield('section', View::make('header'))
这个方法虽然也能解决问题,但方法太笨,而且还要额外多读一次文件,不推荐。