站点定制与外观主题

这部分手册介绍的是有关站点定制与外观主题方面的内容。虽然只利用Drupal自带的核心模块与主题就完全可以建立一个很棒的站点,但是为了充分开发利用Drupal潜在的强大功能,难免要做一些个性化的定制以及外观主题方面的修改,而这些常常需要一些基本的PHP,MySQL与网站设计方面的知识。

在下面的手册中,你将可以找到一些现成的PHP或SQL代码,来帮助你完成一些常见的关于页面、区块与主题的定制。同时还有一些关于Drupal外观主题引擎的介绍,帮助你开放自己的新主题。

如果你有什么有关的使用代码,也欢迎在相关的手册页面加入评论,或者在论坛发帖提出,我们会有选择地加入到手册中。

(尚未完成,持续翻译中。。。)

Core modules

本文档为 Drupal 本身自带的模块提供一些帮助。 当你安装 Drupal 后,这些模块会自动安装,要使用一个模块,首先到 administer >> site building >> modules 启用 之 (一些模块已经自动启用了),然后到 administer >> user management >> access control 设置正确的权限

为了扩展 Drupal 的功能,你还可以使用 "contributed modules",请参考 contributed modules 页面。

如果您希望分享您的帮助文档,可以联系 大米 或者 kzeng,他们可以帮助您建立和更新手册页面。

外观主题开发指南

这一部分介绍如何开发自己的外观主题。部分指南来自于drupal.org相关页面的翻译,部分来源于中文原创。

(不管你使用下面的任何方法开发自己的主题,请一定注意你的新主题的名字不能与已有的主题重名,否则将引起冲突而不能正常工作)

如何升级你的主题

当Drupal版本升级,特别是主要版本升级时,你的主题通常也需要相关的升级才能在新版本下正常工作。

从4.7.x升级到5.x

相关的Drupal 5.0 API 变化

下面列出的是Drupal 5.0中与外观主题有关的API接口变化,如果你的主题中用到了下面的函数,都要进行相应的更新才能在5.0下正常工作:

  1. $primary_links 与 $secondary_links 变量结构改变
  2. 新增 drupal_add_css() 函数添加CSS文件
  3. 新的 $feed_icon 显示聚合图标
  4. 新的clearing类
  5. theme_links() 改为返回链接列表
  6. 新增 drupal_add_js() 函数添加javascript脚本
  7. _phptemplate_callback signature change

4.7.x

<?php
print '<ul>';
foreach (
$primary_links as $link) {
   print
'<li>'. $link .'</li>';
}
print
'</ul>';
?>

在5.x中如果还使用上面的代码,就会显示出"Array"字样,而不是实际的链接。

5.x 中改用theme_links() 函数

<?php
print theme('links', $primary_links);
?>

theme_links() 返回的就是link列表,每个link array的key都是"模块名-链接名"的形式:比如 menu-1-3-4 或者 node-read-more 或者 comment-add-new。

关于theme_links的更多信息,请参见相关的4.7到5.0模块升级手册

2. 使用 drupal_add_css() 添加CSS文件

在4.7.x里,需要使用类似下面的代码来添加自定义的CSS文件:

<?php
theme
('stylesheet_import', base_path() . path_to_theme() . '/extra_stylesheet.css') or theme_add_style($themes[$theme]->filename);
?>

在5.x里,改为了:

<?php
drupal_add_css
($path = NULL, $type = 'module', $media = 'all');
?>

这样添加CSS文件变得更加容易,而且可以控制CSS文件的先后顺序(例如Drupal内核CSS,然后是扩展模块的CSS,然后是外观主题的CSS)。

此外在phpTemplate中新增了一个 $css 变量,包含当前页面所有的CSS文件。原来的变量 $styles 还是包含加载CSS文件所必需的实际HTML代码,而新的 $css 变量的引入使你可以在theme里非常方便地替换CSS文件:

<?php
 
// print $styles;
  // 去掉这一行,如果我们需要在下面去掉drupal.css

 
unset($css['core']['misc/drupal.css']);
  print
drupal_get_css($css);
?>

3. 新的聚合图标 $feed_icon

在 phpTemplate 里还新增了一个 $feed_icon ,这个变量是一个包含当前页面所有的聚合图标的字符串。有了这个变量,你就可以随意摆放聚合图标,而不是直线与页面正文(body)了。更多内容可参看相关的“模块升级手册部分”

4. 新的clear CSS类

在5.x以前的版本中,CSS文件里所用的清除浮动类(clearing class)是这样的:

<br class="clear" />

这样带来的一个问题是插入了很多不必要的换行。5.x采用了新的纯基于CSS的清除类,你的有关代码也要改变:

4.7.x

<div>
Some text here.
<br class="clear" />
</div>

5.x

<div class="clear-block">
Some text here.
</div>

theme_links() 函数在5.x中修正为返回链接列表,并且自动加入了帮助识别的CSS标记,包括“first”与“last"。

5.x中theme_links的用法

<?php
print theme('links', $primary_links);
?>

上面的PHP代码将会生成下面的HTML链接代码:

<ul class="links">

<li class="first menu-1-1-52"><a href="/drupalCVS/?q=test" title="" class="menu-1-1-52">test</a></li>

<li class="menu-1-2-52"><a href="/drupalCVS/?q=test2" title="" class="menu-1-2-52">test2</a></li>

<li class="last menu-1-3-52"><a href="/drupalCVS/?q=test3" title="" class="menu-1-3-52">test3</a></li>

</ul>

此外,你还可以提供参数来指定CSS类的ID:

<?php
print theme('links', $primary_links, array('class' =>'links', 'id' => 'navlist'));
?>

将生成下面的HTML代码:

<ul class="links" id="navlist">

<li class="first menu-1-1-52"><a href="/drupalCVS/?q=test" title="" class="menu-1-1-52">test</a></li>

<li class="menu-1-2-52"><a href="/drupalCVS/?q=test2" title="" class="menu-1-2-52">test2</a></li>

<li class="last menu-1-3-52"><a href="/drupalCVS/?q=test3" title="" class="menu-1-3-52">test3</a></li>

</ul>

6. drupal_add_js() 函数-插入javascript脚本

在4.7.x中,javascript文件是通过drupal_set_html_head()来加入到HTML header中的。

在5.x中模块中,javascript脚本是通过下面的函数插入的:

<?php
drupal_add_js
($data = NULL, $type = 'module', $scope = 'header', $defer = FALSE, $cache = TRUE);
?>

在theme中,可以通过drupal_get_js()函数来插入所有的javascript脚本(include, settings和js代码)。最好在你的theme一开始的部分,紧跟着drupal_get_css()函数就使用这一函数来插入javascript脚本。

在phpTemplate中,同时还新增了一个 $scripts 变量,包括加载设置javascript脚本所需的所有HTML代码。如果你需要在theme中替换某个javascript脚本,也非常容易:

<?php
  
// print $scripts;
  // 不要print $scripts,因为我们要在下面去掉autocomplete.js

  // 这里以数组的形式返回所有的javascript脚本信息
 
$js = drupal_add_js(NULL, NULL, 'header');
  unset(
$js['module']['misc/autocomplete.js']);
  print
drupal_get_js('header', $js);
?>

7. _phptemplate_callback 函数改变

在基于phptemplate引擎的主题中使用 _phptemplate_callback() 函数可以自定义theme所需的变量,供给相应的 *.tpl.php 文件使用。4.7中,你必须通过第三个参数 $file 来明确指定外部文件的名称,如果没有这一参数,那么drupal会自动使用 $hook.tpl.php 文件。在5.x中 $file 参数变成了一个数组,你可以提供一系列文件名作为建议,如果drupal没有找到建议文件,那么才自动使用 $hook.tpl.php ,这样就使得 _phptemplate_callback() 函数的应用更灵活更广泛。

4.7.x

<?php
function _phptemplate_callback($hook, $variables = array(), $file = NULL) {
?>

5.x

<?php
/**
* Execute a template engine call.
*
* Each call to the template engine has two parts. Namely preparing
* the variables, and then doing something with them.
*
* The first step is done by all template engines / themes, the second
* step is dependent on the engine used.
*
* @param $hook
*   The name of the theme function being executed.
* @param $variables
*   A sequential array of variables passed to the theme function.
* @param $suggestions
*   An array of suggested template files to use. If none of the files are found, the
*   default $hook.tpl.php will be used.
* @return
*  The HTML generated by the template system.
*/
function _phptemplate_callback($hook, $variables = array(), $suggestions = array()) {
?>

实用PHP与Javascript代码

Drupal有很多模块来实现不同的功能扩展,但其中的很多功往往可以通过简单的PHP/Javascript代码段来实现。这部分列出一些用户提交的实用PHP及Javascript代码段,这些代码段可以应用于Drupal页面、区块或主题中,来实现特定的功能。如果您也有一些实用的代码,欢迎在这里分享。

页面右上角会有Drupal版本分类,页面中也会尽量注明适用的Drupal版本号,请注意选择适当的代码。

注意:这些代码都是由用户提出,我们并不能保证其功能与安全性,请谨慎使用。某些恶意代码可能会破坏您的站点或带来安全问题,请尽量读懂代码是如何工作的,至少先在测试站点试用并备份您的站点。

PHP区块代码

下面列出的一些用户提交的常用的区块代码,您可以直接将它们复制到区块中(记得开启PHP输入格式),就可以实现特定的功能。

注意:使用前请仔细检查代码,并在测试站点试验。恶意代码可能会破坏您的站点。

显示数据库大小

下面这段block代码,通过计算数据库表单与索引的大小来显示Drupal使用的MySQL数据库大小。由于要查询所有数据库表单,执行起来可能比较慢,最好限制在管理员页面显示。

<?php
function db_size_info($dbsize) {
 
$bytes = array('KB', 'KB', 'MB', 'GB', 'TB');
  if (
$dbsize < 1024) $dbsize = 1;            
  for (
$i = 0; $dbsize > 1024; $i++) $dbsize /= 1024;
 
$db_size_info['size'] = ceil($dbsize);
 
$db_size_info['type'] = $bytes[$i];
  return
$db_size_info;
}
// Database size = table size + index size:
$rows = db_query("SHOW TABLE STATUS");
$dbssize = 0;
while (
$row = mysql_fetch_array($rows)) {
 
$dbssize += $row['Data_length'] + $row['Index_length'];
}
print
"$dbssize bytes<br />";
$dbssize = db_size_info($dbssize);
print
"or<br />";
print
"{$dbssize['size']} {$dbssize['type']}";
?>

PHP区块可见性代码

Drupal从4.7开始引入了区块可见性设置,可以通过简短的PHP代码来控制区块只在特定的页面显示。在页面显示时会自动检查该段代码,当代码返回TRUE时,就显示区块;当代码返回FALSE时,则不在该页面显示此区块。

基本逻辑如下:

<?php
 
if (condition) {
    return
TRUE// block will be shown
 
}
  return
FALSE;
?>

或者简化为:

<?php
 
return (condition);
?>

在区块管理页面可以开启使用PHP代码设定区块可见性,然后填入相关的代码就可以了。

实用SQL代码

SQL代码直接对数据库进行操作,在实现一些特别的功能特别是站点站点设置往往是非常简单有效的。下面SQL代码段都是Drupal用户提交的在实际应用中的代码,如果您也有一些简单有效的SQL代码,欢迎在这里和大家分享(可以在论坛提出,也可以在下面发表评论,请注明您的代码适用的Drupal版本号)。

注意:这些代码都是由用户提交,并没有经过仔细测试。在使用下面的代码前,请尽量仔细阅读代码并理解它是如何工作的;至少要先把您的站点的数据库备份,以免带来不必要的损失。

启用或关闭模块

有时候您可能需要通过数据库操作来启用或关闭模块,比如使用了有问题的模块时。

使用下面的SQL代码开启名字为"example"的模块:

UPDATE `system` SET status=1 WHERE name='example';

使用下面的SQL代码关闭名字为"example"的模块:

UPDATE `system` SET status=0 WHERE name='example';

清除Drupal缓存

在重装、转移或升级站点时,或者在站点开发测试时,往往需要清除Drupal缓存,以避免一些不必要的问题并及时看到站点的更新。清除缓存本身并不会破坏你的站点,也并不会丢失数据,最多使站点暂时变得较慢,当Drupal缓存重新建立后,你的站点速度也会恢复。下面的SQL代码可以用来清除Drupal缓存。

DELETE FROM cache;

(您也可以下载devel模块,这个模块提供了一些开发常用的工具,包括清除缓存按钮。)

重置第一个用户(超级用户)的密码

如果您忘记了超级用户的密码(uid=1),而通过emaili重置密码又不工作时,可以通过下面的数据库操作重置密码:

UPDATE `users` SET `pass` = MD5('mynewpassword') WHERE `uid` =1 LIMIT 1;

用您的新密码替换上面的mynewpassword就可以了。