第四部分:前端开发

第15章和第16章将带你踏上Drupal主题系统的探索之旅,讲述如何打造出强大且易于维护的网站。

第17章将介绍前端开发中的另一个关键部分,利用JavaScript构建强大且易用的功能来提升用户体验,更有趣的是jQuery库。

另见附录D,其中包括为Drupal设计。

第15章:主题化

Jacine Luisi

 

Drupal的主题层,以及主题使用到的,是负责外观或者一个Drupal站点给人的感觉。你会发现一些有名的网站上优秀的主题都包含一些相同的元素,具有符合标准的XHTML标记,CSS和JavaScript。这些是如何组合在一起的?是什么如此特别,是什么让Drupal的主题如此灵活和强大呢?

Drupal主题可以依据你的需要,既可以很简单也可以很复杂。主题具有对每个页面几乎所有部分的最终的决定权和控制权。和Drupal本身一样,主题也很灵活、很强大。无可否认,充分利用Drupal的主题层意味着要克服一个相当陡峭的学习曲线,如果对引擎的内部机制不够理解的话,很容易在开始时犯一些错误。

在本章,你将学习一些关于Drupal主题层的基础知识。你将学习如何去定制和合理修改以及常见任务的最佳做法。您将用自己的方式在任何时间创建灵活和可持续定制的Drupal主题!下一章将在这个基础上创建更加深入复杂的Drupal主题。

本章和下一章的一些例子你可以在DGD7主题里找到。如果你想跟进的话,可以到这里https://github.com/jacine/dgd7去下载。

核心主题目录

开始时,人们通常做的第一件事是到核心的“/themes”目录下,浏览主题中的文件以了解它的总体结构和目录。不幸的是,很多人开始时会错误地去直接定制核心的主题。不要犯这个错误!他们通常此后不久,就会碰到障碍和挫折。Drupal有一个庞大和多样化的用户群,而Drupal核心主题的主要目标是满足大众。

除了美学,核心主题要满足很多需求和不同的使用情况。有些主题支持Color模块,以使其方便让网站管理员改变用户界面的配色方案。这不是一件坏事,但是,它会在试图定制配色(colorized)主题时很容易造成混乱和令人沮丧,因为CSS是自动存储在主题目录外面的。核心主题,还必须有这样的功能,如果作为一个管理主题的话,他们必须支持双向文本;在一般情况下,它们不能偏离Drupal的默认区域和设置。

满足所有人并不简单,而Drupal核心主题恰恰肩负着这个重任。因此核心主题不能达到它本可以具有的灵活和尖端。大多数时候,你创建定制主题的目标和方法会有很大的不同。你将能够把重点放在编写你自己的前端或后端集中设计,定制标记,决定使用哪些CSS文件(如果有的话),和其他令人兴奋的决定。

核心主题

Drupal核心包含4个主题。它们将会在接下来的小节中介绍。

Bartik

Bartik是Drupal7的一位受欢迎的新成员,Drupal安装后将Bartik设为默认的面向用户的主题。这是一个干净、简单的主题,支持Color模块,较好地使用区域(见图15-1)。除了Drupal默认推荐的区域,Bartik还增加了7个区域,用于放置页脚和页脚分块的区块。

图15-1. Bartik是一个干净、简单的主题

Garland

Garland最初是在Drupal5中作为核心主题首次亮相。它是一个更复杂的主题,具有良好的color模块的支持(见图15-2)。它包含15个配色方案,并提供了一个选项,以固定或流动的布局之间切换。

图15-2. Garland是一个更复杂的主题,具有良好的color模块的支持

Seven

Seven也是Drupal7的新成员,同时也是Drupal管理界面的主题。Seven来自Drupal7用户体验项目(http://d7ux.org),它承载着许多用户体验上的改进。它包含了少量的区域,而把重点放在执行管理任务上。

图15-3. Seven是Drupal默认管理界面的主题。

Stark

Stark是一个独特的,轻量级的Drupal主题(见图15-4)。其主要目的是展示出Drupal的默认HTML标记和CSS。它不提供任何模板文件,除了默认边栏区域的基本布局样式,几乎没有提供任何CSS。别让它的简单欺骗你,它实际上是非常有用的。对开发人员来说,在为他们的模块编写CSS代码时,Stark是一个完美的主题。它也能够帮助开发者解决不确定问题是否出在主题上还是另一个模块上。

图15-4. Stark是一个独特的,的确很微小的Drupal主题。

主题引擎

Drupal的主题目录中也包含一个“engines”目录,其中包含一个叫做PHPTemplate的主题引擎。主题引擎提供了一种方式用来分离主题化输出模板文件如同原始的PHP一样简单。使用PHPTemplate引擎的主要好处是,简化了从表现中分离逻辑。这对那些不熟悉PHP语言的人将大有作为,因为他们都能够在主要包含标记和打印变量的模板文件下工作。

虽然其他主题引擎如Smarty、XTemplate和PHPTal可能被使用,PHPTemplate是Drupal的默认主题引擎而且也是迄今为止Drupal主题用过的最流行的主题引擎(许多流行的贡献模块也在使用),所以在本章中我们将会包含该内容。当然,也可以做纯PHP的Drupal主题。例如,变色龙(Chameleon)主题就是一个纯PHP的主题,http://drupal.org/project/chameleon。想获知更多可用的主题引擎完整列表,请访问http://drupal.org/project/theme+engines。

主题管理

主题设置任务位于Drupal管理中的“外观”(Appearance)一栏。这里就是你可以控制一些事情,如哪些主题打算开启还是禁用,你想申请哪些设置,你想选择哪种配色方案(如果你的主题支持color模块的话),等等。

开启和设置一个默认主题

在一个全新安装的Drupal7中,默认的主题(Bartik)出现在“外观”页的顶部,其次是启用和禁用的其他主题(见图15-5)。什么是默认主题?对Drupal来说,仅仅开启一个主题是不够的。设置一个主题作为默认主题就是让它成为前台主题(也就是你的站点访问者可以看到的主题)。

图15-5. 默认安装下外观页面展示开启的主题。

当你想一次同时利用多个主题时,开启一个主题而不设为默认主题是很有用的。当此设置与贡献模块一起使用时是更有益的。这样的例子如SwitchTheme模块(http://drupal.org/project/switchtheme),它允许用户从所有启用的主题名称列表中切换主题。

管理主题

在Drupal7中,Seven主题是默认的管理主题。管理主题通常用在执行管理任务时,其中大部分是发生在“/admin”路径下。你也可以选择允许在编辑站点内容时用管理主题。虽然有些主题比其他的对Drupal管理界面支持的更好,但是如果需要的话所有的主题都可以用来作为管理的主题。

管理主题的配置位于“admin/appearance”页面主题列表的下面。如果想同时在前后台都用一个主题,只要将默认的主题设置为管理主题即可。

全局主题设置

Drupal自带的一些主题设置,可以在管理界面配置。这是大部分网站定义个性化的地方,以及一些其他设置。全局设置页位于“admin/appearance/settings”路径下包含这些设置。当个别主题的设置页面上应用主题设置时,它们将覆盖全局设置。以下章节将详细介绍这些,以及在你的主题什么地方会碰到。

其中一些设置确定是否将位于模板文件中的变量因此输出出来。在图15-6中描绘的设置代表Drupal提供的默认值。这些都可以通过定义主题中的info文件里定义features来覆写,这将在“定义主题元数据”一节中进一步讨论。当在info指定一些功能时,你需要确保包含了所有你将要支持的功能,如只是一个的话,将会覆盖所有Drupal提供的默认值。以下是他们会在info文件中一些设置的快速参考:

features[] = logo
features[] = name
features[] = slogan
features[] = favicon
features[] = main_menu
features[] = secondary_menu
features[] = node_user_picture
features[] = comment_user_picture
features[] = comment_user_verification

图15-6. 全局设置页面

Logo

默认情况下,Drupal会在主题的根目录下寻找一个名为logo.png的文件。另外也有一个选项可以指定一个不同文件的路径作为logo,也可以上传一个logo。当Logo复选框选中时,一个叫做$logo的变量,它的路径将会输出在page.tpl.php里,若没有选中,logo将不会输出。

名字和口号

网站的名字是在安装过程中定义的。站点名字和口号都可以在“admin/config/system/site-information”页面进行修改。在主题设置页,你可以切换他们是否可见。两者都可用在page.tpl.php中,分别为$site_name和$site_slogan。

快捷图标

快捷图标,也称为favicon,是一个Drupal的小图标,出现在地址栏、书签和大多数浏览器的标签。和标志一样,快捷图标可以切换是否可见,也可用自定义的文件。默认的文件是“misc/ favicon.ico”。

在发布和评论中的用户图片

这些设置控制变量$user_picture和变量$picture是否分别在node.tpl.php和comment.tpl.php里输出,从而决定当查看节点和评论时图片是否显示。

评论中的用户验证状态

当用户没有一个验证的账号时,此项将显示在用户名字的旁边“(未验证)”。该文本是在template_preprocess_username()函数中定义,作为变量$variables[‘extra’]打印在theme_username()函数中。见“预处理和处理函数”和“主题函数”部分,了解如何改变它。

主菜单和次级菜单

当主菜单和次级菜单的复选框被选中时,变量$main_menu 和$secondary_menu就会以数组形式包含每个菜单的菜单链接在page.tpl.php中输出。在位于“admin/structure/menu/settings”菜单设置页,你可以选择每个用于哪个菜单。默认情况下,主菜单是用作填充$main_menu源的,可以通过在“admin/structure/menu/manage/main-menu”页来管理。默认的次级菜单源用作用户菜单,可以在“admin/structure/menu/manage/user-menu”页来管理。

这些都是在page.tpl.php中使用theme_links()函数(将在本章稍后介绍)简单的单级菜单输出。

这使得他们很难样式复杂的导航设计时使用。因为往往需要复杂的导航的,很多主题开发人员为导航创建区域和使用的区块来输出菜单,而不是使用这些菜单。我们强烈推荐Menu Block模块(http://drupal.org/project/menu_block),它允许你很容易地去使用菜单做几乎任何东西。

自定义主题设置

自定义主题设置与全局主题设置很相似,它可以由主题或者模块来提供。一个自定义主题设置的例子可以在Garland主题中的garland.info文件里看到。它创建了一个叫做“garland_width”的可以用来设置固定或者流体的设置。快捷方式模块还提供了设置在Seven主题里的遮罩层内的标题旁边提供小图标以显示“添加或删除快捷方式链接”。要学习如何为您的主题创建自定义主题设置,请访问http://drupal.org/node/177868。

安装一个新主题

Drupal会到它的主题目录去扫描可用的主题,因此将你的主题放在正确的目录下,这样Drupal才能识别它。你也有可能将新增的主题放置到Drupal的“/themes”目录下,但从技术上来讲,这被认为是“破坏核心”,并且应当避免。在下载和解压你的主题之后,选择以下哪个目录来放置主题。使用其中任何一个目录都可以帮你确保Drupal自身的任何升级不会覆盖你的主题。

  • sites/all/themes:当你想为你的Drupal中的所有站点安装使用这个目录的主题时。
  • sites/sitename/themes:提供给你的Drupal多站点安装在特定的网站上时。

您也可以使用主题安装程序,点击“外观”页的顶部安装新的主题链接,下载并安装来自贡献的主题。这将使你在这里您可以进入链接到项目下载的压缩包的位置,并单击“安装”。主题安装程序会自动下载你的主题,并放置在“sites/all/themes”目录。一旦完成,您可以像往常一样在“admin/admin/appearance”页上来启用主题。

与区域一起工作

在Drupal页面中所见到的大多数内容是输出在一个区域里的。典型的区域包括header、footer、 sidebar以及content(见图15-8);这些区域往往在定制高级的HTML标记结构时经常用到。在“admin/structure /block”页,区块中有一个选项可以设置显示到每个区域,允许网站的管理员控制和放置区块显示在里面。

图15-8. Bartik主题的区域以及在区块管理页面中的区块放置选项。

在区域的自定义和处理输出和美化上,主题具有充分的控制权。比如,在图15-9就给出了在Bartik主题里关于这方面的一个例子。

图15-9 Bartik区域里填充着定义的区块。

另外,还有一个不太显著的用途,主题有可能也会利用区域与JavaScript或者jQuery配合。常见的用例,包括包含模式或者隐藏某些内容来提升用户体验,或者将区块嵌入到节点内容里。

默认区域

默认情况下,Drupal核心通过程序为主题定义了9个区域。在清单15-2中的代码复制出了以“.info”文件格式默认区域。和大多数的主体层实现原理一样,主题定义区域的原因是因为他们想要修改或者添加到默认值。除非某个主题定义了它自己的区域,否则Drupal将使用默认的区域。这意味着,假如默认的区域足以满足你的设计,那么你将不需要在你的“.info”文件里定义区域。

清单15-2 Drupal的9个按时间顺序排列的预定义的主题区域

regions[page_top] = Page Top
regions[header] = Header
regions[highlighted] = Highlighted
regions[help] = Help
regions[content] = Content
regions[sidebar_first] = Sidebar First
regions[sidebar_second] = Sidebar Second
regions[footer] = Footer
regions[page_bottom] = Page Bottom

然而,在主题的“.info”文件开头包含这段代码是个不错的做法。倘若你仅定义一个区域的话,它将会覆盖核心默认的,因此保持默认区域的完整列表,注释掉已禁用的区域(而不是完全删除或者忽略)是一个很好的方法,可以跟进将用它们来做什么。其中的一些区域可能会需要,比如:page_top,content,page_bottom这些区域。对于正常运作的网站,这些是必需的且必须在每一个Drupal主题输出的。一个如何组织“.info”文件中的区域的例子,且考虑到默认设置,如清单15-3 所示。

清单15-3. 一个在“.info”文件中实现区域的例子

; 核心区域 – 禁用的
;regions[highlighted] = Highlighted
;regions[help] = Help
;regions[header] = Header
;regions[footer] = Footer
; 核心区域 – 需要的
regions[page_top] = Page Top
regions[content] = Content
regions[page_bottom] = Page Bottom
; CORE REGIONS
regions[sidebar_first] = Sidebar First
regions[sidebar_second] = Sidebar Second
; CUSTOM REGIONS
regions[my_custom_region] = My Custom Region

提示:如果对Drupal在哪里定义默认区域感兴趣,不妨看看“_system_rebuild_theme_data()”函数,地址在http://api.drupal.org/_system_rebuild_theme_data

如图15-10所示,展示的Drupal默认区域是一个标准的三栏布局。灰色的区域是必须的,而其余的是可选的。Header、sidebar_first、sidebar_second、footer是布局方面的区域。page_top和page_bottom是特殊区域;它们将在本章的“隐藏区域”部分讨论。

图15-10. Drupal的默认布局区域

Highlighted(高亮)区域取代了过去的站点任务(Mission),它过去是一个包含站点任务状态的静态变量,或者是一个在page.tpl.php中手动输出简短的摘要文本。过去实施不够理想有多方面原因,但是最主要是因为仅显示在首页。所以说,使用自定义的区块来显示此信息是一个更好的选择,因此创建了highlighted区域。

Help(帮助)区域曾经也是page.tpl.php中的变量,用于输出错误和状态信息。现在状态信息放在一个称为“系统帮助”的区块中,同时Help区域用于放置它。但是“系统帮助”区块可以很容易地放在内容区域中,权重设置高于内容区块也能达到同样的效果。

内容区域是Drupal7新增的。据介绍,包含页面主要内容的区块,有一点比较特殊,就是它可以在区域之间切换,但是不能被禁用。

定义主题元数据(.info文件)

.info文件(读作“点info文件”)包含关于你的主题的元数据,例如,主题的名字,Drupal支持的哪个版本,以及一些如样式表和主题将包括的区域等。书写info文件通常是是创建一个主题的第一步。

文件的第一部分名字通常是机器识别的主题的名称,它是Drupal用来存储关于你的主题到数据库的信息。破折号和其它特殊字符是不允许的。虽然下划线是被允许的,但是通常认为最佳的做法是避免使用它们命名你的info文件。使用themename.info而不是theme_name.info。当进行主题函数覆写时,这个名字也用于函数名字的前缀。当覆写theme_menu_link()函数时,比如,当试图确定覆写正在被执行时,函数名themename_menu_link()通常比theme_name_menu_link()更容易阅读。

注意:你的主题(机器)名字必须唯一的。不要让你的名字与已有的模块重名,因为这样有可能会导致命名空间问题和增加追踪下载PHP错误的难度。

每个主题依赖主题的info文件中的一些基本属性。名字、核心和引擎属性都是Drupal主题最起码的要求。下面章节将包含每个可选属性的概述,并且带有语法说明。

提示:为了给info文件添加注释,在每一行的开头添加一个分号,像这样:

;这是一条注释。注释非常好。经常去使用它。

必要属性

Core:Drupal将仅当你的核心设置为支持当前的Drupal主版本时,才允许你的主题可以被开启。主版本仅仅是6.x,7.x或者8.x等。

core = 7.x

Name:人类识别的主题名字。它不需要与机器识别的名字一致或者相似,这里可以自由创建。

附加属性

Base theme(基主题):Drupal允许主题间设立一点关系。创建一个子主题,它可以继承基主题(详见下一章)的功能和优点。创建子主题时,需要指定基主题。在这里用的基主题的机器名很重要。

base theme = themename(主题名称)

Description(描述):是指主题的基本功能或用途需要在此说明。描述将被显示在“admin/appearance”页面,描述也可以包含HTML。

description = The description of my theme(我的主题描述)

Engnine(引擎):指定主题引擎。PHPTemplate是默认和最常用的,所以除非你想改变它,没有必要去手动设置。其他选项包括一个纯PHP主题的醒目和主题(比如,到http://drupal.org/project/chameleon看一下Chameleon主题)。

engine = phptemplate

Features(功能):设置功能是覆写Drupal全局主题设置的一种方法。下面是Drupal默认主题设置的一个列表。这些设置可以在每个主题设置页面的主题界面上进行开关的切换。甚至指定禁用Drupal默认的而使用你的。

features[] = logo
features[] = favicon
features[] = name
features[] = slogan
features[] = node_user_picture
features[] = comment_user_picture
features[] = comment_user_verification
features[] = main_menu
features[] = secondary_menu

PHP:Drupal 7支持PHP 5.2.5版,默认情况下你的主题也是如此。这一点,你可能永远不会需要,但万一你的主题包含只有一定PHP版本的代码,你可以在这里指定。

php = 5.3

Regions(区域):区域是页面用来放置内容(区块)的地方。每一条都是以“regions”为前缀,括号中为区域的系统名称,最后以人类可读得名称作为值。例如:regions[system_name] = Human readable name(人类可读的名字)。默认的区域如下:

regions[page_top] = Page Top
regions[header] = Header
regions[highlighted] = Highlighted
regions[help] = Help
regions[content] = Content
regions[sidebar_first] = Sidebar First
regions[sidebar_second] = Sidebar Second
regions[footer] = Footer
regions[page_bottom] = Page Bottom

Settings(设置):设置属性是用来储存主题中的自定义实现的。Garland主题提供了设置站点管理员可以选择布局的类型(固定或者流式)。虽然我们不会包含自定义主题的设置,但是我们强烈建议查看Omega(http://drupal.org/project/omega)和Fusion(http://drupal.org/project/fusion)主题,来了解主题设置如何使用的。更多信息,请查看http://drupal.org/node/177868。

settings[garland_width] = fluid

Screenshot(截图):Drupal会自动在主题根目录下查找叫做“screenshot.png”的文件,所以此行只有在你需要使用一个主题截图替代路径或者文件名字时才是必须的。截图的推荐推荐尺寸是294 x 219像素。

sceenshot = screenshot.png

Stylesheets:Drupal 7 中有相当多的方式来加入CSS文件。如果你想在每个页面都加载CSS文件的话,你可以在主题的info文件中添加css。在下一章中的“管理CSS文件”部分将会详细介绍。

stylesheets[screen][] = path/to/screen-stylesheet.css
stylesheets[print][] = path/to/print-stylesheet.css

Scripts:JavaScript文件可以在info文件中使用scripts属性来定义。和样式表相似,当你需要在每个页面都加载某些JavaScript文件时。

scripts[] = path/to/script.js

version:贡献的主题和模块都是不提倡定义版本的。这是因为drupal.org有一个包装脚本,在发行新版本时,用来详细控制添加版本。当然,如果需要的话,你可以在自定义的主题中使用它。

version = 7.x-1.1

现在我们就通过实例看一下你的DGD7主题下初步的样子,如列表15-1中所示。

列表15-1。DGD7主题info文件的顶端部分

name = DGD7 Theme

description = A theme written for The Definitive Guide to Drupal 7 book website.

core = 7.x

核心的属性除外,所有上述的都可以在“admin/appearance”页面的用户界面中看到,如图15-7所示。这是你展开主题所需要的。

图15-7. DGD7主题显示在主题列表页admin/appearance上。

创建你的第一个主题!

根据到目前为止所学到的,创建一个自定义的主题:

1. 通过在“sites/all/themes”目录下创建一个名为dgd7的文件夹开始。

2. 在dgd7文件夹下,创建一个名为dgd7.info的文件,同时将加入以下代码:

name = DGD7 Theme
description = A theme written for The Definitive Guide to Drupal 7 book website.
core = 7.x

3. 从本章的源代码文件中取得screenshot.png并复制到dgd7文件夹下。这一步是可选的。如果没有定义截图,将会以“没有截图”来代替。

4. 现在访问并重新加载admin/appearance页面,你将看到该主题位于“禁用的主题”之列。点击“启用并设为默认”链接开始在你的站点上使用该主题。

提示:你需要清除你的网站的缓存来让info文件中的改动生效!若想清除网站的缓存,请查看位于“admin/config/development/performance”的性能页面。