[Drpal模板制作手册-5]重写可主题化的输出
只要当默认的内容标记需要变更时才会用到下面的知识。对于想纯粹使用 样式表 来处理页面表现的,可以跳过这一章节。
重写用于主题化的输出一共有三个要点。首先是要找到输出来源,然后找到可用于覆写的内容,第三是理解其类型。
注意:Drupal会用主题注册表来缓存主题数据。当要建立覆写时必须将其清除
1.找到输出源:
- 要追踪到输出源可能会有点困难,因为有些可主题化的调用会被继承很多次,在整个系统中来回传播。

链接到一个520KB大小的PDF. Provided for illustration only.
大多数页面元素都是被“绑定” 到 主题(‘页面‘) 中,渲染出导航菜单,导航菜单中的项目,块域,块域中的区块,等等,然后放在 page.tpl.php 模板里。每一块主题化数据通常作为一个主题“挂钩” 来引用。
注意: 主题函数和模板现在可以作为主题挂钩来引用。整个系统中还有很多和制作主题没有关系的挂钩。 此文中提到的所有“挂钩”都是指主题挂钩。
现在可以用devel模块来追踪系统输出的标记内容的来源。 It includes a theming tool to easily visualize the source of any output, its type and tons of other theming data. See the screencast for a demonstration. 由于技术限制,此模块Drupal 6以下版本并不适用。
2. 覆写系统:

如果你需要在这些主题化约定之外控制更多东西,试试 主题注册表 。
注意:尽管仍然可能实施,Drupal 6中的PHPTemplate.engine将不再覆写主题函数。. In 5, that is what allowed templates to be used for a handful of the theming hooks. 现在没有必要这么做。
如上所说,有两种方式,或者“类型”,可以达到处理挂钩的目的。普通的“函数(functions)” 或者“模板(templates)”。根据主题化元素的性质,这两种方式各有适用范围。核心与模块可以通过两种方式的任意一种来生成输出。The upper theming layers can carry over the same type or change it.

链接到一个PDF文档. Flow map for 5 also available for comparison.
中文版[不完全翻译]
通过函数来应用的主题挂钩速度更快。通常来说会比用模板快五倍左右。但是对于只熟悉xhtml的设计者来说,用模板肯定要简单一些。通常情况下,这些速度不用被考虑,因为这也取决于挂钩的性质和它在页面中被调用的次数。
Note: In versions before 6, core and modules could only work as functions for the theming hooks. Implementing through templates was done by PHPTemplate by overriding the hooks and doing the conversion on the engine layer.
以下是在devel themer模块的帮助下进行覆写的两个例子。
- 覆写函数:
- 主题函数theme_menu_local_tasks 是一个用于输出primary和secondary标签页的简单函数。(也就是Drupal中默认带有的primary menu和secondary menu这两个菜单。)这个例子中的挂钩就是”menu_local_tasks“. 要重写它,函数中的”theme” 前缀可以被改为你的主题名或者你正在使用的主题引擎(如phptemplate)的名字。我们建议你使用主题名,以防止将来可能会和子主题产生冲突。
此例显示系统默认的Garland主题使用的是主题引擎的名字来覆写。如果你要用Garlan作为父主题建立一个子主题,你就必须使用主题名来进行覆写。将以下代码放到主题的template.php文件中就可以覆写默认输出。要看到结果需要先清理主题注册表。 把”drop” 改为你的主题名。<?php
function drop_menu_local_tasks() {
$output = ''; if ($primary = menu_primary_local_tasks()) {
$output .= "<ol class="tabs primary">n". $primary ."</ol>n";
}
if ($secondary = menu_secondary_local_tasks()) {
$output .= "<ol class="tabs secondary">n". $secondary ."</ol>n";
}return $output;
}
?>这里所做的改变仅仅是把无序列表变成了有序列表。全部theme函数的列表可以在api.drupal.org找到。
- 覆写模板:
- If the default implementation is done as a template then simply moving the source template file into the theme will automatically override it after clearing the theme registry. 这里有一个针对search-theme-form.tpl.php的例子。 Note that the theming hook in this case is “search_theme_form” with the template using hyphens instead of underscores.
That is all you need to do.只要把主题模板文件找到,复制到你自己的主题文件夹中的任意位置,然后做出自己的更改就可以了。. All the core .tpl.php files are documented. It should give a good indication on what can be done with the output.Note: templates can be placed in any directory within the theme. This allows for better management and less clutter in the base level of the theme directory.Related pages:- To customize the variables inside templates, see the sub-page on Preprocess functions.
- A listing of all the theme templates can be found on the sub-page, Core templates and suggestions.
- 从函数转换为模板
- 将函数转换为模板需要做一点初始工作,但是一旦完成,数据将变得更易处理。 如果你在和一个设计师合作,这样的转换就能帮助他们关注于页面设计,而非编写代码。 Drupal核心中已经有很多模板可供控制,将来会有更多的。Drupal社区中共享的模块如果编写得当,也应该提供有了相应的模板。 These instructions are provided for the theming hooks not already made available as templates.Getting Drupal to recognize the theming hook as a template is automated. These are the only requirements to trigger this change:
- Name of the template must match the theming hook.
- The underscores in the hook must be changed to hyphens.
- The template name must have an extension of “.tpl.php”. (It can vary based on the theme engine.)
Consider the theming function theme_user_signature. The theme hook here is “user_signature“. Creating a file named “user-signature.tpl.php” will tell Drupal that the hook is now a template after clearing the registry. Any content in this file will now take the place of the function. The part that takes more work is setting up the variables to be used in this file and that is done through preprocess functions.
A few notes:
- While it is possible to code directly inside the template, it is not considered good practice. All the complex logic should be separated from the .tpl.php file. This keeps it clean and easy to manage.
- There is also the issue of security. The separation can minimize the chance of cross-site scripting attacks by cleaning out potentially malicious user generated content. When handing over template files to your designer, all the output should be clean so they do not have to concern themselves with security issues.
- Compare the theming functions in 5 to the template conversions in 6 for forums. You can use that as an example on converting between the two types.
- More information on preprocess functions available.
对于大多数开发者来说,这些注册表项不会被直接接触到。只要记得在增删主题函数和模板的时候清理注册表就好了。 编辑已有函数和模板不需要重建注册表。
要清空主题注册表,执行以下步骤之一:
- 点击”管理>站点配置>性能”中的清除缓存按钮。
- 如果启用了devel 区块(由devel模块提供),点击“清空缓存(Clear Cache)”链接
- 使用API函数drupal_rebuild_theme_registry.
The theme registry is cached data instructing Drupal on the available theming hooks and how to handle it by indicating its type. In previous versions all theming calls were handled on the fly. Since a lot more work is being done under the hood, the cached instructions speeds up the process especially for templates. The theme engine your theme is running under should automatically register all the theming hooks for you.
There are special cases where you may need to work with the registry directly. When your theme requires a new hook to be registered that was not already implemented on the layers below it (core, modules, engine). This includes some forms when they are not explicitly themed by core or modules but instead rely on the default form presentation.
- More details can be found in the sub-page, The theme registry for special cases.
- Do not confuse the theme registry with the theme’s .info file which is also cached. Points 1 and 2 on clearing the registry will clear both.
© 笨活儿 允许转载,但请以链接形式保留出处。也欢迎您使用RSS订阅本博客。
九月 16, 2010 11:28 下午
写得好,我顶了,可惜drupal在中国太不普及了。不会英语真的是太累了。
十一月 22, 2011 3:10 上午
我大致明白了:但是要把设计师丢过来的静态页面转成模板怎么办呢?针对这个问题有没有什么好的解决方法呢?还忘站长赐教。
十一月 30, 2011 10:29 上午
这个就是前端工程师的基本工作啊。。 切图。。。