You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Drupal自定义模块中自定义Twig模板无法渲染表单的问题

解决Drupal表单无法渲染到自定义html级Twig模板的问题

我之前在做Drupal表单自定义的时候也踩过这个模板关联的坑,你的问题核心是混淆了表单级主题和页面级html主题的用法,下面分情况给你梳理解决方案:

一、先明确你的需求

首先要搞清楚:你是想让包含该表单的整个页面使用自定义的html模板,还是只想自定义表单本身的渲染结构?这两种场景的实现方式完全不同。


场景1:让表单所在页面使用自定义html模板

如果你要替换整个页面的html.html.twig,那不能通过表单的#theme来设置,因为html.html.twig是页面顶级模板,由页面渲染流程控制,不是表单的主题。你需要通过添加页面模板建议来实现:

  1. 在resume.module中添加模板建议
    实现hook_preprocess_html()来判断当前页面是否是你的表单页面,然后注入自定义模板建议:

    function resume_preprocess_html(&$variables) {
        // 获取当前路由名称,替换成你的表单对应的路由(比如你在routing.yml里定义的路由)
        $current_route = \Drupal::routeMatch()->getRouteName();
        if ($current_route === 'resume.my_form_route') {
            // 添加自定义html模板建议
            $variables['theme_hook_suggestions'][] = 'html__resume__myform';
        }
    }
    
  2. 在自定义html模板中渲染表单
    你的html--resume--myform.html.twig里,表单是包含在页面的content区域中的,所以用以下代码渲染(可以复制原html.html.twig的结构,替换需要自定义的部分):

    <!DOCTYPE html>
    <html{{ html_attributes }}>
      <head>
        {{ head }}
        <title>{{ head_title|safe_join(' | ') }}</title>
        {{ styles }}
        {{ scripts }}
      </head>
      <body{{ attributes }}>
        {{ page_top }}
        {{ page }} {# 这里的page.content就包含你的表单 #}
        {{ page_bottom }}
      </body>
    </html>
    

场景2:自定义表单本身的渲染模板(不替换整个html页面)

如果你只是想自定义表单的结构,不需要替换整个页面的html模板,那你之前的主题注册和#theme设置有误:

  1. 修改表单类中的#theme设置
    把表单的主题钩子改成表单级的,而不是html级的:

    public function buildForm(array $form, FormStateInterface $form_state) {
        // 设置表单自身的主题钩子
        $form['#theme'] = 'resume_myform';
        
        $form['candidate_name'] = [
            '#type' => 'textfield',
            '#title' => t('Candidate Name:'),
            '#required' => TRUE,
        ];
        
        $form['actions']['#type'] = 'actions';
        $form['actions']['submit'] = [
            '#type' => 'submit',
            '#value' => $this->t('Save2'),
            '#button_type' => 'primary',
        ];
        
        return $form; // 注意这里要加分号,你之前的代码漏了
    }
    
  2. 正确注册表单主题
    在resume.module中注册表单主题,注意模板文件名的下划线/连字符转换:

    function resume_theme() {
        return [
            'resume_myform' => [
                'render element' => 'form',
                'template' => 'resume-myform', // 对应templates/resume-myform.html.twig
            ],
        ];
    }
    
  3. 编写表单模板
    在templates/resume-myform.html.twig中,你可以直接渲染整个表单,或者逐个控制元素:

    <div class="custom-resume-form">
        <h3>{{ 'Candidate Info'|t }}</h3>
        {{ form.candidate_name }}
        <div class="form-actions">
            {{ form.actions.submit }}
        </div>
        {# 别忘了渲染表单的隐藏元素 #}
        {{ form.form_build_id }}
        {{ form.form_token }}
        {{ form.form_id }}
    </div>
    

二、必做的缓存清理和检查

不管哪种场景,做完修改后一定要:

  • 清除Drupal的所有缓存(配置 -> 性能 -> 清除所有缓存)
  • 确认模板文件放在模块的templates目录下,文件名大小写、连字符/下划线完全匹配
  • 检查模板文件的权限,确保Web服务器可以读取它

内容的提问来源于stack exchange,提问作者user3646821

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:47:20