作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
在单个Drupal页面中, 这个模板用来显示基本HTML结构的。它包含以下可用变量:
$css:当前页面的CSS文件数组。
$language:站点正在使用的语言。它是一个对象,$language->language包含了它的文字表述;$language->dir包含了语言的方向,可以使'ltr'(从左到右),或者是'rtl'(从右到左)。
$rdf_namespaces:用在HTML文档中的所有RDF命名空间前缀。
$grddl_profile:一个GRDDL profile(轮廓),用于允许代理提取RDF数据。
$head_title:页面标题修改后的版本,用在TITLE标签中。
$head_title_array: $head_title变量的关联数组版本,$head_title变量就是基于它生成的,Drupal对它已经做过预处理,所以可用它来输出成TITLE标签。根据实际情况,键值对儿可以包含一个或多个以下元素:title,当前页面的标题;name,网站的名字;slogan:网站的口号。
$head: HEAD部分的标记文本,包括meta标签、keyword标签等等。
$styles:样式标签,用来导入当前页面的所有CSS文件。
$scripts:脚本标签,用来为当前页面加载所有的JavaScript文件和设置。
$page_top: 最前面的标记文本,这个变量的内容来自于修改该页面的第三方模块。从名字便可以看出,这个变量应该放在其它动态内容之前输出。
$page:呈现的页面内容。
$page_bottom:最后的结束标记文本,这个变量的内容来自于修改该页面的第三方模块。这个变量应该放在其它动态内容之后输出。
$classes: 类字符串,用于通过CSS定制样式。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
它的模板建议规则,首先按照节点ID来定义的,然后使用节点类型。我们还以node/1/edit为例,假定当前节点类型为article:
node--1.tpl.php
node--story.tpl.php
node.tpl.php
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
block.tpl.php默认变量
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$block->subject: 区块标题。
$content: 区块内容。
$block->module: 生成该区块的模块。
$block->delta: 区块的ID,在其所在的模块中是唯一的。
$block->region: 当前区块所在的区域。
$classes: CSS类字符串。可以在预处理函数中,通过修改$classes_array的值,来修改$classes的值。默认值有:block,block-[module]。需要注意的是,这里的[module]表示生成该区块的模块,例如对于默认的用户导航区块,它是由用户(user)模块生成的,那么此时对应的CSS类就是"block-user"。
$title_prefix (array): 在模板的主标题标签前面显示的内容,注意它是数组结构,在模板中输出时,使用render()输出。
$title_suffix (array): 在模板的主标题标签后面显示的内容,注意它是数组结构,在模板中输出时,使用render()输出。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$classes_array: 一个数组,里面包含了CSS类属性的值。$classes就是基于$classes_array生成的。
$block_zebra: 区块斑马线,可用值有'odd'和'even',依赖于当前区域。
$zebra: 区块斑马线,可用值有'odd'和'even',独立于任何区域。
$block_id: 计数器,依赖于当前区域。
$id: 计数器,独立于任何区域。
$is_front: 标记,用来表示是否显示在首页。
$logged_in: 标记,用来表示当前用户是否是登录用户。
$is_admin: 标记,用来表示当前用户是不是管理员。
$block_html_id: 一个有效的唯一的HTML ID。
这些变量来自于:
template_preprocess()
template_preprocess_block()
template_process()
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
<div id="<?php print $block_html_id; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>
<?php print render($title_prefix); ?>
<?php if ($block->subject): ?>
<h2<?php print $title_attributes; ?>><?php print $block->subject ?></h2>
<?php endif;?>
<?php print render($title_suffix); ?>
<div class="content"<?php print $content_attributes; ?>>
<?php print $content ?>
</div>
</div>
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
它的模板建议规则,首先按照它所在的module及delta来定义,然后按照它所在的区域来定义。我们还以主菜单区块为例,假定将它放到了navigation区域:
block--system--main.tpl.php
block--system.tpl.php
block--navigation.tpl.php
block.tpl.php
默认的模板文件位于modules\field\theme下面:
<div class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
<?php if (!$label_hidden): ?>
<div class="field-label"<?php print $title_attributes; ?>><?php print $label ?>: </div>
<?php endif; ?>
<div class="field-items"<?php print $content_attributes; ?>>
<?php foreach ($items as $delta => $item): ?>
<div class="field-item <?php print $delta % 2 ? 'odd' : 'even'; ?>"<?php print $item_attributes[$delta]; ?>><?php print render($item); ?></div>
<?php endforeach; ?>
</div>
</div>
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$items: 包含字段值的数组。使用render()输出。
$label: 条目的标签。
$label_hidden: 标签显示是否设置为了'hidden'。
$classes: CSS类字符串。可以在预处理函数中,通过修改$classes_array的值,来修改$classes的值。默认值有:field、field-name-[field_name]、field-type-[field_type]、field-label-[label_display]。
其它变量:
$element['#object']: 字段附属的实体对象。
$element['#view_mode']: 查看模式,比如:'full', 'teaser'...
$element['#field_name']: 字段名字。
$element['#field_type']: 字段类型。
$element['#field_language']: 字段语言。
$element['#field_translatable']: 字段是否可被翻译。
$element['#label_display']: 标签显示的位置,inline(内联显示), above(上方显示), hidden(隐藏显示)。
$field_name_css: CSS兼容的字段名字。
$field_type_css: CSS兼容的字段类型。
$classes_array: 一个数组,里面包含了CSS类属性的值。$classes就是基于$classes_array生成的。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
template_preprocess_field()
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
我们以字段field_email为例,它的字段类型为text,把它添加到了用户实体上面:
field--field-email--user.tpl.php
field--user.tpl.php
field--field-email.tpl.php
field--text.tpl.php
field.tpl.php
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
很多人经常会问这样的问题,Drupal是怎么把这些模板文件转为HTML内容返回的呢?我们前面已经讲过了,预处理函书里面,可以为模板文件设置变量。现在的问题是怎么最终使用模板文件生成HTM?这个工作,是在下面的函数中实现的:
function theme_render_template($template_file, $variables) {
extract($variables, EXTR_SKIP); // Extract the variables to a local namespace
ob_start(); // Start output buffering
include DRUPAL_ROOT . '/' . $template_file; // Include the template file
return ob_get_clean(); // End buffering and return its contents
}
把模板文件和变量传递了过来,然后返回生成的HTML片段。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
Drupal自带的默认html.tpl.php模板文件,位于modules\system目录下面:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML+RDFa 1.0//EN"
"http://www.w3.org/MarkUp/DTD/xhtml-rdfa-1.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="<?php print $language->language; ?>" version="XHTML+RDFa 1.0" dir="<?php print $language->dir; ?>"<?php print $rdf_namespaces; ?>>
<head profile="<?php print $grddl_profile; ?>">
<?php print $head; ?>
<title><?php print $head_title; ?></title>
<?php print $styles; ?>
<?php print $scripts; ?>
</head>
<body class="<?php print $classes; ?>" <?php print $attributes;?>>
<div id="skip-link">
<a href="#main-content" class="element-invisible element-focusable"><?php print t('Skip to main content'); ?></a>
</div>
<?php print $page_top; ?>
<?php print $page; ?>
<?php print $page_bottom; ?>
</body>
</html>
模板文件,是由两部分组成的,静态的html标记文本,动态的变量。Drupal在生成这个页面时,会把这些变量预先的填充好内容,然后将其套到对应的模板上,这样便合成了一个完整的html页面。对于其它模板来说,是合成了对应功能的html片断。注意这里面的语法:
<?php print $page; ?>
这就是一个很普通的php语句,Drupal自带的模板引擎是PHPTemplate,这样只要我们了解一点PHP,便可以很快地上手。对于其它的模板引擎,由于还需要学习额外的语法,学习成本会高那么一点点,所以在Drupal中很少用到。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
html.tpl.php的模板建议,是由theme_get_suggestions设置的,在预处理函数template_preprocess_html中,对应的代码:
if ($suggestions = theme_get_suggestions(arg(), 'html')) {
$variables['theme_hook_suggestions'] = $suggestions;
}
它的模板建议规则是按照路径来的,路径越具体,优先级越高。我们举个例子,来了解一下模板建议及其优先级问题。假定当前Drupal路径为node/1/edit,那么html.tpl.php有以下模板建议:
html--node--edit.tpl.php
html--node--1.tpl.php
html--node--%.tpl.php
html--node.tpl.php
当用户访问页面node/1/edit,会使用这里面的哪个模板。Drupal的主题系统,会按照html.tpl.php的模板建议规则,首先检查html--node--edit.tpl.php是否存在,如果存在,就使用该模板文件;如果不存在,会接着检查html--node--1.tpl.php是否存在,如果存在,就使用html--node--1.tpl.php;如果不存在,会接着检查html--node--%.tpl.php是否存在,如果存在,就使用html--node--%.tpl.php;如果不存在,会接着检查html--node.tpl.php是否存在,如果存在,就使用html--node.tpl.php;如果不存在,就会使用主题自带的html.tpl.php文件,如果该主题没有html.tpl.php文件,则会使用Drupal核心自带的默认html.tpl.php文件。
注意,在$variables['theme_hook_suggestions']对应的数组中,越靠后的模板建议,优先级越高。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$base_path: Drupal安装的基路径。通常情况下,默认为/。它的值由base_path()生成。
$directory: 模板文件所在的目录,比如modules/system或者themes/bartik。它的值由path_to_theme()生成。通常把这个变量和$base_path一起使用,来构建模板所在的绝对路径:
<?php print $base_path . $directory ?>
这段代码等价于:
<?php print base_path() . path_to_theme() ?>
$is_front: 如果当前页面为首页,返回TRUE。
$logged_in: 当前用户是注册用户并且已经登录,返回TRUE;否则,返回FALSE。
$is_admin:如果用户有权访问管理界面,返回TRUE;否则,返回FALSE。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$front_page:首页的URL,它包含了语言前缀/域名。它的值由不带参数的url()生成。当链接指向首页时,可以使用这个变量,来替代$base_path。
$logo: 指向logo图片的路径,定义在主题的配置中。
$site_name: 站点的名称。当管理员在主题配置中禁止显示时,$site_name为空。
$site_slogan: 站点的口号。当管理员在主题配置中禁止显示时,$site_slogan为空。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$main_menu: 站点主导航菜单链接的数组,如果没有配置,则为空。它在模板文件中这样输出,如下所示:
<?php print theme('links__system_main_menu', array('links' => $main_menu, 'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?>
通过修改上面的代码,我们可以修改主菜单的ID,Class,从而能够更好的控制它的样式输出。
$secondary_menu: 站点二级导航菜单链接的数组,如果没有配置,则为空。
$breadcrumb: 当前页面的面包屑。
$title_prefix (array):在模板的主标题标签前面显示的内容,注意它是数组结构,在模板中输出时,使用render()输出。
<?php print render($title_prefix); ?>
$title:页面的标题,可用在实际的HTML内容中。它在模板中这样输出:
<?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
注意,这里面$title已经是现成的html内容了,而$title_prefix此时还是一个数组,它们的输出方式有所不同。在Drupal7的模板中,使用render(),是很普遍的。
$title_suffix (array): 在模板的主标题标签后面显示的内容,注意它是数组结构。
$messages: 状态消息和错误消息对应的HTML,应该突出显示。
$tabs (array): 当前页面对应的子页面的Tabs链接,例如当显示一个节点时,对应的查看/编辑标签。
$action_links (array): 作用于当前页面的动作,比如菜单管理界面的“添加菜单”链接。
$feed_icons: 当前页面的所有种子图标。
$node: 如果当前页面是一个节点页面,比如node/123,或者是节点的子页面node/123/revisions,这个变量就是对应的自动加载的节点对象。
$page['help'] : 动态的帮助文本,主要用于管理界面。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
很多人,特别是初学Drupal的人,经常会问,模板里面的变量是从哪里蹦出来的。肯定是在别的地方定义了这些变量,所以我们才能在这里引用。这些变量是在下面的函数中定义的:
template_preprocess()
template_process()
template_preprocess_page()
template_process_page()
有兴趣的可以在api.drupal.org查一下这些函数。我们也会在后面的内容中,对这些函数做进一步的介绍。
<?php if ($title): ?><h1 class="title" id="page-title"><?php print $title; ?></h1><?php endif; ?>
<?php print render($title_suffix); ?>
<?php if ($tabs): ?><div class="tabs"><?p<div id="page-wrapper"><div id="page">
<div id="header"><div class="section clearfix">
<?php if ($logo): ?>
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home" id="logo">
<img src="<?php print $logo; ?>" alt="<?php print t('Home'); ?>" />
</a>
<?php endif; ?>
<?php if ($site_name || $site_slogan): ?>
<div id="name-and-slogan">
<?php if ($site_name): ?>
<?php if ($title): ?>
<div id="site-name"><strong>
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a>
</strong></div>
<?php else: /* Use h1 when the content title is empty */ ?>
<h1 id="site-name">
<a href="<?php print $front_page; ?>" title="<?php print t('Home'); ?>" rel="home"><span><?php print $site_name; ?></span></a>
</h1>
<?php endif; ?>
<?php endif; ?>
<?php if ($site_slogan): ?>
<div id="site-slogan"><?php print $site_slogan; ?></div>
<?php endif; ?>
</div> <!-- /#name-and-slogan -->
<?php endif; ?>
<?php print render($page['header']); ?>
</div></div> <!-- /.section, /#header -->
<?php if ($main_menu || $secondary_menu): ?>
<div id="navigation"><div class="section">
<?php print theme('links__system_main_menu', array('links' => $main_menu, 'attributes' => array('id' => 'main-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Main menu'))); ?>
<?php print theme('links__system_secondary_menu', array('links' => $secondary_menu, 'attributes' => array('id' => 'secondary-menu', 'class' => array('links', 'inline', 'clearfix')), 'heading' => t('Secondary menu'))); ?>
</div></div> <!-- /.section, /#navigation -->
<?php endif; ?>
<?php if ($breadcrumb): ?>
<div id="breadcrumb"><?php print $breadcrumb; ?></div>
<?php endif; ?>
<?php print $messages; ?>
<div id="main-wrapper"><div id="main" class="clearfix">
<div id="content" class="column"><div class="section">
<?php if ($page['highlighted']): ?><div id="highlighted"><?php print render($page['highlighted']); ?></div><?php endif; ?>
<a id="main-content"></a>
<?php print render($title_prefix); ?>
hp print render($tabs); ?></div><?php endif; ?>
<?php print render($page['help']); ?>
<?php if ($action_links): ?><ul class="action-links"><?php print render($action_links); ?></ul><?php endif; ?>
<?php print render($page['content']); ?>
<?php print $feed_icons; ?>
</div></div> <!-- /.section, /#content -->
<?php if ($page['sidebar_first']): ?>
<div id="sidebar-first" class="column sidebar"><div class="section">
<?php print render($page['sidebar_first']); ?>
</div></div> <!-- /.section, /#sidebar-first -->
<?php endif; ?>
<?php if ($page['sidebar_second']): ?>
<div id="sidebar-second" class="column sidebar"><div class="section">
<?php print render($page['sidebar_second']); ?>
</div></div> <!-- /.section, /#sidebar-second -->
<?php endif; ?>
</div></div> <!-- /#main, /#main-wrapper -->
<div id="footer"><div class="section">
<?php print render($page['footer']); ?>
</div></div> <!-- /.section, /#footer -->
</div></div> <!-- /#page, /#page-wrapper -->
它的模板建议规则也是按照路径来定义的,路径越具体,优先级越高。我们还以node/1/edit为例,那么它有以下模板建议:
page--node--edit.tpl.php
page--node--1.tpl.php
page--node--%.tpl.php
page--node.tpl.php
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$content: 这个区域的内容,通常为区块。
$classes: 包含CSS类的字符串。可以通过修改预处理函数中的$classes_array变量来修改这里的值。它的默认值有region,region-[name],注意“[name]”中的下划线将自动替代为连字符,比如page_top区域,其中对应的一个类为region-page-top。
$region:区域变量的名字,定义在主题的.info文件中。
$classes_array: CSS类的数组,$classes变量的值基于$classes_array生成。
在这个模板中,还可以使用的通用变量有: $is_admin、$is_front、$logged_in。
对应的预处理函数:
template_preprocess()
template_preprocess_region()
template_process()
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
它的模板建议规则,是按照区域名字来定义的。我们还以right区域为例,它的模板建议为:
region--right.tpl.php
region.tpl.php
Drupal自带的默认region.tpl.php模板文件,位于modules\system目录下面,内容如下:
<?php if ($content): ?>
<div class="<?php print $classes; ?>">
<?php print $content; ?>
</div>
<?php endif; ?>
<div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?> clearfix"<?php print $attributes; ?>>
<?php print $user_picture; ?>
<?php print render($title_prefix); ?>
<?php if (!$page): ?>
<h2<?php print $title_attributes; ?>><a href="<?php print $node_url; ?>"><?php print $title; ?></a></h2>
<?php endif; ?>
<?php print render($title_suffix); ?>
<?php if ($display_submitted): ?>
<div class="submitted">
<?php print $submitted; ?>
</div>
<?php endif; ?>
<div class="content"<?php print $content_attributes; ?>>
<?php
// We hide the comments and links now so that we can render them later.
hide($content['comments']);
hide($content['links']);
print render($content);
?>
</div>
<?php print render($content['links']); ?>
<?php print render($content['comments']); ?>
</div>
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
node.tpl.php 默认变量
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$title: 节点的标题,已过滤。
$content:节点条目数组。使用render($content),可以全部输出;使用 render($content['field_example'])可以输出一个子集;使用hide($content['field_example'])可以临时隐藏给定元素的输出。
$user_picture: 节点作者的头像,来自于user-picture.tpl.php。
$date: 格式化的创建日期。如果想对这个变量重新格式化,那么可以在预处理函数中,对$created使用format_date()函数,并向其传递合适的参数。
$name: 节点作者用户名的格式化输出,这里使用了theme_username()。
$node_url: 当前节点的直接URL。
$display_submitted: 布尔值,用来指示是否显示提交信息。
$submitted: 提交信息,在template_preprocess_node()中基于$name和$date生成。
$classes: CSS类字符串。可以在预处理函数中,通过修改$classes_array的值,来修改$classes的值。默认值有:node,node-[type],node-teaser,node-preview,node-promoted,node-sticky,node-unpublished。注意,这里的node-[type]表示当前节点类型,如果当前节点为博客,那么这里就是"node-blog"。
$title_prefix (array): 在模板的主标题标签前面显示的内容,注意它是数组结构,在模板中输出时,使用render()输出。
$title_suffix (array): 在模板的主标题标签后面显示的内容,注意它是数组结构,在模板中输出时,使用render()输出。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$node:完整的节点对象。它里面包含的数据可能并不安全。
$type:节点类型,例如:article、page、blog等等
$comment_count:该节点上面的评论数量。
$uid: 节点作者的用户ID。
$created: 节点的发布时间,格式为Unix时间戳。
$classes_array: 一个数组,里面包含了CSS类属性的值。$classes就是基于$classes_array生成的。
$zebra: 斑马线,可能的值有:"even"或"odd"。用在摘要列表中。
$id: 节点的位置。每输出一次,这个变量加一。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
$view_mode:查看模式,比如:'full'、'teaser'等等。
$teaser:摘要状态的标记,等价于$view_mode == 'teaser'。
$page: 标记,用来表示当前是否是完整页面状态。
$promote: 标记,用来表示当前节点是否推荐到了首页。
$sticky: 标记,用来表示当前节点是否被置顶。
$status: 标记,用来表示当前节点是否已发布。
$comment: 当前节点的评论设置的状态。
$readmore: 标记,当摘要内容HOLD不住正文内容时,为TRUE。
$is_front: 标记,用来表示是否显示在首页。
$logged_in: 标记,用来表示当前用户是否是登录用户。
$is_admin: 标记,用来表示当前用户是不是管理员。
作者:老葛,北京亚艾元软件有限责任公司,http://www.yaiyuan.com
对于附加在该节点上面的每个字段实例,都会为其定义一个对应的变量。例如,$node->body变成了$body。当需要访问一个字段的原始数据时,推荐大家使用这些变量,如果从$node变量中直接获取,此时还需要考虑字段上面的语言,例如,$node->body['en'];这样就会覆写掉前面设置的语言协定规则。
有关字段变量的生成,可以参看函数field_attach_preprocess,在这个函数中,去掉了字段上面的语言信息。代码如下:
$variables[$field_name] = isset($entity->{$field_name}[$langcode]) ? entity->{$field_name}[$langcode] : NULL;
这些变量来自于:
template_preprocess()
template_preprocess_node()
template_process()