定义额外的模板文件
译者:老葛 Eskalate科技公司
如果你和一个设计者一同工作,你想让他/她从代码中找到主题函数并覆写它,这有点难为人的。幸运的是,有另一种方法,使得设计者更容易的修改外观。你可以将匹配的主题函数替换为它们自己的模板文件。我们将通过大家熟悉的面包屑的例子来说明这一点。
首先,在你的主题目录下创建一个名为breadcrumb.tpl.php的文件。这是用于面包屑的新的模板文件。因为我们想将<div>标签替换为<span>标签,继续前进,向该文件中添加以下内容:
<span class="breadcrumb"><?php print $breadcrumb ?></span>
现在设计者就很容易编辑了。现在你需要在Drupal需要显示面包屑时告诉它调用这个模板文件。在template.php里,像你前面做的那样覆写theme_breadcrumb(),但是这次在函数内部你将使用模板文件来代替相应的功能:
function mytheme_breadcrumb($breadcrumb) {
if (!empty($breadcrumb)) {
$variables = array(
'breadcrumb' => implode(' * ', $breadcrumb)
);
return _phptemplate_callback('breadcrumb', $variables);
}
}
这个函数的关键点在于_phptemplate_callback()。它的第一个参数是要查找的模板文件的名字,第二个参数是传递给模板文件的变量数组。你的模板文件需要多少变量,你就可以创建并传递多少。
添加和操纵模板变量
问题又来了:如果你可以创建你自己的模板文件并控制传递给它们的参数,那么你如何操纵或者添加传递给页面和节点模板文件的变量呢?
每次加载一个模板文件都需要调用_phptemplate_callback()函数,我们在前面已经介绍了该函数。这个函数负责收集变量并将其传递给合适的模板文件中,而这些变量可来自于不同的位置:
• 作为_phptemplate_callback()的第2个参数传递过来的$variables数组。
• 通过phptemplate.engine中的_phptemplate_default_variables()为每个模板文件追加的默认变量。
• 从_phptemplate_variables()返回的变量。这个函数在Drupal中,默认情况下是不存在的,在变量发送给相应的模板文件以前,你可以在你的主题内使用这个函数来操纵变量。
图8-7展示了如何将其与更高的主题系统绑定到一起
图8-7 开发者可以使用_phptemplate_variables()函数来拦截并操纵发送给模板文件的变量
_phptemplate_variables()的一个通常的用法是,当有人访问站点而且已经登录时,为其设置一个变量。向你的template.php文件中添加以下变量:
/**
* Intercept template variables.
*
* @param $hook
* The name of the theme function being executed.
* @param $vars
* An array of variables passed to the template file.
*/
function _phptemplate_variables($hook, $vars = array()) {
switch ($hook) {
// Send a new variable, $logged_in, to page.tpl.php to tell us if the current
// user is logged in or out.
case 'page':
// Get the currently logged in user.
global $user;
// An anonymous user has a user ID of zero.
if ($user->uid > 0) {
// The user is logged in.
$vars['logged_in'] = TRUE;
}
else {
// The user is not logged in.
$vars['logged_in'] = FALSE;
}
break;
}
return $vars;
}
在前面的代码中,由于这样或者那样的原因,你为页面主题钩子或者page.tpl.php创建了一个新的变量。当用户已登录时,$logged_in为TRUE;当匿名用户访问站点时,$logged_in为FALSE。另一个通常需要设置变量的情况是,当一个作者创建一个评论时,检查他是不是被评论的文章的作者,这样就可以使用不同的样式了。下面是如何实现的:
function _phptemplate_variables($hook, $vars = array()) {
switch ($hook) {
// Send a new variable, $logged_in, to page.tpl.php to tell us if the current
// user is logged in or not.
case 'page':
// Get the currently logged in user.
global $user;
// An anonymous user has a user id of zero.
if ($user->uid > 0) {
// The user is logged in.
$vars['logged_in'] = TRUE;
}
else {
// The user is not logged in.
$vars['logged_in'] = FALSE;
}
break;
case 'comment':
// We load the node object to which the current comment is attached.
$node = node_load($vars['comment']->nid);
// If the author of this comment is equal to the author of the node,
// we set a variable; then in our theme we can theme this comment
// differently so it stands out.
$vars['author_comment'] = $vars['comment']->uid == $node->uid ? TRUE
: FALSE;
break;
}
return $vars;
}
现在在comment.tpl.php中你可以检查$author_comment的值,根据它的值的不同可设置不同的CSS类。
注意 在_phptemplate_variables()中你还可以修改的一个变量是$vars['template_file'],它是Drupal将要调用的模板文件的名字。如果你在一个更复杂的条件下需要加载另外一个模板文件,你可以在这里修改这个变量。