You are here

覆写drupal主题函数

老葛的Drupal培训班 Think in Drupal

正如你看到的,可主题化的项目是通过它们的函数名来标识的,每个函数名前都带有前缀“theme_”,或者还可以通过模板文件来标识。这一命名规范使得Drupal能够为所有的可主题化函数创建一个函数覆写机制。这样,设计者就可以指示Drupal执行一个具有更高优先级的自定义函数,从而替代开发者在模块中给出的默认的主题函数,或者替代Drupal的默认模板文件。例如,让我们检查一下,在构建站点的面包屑时该流程是怎么工作的。
    打开includes/theme.inc文件,并检查里面的函数。这里的许多函数都以theme_开头,这就告诉人们它们是可以被覆写的。特别的,我们看看theme_breadcrumb():
 
/**
 * Return a themed breadcrumb trail.
 *
 * @param $breadcrumb
 * An array containing the breadcrumb links.
 * @return a string containing the breadcrumb output.
 */
function theme_breadcrumb($breadcrumb) {
     if (!empty($breadcrumb)) {
         return '<div class="breadcrumb">'. implode(' » ', $breadcrumb) .'</div>';
     }
}
 
这个函数控制着Drupal中面包屑导航条的HTML输出。当前,它在面包屑的每一项之间添加了一个向右的双箭头分隔符(»)。假定你想将div标签改为span标签,并使用星号(*)来代替双箭头(»)。那么你该怎么办呢?一种方式是在theme.inc中修改这个函数,保存,并调用。这样也能达到目的。(别!别!千万别这样做!)。我们有更好的方式。
你有没有见过Drupal核心中是怎么调用这些主题函数的?你永远都不会看到直接调用theme_breadcrumb()的情况。替代的,它通常包装在帮助函数theme()中。你期望这样调用这个函数:
 
theme_breadcrumb($breadcrumb)
 
    但实际不是这样。替代的,你将看到开发者这样调用:
 
theme('breadcrumb', $breadcrumb);
 
    这个通用的theme()函数负责初始化主题层,并将函数调用分发到合适的位置,这使得我们能够以更优雅的方式来解决我们的问题。图8-5展示了通过调用theme(),指示Drupal按照下面的次序查来找相应的面包屑函数。
假定你使用的主题为Greyscale,,它是基于PHPTemplate的主题,那么Drupal将会查找下面的函数(我们暂且忽略一下breadcrumb.tpl.php):
 
greyscale_breadcrumb()
phptemplate_breadcrumb()
sites/all/themes/custom/greyscale/breadcrumb.tpl.php
theme_breadcrumb()
 
    我们看到函数phptemplate_breadcrumb()可以覆写内置的面包屑函数,那么我们要把这个函数放到哪里呢?
    很简单,那就是你主题的template.php文件,在这里你可以覆写Drupal的默认主题函数,拦截和创建传递给模板文件的自定义变量.
 
注意 在做这些练习的时候,不要使用Garland作为当前主题,因为Garland已经有了一个template.php文件.替代的,在这里可以使用Greyscale或者Bluemarine.
 
    为了修改Drupal的面包屑,创建文件sites/all/themes/custom/greyscale/template.ph,并将theme.inc中的theme_breadcrumb()函数复制并粘贴到该文件里面。记住要包含<?php标签。还有对函数要进行重命名,将theme_breadcrumb改为phptemplate_breadcrumb。接着,导航到“管理➤站点构建 ➤模块”以重新构建主题注册表,这样Drupal就能够找到你的新函数了。
 
<?php
/**
 * Return a themed breadcrumb trail.
 *
 * @param $breadcrumb
 * An array containing the breadcrumb links.
 * @return a string containing the breadcrumb output.
 */
function phptemplate_breadcrumb($breadcrumb) {
     if (!empty($breadcrumb)) {
         return '<span class="breadcrumb">'. implode(' * ', $breadcrumb) .'</span>';
     }
}
 

当下一次Drupal需要生成面包屑时,它就会首先找到你的函数,并使用它来代替默认的theme_breadcrumb()函数,这样面包屑中就会包含你的星号,而不再包含默认的双箭头了。很漂亮,不是么?通过theme()函数来管理所有的主题函数调用,如果当前主题覆写了任何一个theme_ 函数,那么Drupal将使用它们来代替默认的主题函数。开发者,请注意:在你的模块中任何需要输出HTML或者XML的部分都应该使用以“theme_”开头的主题函数,这样设计者就可以对它们进行覆写了。

Drupal版本:

评论

 假定你使用的主题为Greyscale,,它是基于PHPTemplate的主题,那么Drupal将会查找下面的函数(我们暂且忽略一下breadcrumb.tpl.php):

 
greyscale_breadcrumb()
phptemplate_breadcrumb()
sites/all/themes/custom/greyscale/breadcrumb.tpl.php
theme_breadcrumb()
 
    我们看到函数phptemplate_breadcrumb()可以覆写内置的面包屑函数,那么我们要把这个函数放到哪里呢?
 
请问在这一段中是不是依次查找啊!!如果没有greyscale_breadcrumb()函数,会查找phptemplate_breadcrumb().......???

theme_breadcrumb()这个是最后才调用的.正确的顺序是:

sites/all/themes/custom/greyscale/breadcrumb.tpl.php

phptemplate_breadcrumb() 

theme_breadcrumb()

遵循从具体向抽象的一般Drupal覆写规律.Drupal会依次查询可能存在的主题函数,或者模板文件.当找到第一个的时候,就会终止查找,并将找到的主题函数或者模板文件返回给相应的回调.