Laravel 5.6模板继承下翻译与theme_url失效问题求助
这问题我之前在使用igaster/laravel-theme时也碰到过,结合Laravel的模板渲染机制和这个主题包的工作原理,咱们来拆解核心原因:
核心差异:模板继承 vs @include的执行顺序
Laravel的模板渲染机制中,@extends(模板继承)和@include的执行逻辑有本质区别:
- 模板继承(@extends):当渲染子模板时,Laravel会先解析子模板的所有内容,收集
@section的代码片段,然后才加载并执行父模板的代码。这意味着子模板里的__('lang.title')和theme_url()调用,会在父模板中App::setLocale()、Theme::Set()这些设置生效前就被执行。 - @include:父模板会按代码顺序逐步执行,当遇到
@include时才加载并渲染目标子模板。此时父模板中前面的@php块已经执行完成,Locale和Theme的全局设置已经生效,子模板的函数调用自然能获取到正确的配置。
为什么模板继承时会失效?
你在父模板中把Locale和Theme的设置写在@php块里,但由于模板继承的执行顺序,子模板的__()和theme_url()在父模板的@php块执行前就已经被解析执行了——此时Locale还是框架默认值,Theme也没切换到mobile,自然无法输出正确的翻译和主题资源路径。
而换成@include后,父模板先完成所有全局设置,再加载子模板,函数调用能拿到最新的全局配置,所以功能恢复正常。
推荐解决方案(一劳永逸)
把Locale和Theme的设置移出模板,放到路由中间件中执行,这是框架推荐的全局配置时机,能确保所有模板渲染时设置都已生效:
- 创建一个中间件文件(比如
app/Http/Middleware/SetThemeAndLocale.php):
<?php namespace App\Http\Middleware; use Closure; use Illuminate\Support\Facades\App; use igaster\laravelTheme\Theme; class SetThemeAndLocale { public function handle($request, Closure $next) { // 设置Locale和Theme App::setLocale('en'); Theme::set('mobile'); return $next($request); } }
- 在
app/Http/Kernel.php中注册这个中间件:- 如果要全局生效,加到
$middleware数组里; - 如果只针对特定路由,加到
$routeMiddleware数组里,然后在路由中调用。
- 如果要全局生效,加到
这样不管你用模板继承还是@include,模板渲染时Locale和Theme的设置都已经提前完成,不会再出现功能失效的问题。
内容的提问来源于stack exchange,提问作者Zdeněk Nováček
相关产品推荐
相关产品推荐

