如何在模块中为自定义页面覆写page.html.twig
解决方法
1. 正确配置hook_theme
在自定义模块的.module文件里,定义page__test主题钩子时,得明确声明要传递的变量:
function YOUR_MODULE_NAME_theme($existing, $type, $theme, $path) { return [ 'page__test' => [ 'base hook' => 'page', // 继承page模板的基础结构 'variables' => [ 'custom_var' => NULL, // 声明自定义变量,默认值设为NULL ], ], ]; }
2. 在Controller里传递变量
修改你的Controller类,返回指定page__test主题钩子的渲染数组,把变量传进去:
namespace Drupal\YOUR_MODULE_NAME\Controller; use Drupal\Core\Controller\ControllerBase; class TestController extends ControllerBase { public function testPage() { // 准备要传的变量 $custom_data = '这是来自Controller的变量内容'; return [ '#theme' => 'page__test', '#custom_var' => $custom_data, // 和hook_theme里的变量名对应上 // 要是不需要默认页面内容区域,留空#markup或者删掉就行 '#markup' => '', ]; } }
3. 在自定义page模板里用变量
直接在page--test.html.twig里调用变量:
{# 完全自定义页面结构 #} <div class="test-page"> <h1>{{ page.title }}</h1> <p>{{ custom_var }}</p> {# 要是还想保留默认页面元素,比如侧边栏,继续用page.sidebar_first这类变量就行 #} </div>
为啥之前拿不到变量?
默认的page模板不会自动接收Controller传的自定义变量,必须通过hook_theme明确声明变量,而且要在渲染数组里正确传入,模板才能识别。要是只简单覆写page--test.html.twig却没在主题钩子中声明变量,模板根本拿不到Controller里的内容。
备选方案:用预处理函数传变量
要是不想改主题钩子定义,也可以通过hook_preprocess_page把Controller的变量传给page模板:
步骤1:在Controller里存变量
public function testPage() { // 把变量存到请求属性里,方便预处理函数获取 \Drupal::request()->attributes->set('test_custom_var', '来自Controller的变量'); return [ '#markup' => '', ]; }
步骤2:写预处理函数
function YOUR_MODULE_NAME_preprocess_page(&$variables) { // 判断当前是不是目标路由 if (\Drupal::routeMatch()->getRouteName() == 'YOUR_ROUTE_NAME') { $request = \Drupal::request(); if ($request->attributes->has('test_custom_var')) { // 把变量注入到page模板的变量数组里 $variables['custom_var'] = $request->attributes->get('test_custom_var'); } } }
步骤3:在模板里用变量
还是在page--test.html.twig里直接用{{ custom_var }}就行。
内容的提问来源于stack exchange,提问作者Vladimir
相关产品推荐
相关产品推荐

