使用 Twig 模板
Drupal 允许你覆盖所有用于生成 HTML 标记的模板,因此你可以完全控制在自定义主题中输出的标记。从高层级的 HTML 到最小的字段,每个页面元素都有模板。
覆盖模板
你可以通过在主题文件夹中添加符合特定命名约定的模板来覆盖 Drupal 的核心模板。
要覆盖模板,你需要:
1. 找到你要覆盖的模板。
2. 将模板文件从其基础位置复制到你的主题文件夹。
3. (可选)根据命名约定重命名模板,以便更具体地针对模板被使用的子集区域。
4. 根据需要修改模板。
一旦你将模板文件复制到主题并清除缓存,Drupal 将开始使用你的模板文件而不是核心版本。
你可以使用 Twig 调试工具来找出页面任何部分使用了哪些模板。
主题 hook 建议
有时你只想在某些位置修改模板文件。一个典型的例子是只对某一内容类型的节点使用不同的模板。Drupal 的主题层允许你根据命名约定来针对特定使用场景。当渲染一个文章节点时,Drupal 会先查找 node--article.html.twig 文件并使用它(如果存在)。如果不存在,则退回到标准模板 node.html.twig。Drupal 确定模板文件可能名称的过程被称为主题建议。
主题 hook 建议允许你在主题中为模板文件实现有针对性的覆盖,这些文件需要符合特定命名约定。
来自核心、模块、主题引擎和主题的所有层都可以提供建议。你可以通过以下 hook 添加或修改建议:
- hook_theme_suggestions_HOOK(array $variables)
- hook_theme_suggestions_alter(array &$suggestions, array $variables, $hook)
- hook_theme_suggestions_HOOK_alter(array &$suggestions, array $variables)
重建缓存
当使用主题建议时,有可能 Drupal 使用缓存而不是新的模板。遇到这种问题时请清除缓存。清除缓存的方法参见 Drupal 缓存清理文档。
背景信息
你可以将建议理解为命名提示,引导系统在正确的情况下选择合适的模板。
模板建议通过主题建议 hook 设置,这些 hook 可以被修改。这些 hook 允许任何模块或主题提供替代主题函数或模板命名建议,并重新排序或删除由 hook_theme_suggestions_HOOK() 或之前的调用提供的建议。
Drupal 如何基于路径为页面生成主题建议
以下是基于函数 theme_get_suggestions() 的解释:
Drupal 使用 theme_get_suggestions() 生成给定页面的可能模板列表,该函数由 system_theme_suggestions_page() 调用。
Drupal 页面路径会先被分解为组件。如上所述,Drupal 路径不同于其别名:每个页面只有一个 Drupal 路径。例如,"http://www.example.com/node/1/edit" 和 "http://www.example.com/mysitename?q=node/1/edit" 的 Drupal 路径都是 node/1/edit,其组件为 "node"、1 和 "edit"。
接下来前缀设置为 "page"。然后对每个组件应用以下逻辑:
1. 如果组件是数字,将前缀加上 “__%” 添加到建议列表。
2. 无论组件是否为数字,将前缀加上 “__” 和组件添加到建议列表。
3. 如果组件不是数字,将 “__” 和组件添加到前缀。
在遍历所有组件后,如果页面是主页(在 "Administration > Configuration > System > Site information" 中设置),则将 "page__front" 添加到建议列表。
最终,为了将建议转换为实际文件名,“__” 会被替换为 “-”,并在末尾加上 “.html.twig”。因此,对于 node/1/edit,我们得到如下建议列表:
1. page.html.twig(始终存在的建议)
2. page--node.html.twig(前缀设置为 page__node)
3. page--node--%.html.twig
4. page--node--1.html.twig(前缀不变,因为组件是数字)
5. page--node--edit.html.twig(前缀设置为 page__node__edit)
6. page--front.html.twig(仅当 node/1/edit 是首页时才会出现)
当页面渲染时,会优先检查最后一个建议。如果存在则使用,否则检查下一个,依此类推。当然,如果没有任何特定建议存在,最后会使用 page.html.twig。这也解释了为什么 page--front.html.twig 如果存在,总是会覆盖其他首页模板:它始终是首页的最后一个建议。
与 Drupal 7 的区别
在以前,要修改模板建议,你需要在预处理函数中修改 $variable['theme_hook_suggestion'] 和 $variable['theme_hook_suggestions']。在 Drupal 8 中,模块和主题通过它们各自的专用 hook 来定义和修改主题建议。
更多信息
参见 新主题建议 hook