听晴空讲Drupal主题——第四章 德国人写的主题教程(1)

前言:我承认,这一整章的内容之所以选择翻译这个德文的教程,是因为我有点偷懒。因为前面三章的内容是我自己规划的,往往写一节只需要2,3个小时,但是构思推敲写什么内容却让我大伤脑筋。正好玩Drupal的人看英文估计也没啥问题,德文就不一定了。所以这次我给大家换换口味带来一套基于德文的翻译资料。

4.1 德国人写的主题教程(1)How to Make a Drupal Theme step by step  (1)

http://www.drupaltutorials.de/2013/06/19/drupal-themes-teil-2

在最理想的情况下,你只要用一个已经做好的系统就可以忽悠你的客户了——Drupal官网提供的那些现成的主题和模块在某种意义上来说,就是出于这种目的。事实上在现实中也有很多这样的例子。在这篇教程里,我们将讲述从哪里可以得到主题,如何安装并使用它们。

有许多主题都是免费提供的。你可以在官网的https://drupal.org/project/Themes中找到。在你们下载一个主题之前,请一定记住检查它所适用的Drupal版本是否与你使用的版本一致。你可以通过页面上的“compatibility”过滤器来选择你想要的版本。

点击“search”按钮后搜索就开始了。在搜索结果列表的第一页中往往会有几个基主题,你可以在他们的基础上创建自己的主题。(更多有关基主题的话题我们将在下一节讲到)。除了这些基主题之外,更多的搜索结果则是普通的主题。

你们可以随便下载一个主题来学习如何安装Drupal主题。(我在这里选择的是“Professional Theme”:https://drupal.org/project/professional_theme)。和下载模块一样,你既可以选择tar.gz也可以选择zip文件。

下载完成后文件并不需要手动解压缩。在顶部导航条找到“外观”,并点击“安装新主题”(/admin/appearance/install)。通过“选择文件”按钮,你可以选择之前下载好的主题包。然后点击“安装”按钮,开始安装主题。Drupal会自动将主题安装到目录sites/all/themes下。如果要启用这个主题,你可以在/admin/appearance页面中,“禁用的主题”区域中找到新安装的主题,点击“启用”即可。在这个页面中,你可以看到所有已经安装的主题及他们的缩略图。

你也可以点击“启用并设为默认”链接。这样的话在前台就可以看到相对应的结果。

如果前台没有显示出这个新安装的主题,请检查是不是安装并启用了其它主题。启用主题之后,你可以点击“设置”链接来对主题进行配置。至于有哪些配置选项则取决于你安装的是什么主题。

主题的细节

每个主题在https://drupal.org上都有自己的主页。页面所提供的主题都附带了很多信息,你很有必要在安装之前了解一下这些信息。

除了一段简短的描述之外都会注明主题的其它一些特性。其中比较重要的一个特性是对浏览器版本的兼容性描述。而最重要的信息则是主题所适用的Drupal版本。因为为Drupal6开发的主题是无法在Drupal7安装的。

与此同时有很多主题都有一个在线Demo。

通过这个Demo我们可以很直观的看到主题的效果。

另外你还一定要看一眼bug报告。这里重要的信息并不是bug的数量,而是bug修补的速度。有些bug甚至根本没有被处理过——这可不是我们希望的结果。

在主题的下载区域的版本栏中(Version),注明了主题所对应的Drupal版本。如图:7.x表示这个主题是为Drupal7开发的。

如果你非要尝试安装一个不兼容版本的主题,安装的过程会被中断并报错。

你还应该注意一些主题的Beta版和Alpha版本。这样的主题中依然存在没有排除的错误,所以你无论如何不能用它来忽悠你的客户。

以下省略废话238句。。。。

Drupal 版本: 

听晴空讲Drupal主题——第四章 德国人写的主题教程(2)

4.2 德国人写的主题教程(2)How to Make a Drupal Theme step by step  (2)

http://www.drupaltutorials.de/2013/06/21/drupal-themes-teil-3/

 

修改已经做好的主题来完成项目,是对于大多数的Drupal使用者来说最轻松的方式。因为这种情况下,你只需要对颜色做少量改动,修改少量代码,就可以让你的网站看上去独一无二。但是,这样是远远不够的。因为如果你想在网页上实现自己设计的样式,你就一定无法避开主题开发的过程。

在你开始制作自己的主题之前,你必须学习一些与其相关的基础知识。理论上,你应该熟悉以下技能(至少了解一点点):

• CSS
• (X)HTML
• PHP

你应该有很好的css和html经验,并对PHP有一些最基本的了解。如果你的页面还会需要JS特效的话,那你当然也应该对Javascript有所了解。

 

重要工具

首先还要介绍一下制作主题所必须的工具。其中最经典的就是Firefox的插件:Firebug。通过这个插件,你可以在浏览器上对页面元素和代码逐行定位和检查。你还可以直接在插件中改动页面代码并实时查看结果。

你可以在http://getfirebug.com/下载Firebug。

如果你使用的是火狐firefox浏览器,并访问这个页面的话,就能自动安装firebug插件。对于谷歌Chrome浏览器,或者IE等,也有类似Firebug的工具(或者是精简版)。你可以在http://getfirebug.com/firebuglite页面找到。

你还应该在你的Drupal网站上安装Devel模块。这个模块可以为你显示出页面上的Drupal参数。Devel模块的下载地址是:https://drupal.org/project/devel。另外,你还需要安装simplehtmldom api模块,地址https://drupal.org/project/simplehtmldom

因为这个模块是theme developer模块的支持模块。Theme developer模块的地址为:https://drupal.org/project/devel_themer。一旦你安装并启用了这个模块,你就会发现主题开发的难度明显降低了,因为这个模块会为你提供主题相关的重要信息。

 

一旦你启用了这个控制选项,你的Drupal网页行为就会发生一些变化。启用之后,当你的鼠标划过每个元素的时候,元素的周围会出现一个红色的边框。

点击某个页面元素,就能看到相应的信息。

这样你就知道这个元素相对应的模板建议和主题函数都信息。

 

基主题的使用

制作Drupal主题的流程有好几种。你当然可以自己从头开始去制作主题,但是更容易和高级的办法是使用基主题。在这些主题中,一些基本的元素和规则已经为你定义好了。在官网中提供了很多不同的基主题,其中最有名的基主题无疑是Zen(https://drupal.org/project/zen)。

Zen是一个基于Html5的主题,它提供了很多实用的功能。除了zen之外,还有很多其他有用的基主题,比如:Framework,Omega和Blueprint等。我将向大家介绍用Genesis基主题进行主题开发的基本方法。Genesis主题的官方地址为https://drupal.org/project/genesis

 

你可以在这个页面下载Genesis。解压缩你下载的文件,并将文件中的两个子文件夹genesis和genesis_SUBTHEME拷贝到sites/all/themes路径下。并将genesis_SUBTHEME的名字修改为你的主题的名字,在我们的例子中,我们用psdtutorials作为主题名称。

这样,准备工作就完成了,并且可以开始主题开发工作了。

.Info文件

首先来看看themename.info文件。(这里的themename就是主题的名字。)如果缺少了这个文件,Drupal系统就无法识别主题文件夹中的文件,所以这个文件是必须存在的。打开文件夹/all/themes/psdtutorials并将genesis_SUBTHEME.info文件命名为psdtutorials.info。这个文件中包含着和主题有关的重要信息。这个文件中包含这普通的命令语句也包含注释语句。注释语句是用分号来进行识别的。

; $Id: genesis_SUBTHEME.info,v 1.25 2011/01/14 03:12:40 jmburnz Exp $

; Change the name to match your new subthemes name and modify the description.

这里紧接着就是主题的基本信息。

name         = Genesis SUBTHEME

description  = My Kickn' Sub-theme

core         = 7.x

engine       = phptemplate

screenshot   = genesis-subtheme.png

base theme   = genesis

 

每一行应该只有一条语句。主题的名字是必须定义的。它会显示在主题管理页面。虽然并没有规定主题文件夹名字和info文件中定义的主题名字一样,但是在实践中两者一般都是一致的。

name = psdtutorials

 

接下来就是主题的描述。

主题的描述会出现在主题管理页面中主题名字的下方。

description = Ein Theme von psd-tutorials.de(psd-tutorials.de网站的主题)

 

"core"定义了主题所适用的版本。如果是为Drupal7开发的主题,我们通常写为:

core = 7.x

 

"engine"指定了主题所使用的模版引擎。一般来说,都是phptemplate。(晴空注:在drupal8中使用的是twig引擎,欢呼雀跃吧。)

engine = phptemplate

 

"screenshot"定义的是主题的缩略图。缩略图被用于在主题管理页面显示。通常你都会在主题做好的时候才会定义这个。(晴空注:其实完全可以在一开始就定义好,到最后才处理图片),这里用主题的名字来给缩略图命名。

screenshot = psdtutorials.png

 

另一个重要信息是定义基主题"base theme"。这条语句定义了这个主题的基主题是什么。在我们的例子中基主题是genesis。

base theme = genesis

 

于是这个主题的info文件的开头应该是如下:

name         = psdtutorials

description  = Ein Theme von psd-tutorials.de

core         = 7.x

engine       = phptemplate

screenshot   = psdtutorials.png

base theme   = genesis

这样你就为做好你自己的主题迈出了第一步。其余的步骤将在接下来章节中讲到。

Drupal 版本: 

听晴空讲Drupal主题——第四章 德国人写的主题教程(3)

4.3 德国人写的主题教程(3)How to Make a Drupal Theme step by step  (3)

http://www.drupaltutorials.de/2013/06/26/drupal-themes-teil-4/

 

上一节中你已经做了一个自己的主题。现在我们继续讲述如何制作主题。我们首先还是继续关注info文件。因为这个文件中还声明了网站必要的css文件和主题中会用到的区域。最后你将学会如何用firebug来对页面进行临时性的修改。

在继续之前你可以将你的主题设置为系统默认主题。在主题管理页面你之前新建的子主题下面点击“启用并设为默认”。

现在就可以进行下一步骤了。当你设置了info文件头部的关于主题的基本信息之后,接下来就是定义主题需要使用的样式表。

; Subtheme modular stylesheets.

  stylesheets[all][] = css/html-elements.css

  stylesheets[all][] = css/page.css

  stylesheets[all][] = css/fields.css

  stylesheets[all][] = css/nodes.css

  stylesheets[all][] = css/blocks.css

  stylesheets[all][] = css/comments.css

  stylesheets[all][] = css/navigation.css

  stylesheets[all][] = css/views-styles.css

  stylesheets[all][] = css/custom.css

这里的css文件路径必须是相对于主题文件夹的相对路径。你可以在psdtutorials文件夹中的css子文件夹找到相应的css文件。如果你自己写了一个css文件,你也应该把它放在这个文件夹中。同时你还应该注意Css的文件顺序。因为css的特别之处就在于层叠,事实上Css的中文名称就是层叠样式表。最后定义的样式总是会覆盖掉之前定义的。

  stylesheets[all][] = css/custom.css

[all]的意思是这个css文件将在所有输出媒介上起作用。

相对应的,你还可以用单独的css文件来定义网页的打印样式。

  stylesheets[print][] = css/print.css

 

接下来是区域的定义。

; The regions defined in the page.tpl.php file. The name in brackets is the 

; name of the variable. The text after the = sign is the short description 

; you see on the block configuration page.

注释:page.tpl.php文件中所使用的区域定义如下:方括号中的名字是变量名。等号后面的文字是区域的名称,即简单描述,这个描述会被显示在区块设置页面上。

  regions[sidebar_first]      = Sidebar first

  regions[sidebar_second]     = Sidebar second

  regions[content]            = Main Content

  regions[highlighted]        = Highlighted

  regions[leaderboard]        = Leaderboard

  regions[header]             = Header

  regions[secondary_content]  = Secondary

  regions[tertiary_content]   = Tertiary

  regions[footer]             = Footer

  regions[help]               = Help

  regions[page_top]           = Page top

  regions[page_bottom]        = Page bottom

我们之前已经说过,区域中放置的是区块。

如果你把info文件定义区域的语句和区块管理页面(结构>区块)上的区域进行对比,就可以非常直观的看出这些语句的含义。

你会发现info文件中定义的区域顺序和区块管理页面中所显示的顺序是一致的。你可以通过下拉选择菜单把区块放置到你指定到区域中。区域的定义规则非常简单直接,不管你定义多少个区域,规则都是一样的。

regions[page_bottom] = Page bottom

中括号中的是区域的变量名称。你在区块管理界面上看到的区域名,是被定义在等号右边的。

将主题中可用的区域演示出来是一个很有用的做法。导航至“结构>区块”的区块管理页面并点击“演示块区域(你的主题名称)”。

最后你可以看到如下所示的结果:

这样你就可以非常直观的看见主题中有哪些区块可以使用。使用这个方法你能快速的了解一个主题的区域设置以及如何套用——并且在你使用基主题的时候非常有用。一般来说,基主题都会提供一个详细的使用文档来说明这个套用的方法。

负责区域划分的是Css文件layout.css,它位于sites/all/themes/genesis/css文件夹里。下面是它的部分摘要:

/* Standard 3 column, em based widths. */

#genesis-1a .two-sidebars .content-inner{margin:0 22em;}

#genesis-1a .sidebar-first .content-inner{margin-left:22em;}

#genesis-1a .sidebar-second .content-inner{margin-right:22em;}

#genesis-1a #sidebar-first{width:20em;margin-left:-100%;}

#genesis-1a #sidebar-second{width:20em;margin-left:-20em;}

/* Standard 3 column, % based widths. */

#genesis-1b .two-sidebars .content-inner{margin:0 25.25%;}

#genesis-1b .sidebar-first .content-inner{margin-left:25.25%;}

#genesis-1b .sidebar-second .content-inner{margin-right:25.25%;}

#genesis-1b #sidebar-first{width:24.25%;margin-left:-100%;}

#genesis-1b #sidebar-second{width:24.25%;margin-left:-24.25%;}

/* Standard 3 column, px based widths (default). */

#genesis-1c .two-sidebars .content-inner{margin:0 260px;}

#genesis-1c .sidebar-first .content-inner{margin-left:260px;}

#genesis-1c .sidebar-second .content-inner{margin-right:260px;}

#genesis-1c #sidebar-first{width:240px;margin-left:-100%;}

#genesis-1c #sidebar-second{width:240px;margin-left:-240px;}

这里定义了几种不同的页面样式。首先让我们来关注#genesis-1a。这是一种非常经典的Drupal页面排版方式。页面中间有一个主区域,在它两侧分别有一个左边栏和一个右边栏。第一栏的宽度是22em。这里#genesis-1a是用em单位定义的。这种单位的优点是:字体大小会自动跟随栏宽变化。其他的定义方式也在注释中进行了说明。

/* Standard 3 column, em based widths. */

类似于Genesis的基主题的一个特点就是它的灵活性。Em单位并不是你的唯一选择。#genesis-1b的注释语句就非常清楚的标明你也可以使用百分比来定义宽度。

/* Standard 3 column, % based widths. */

与此同时,你也可以用基于像素的px来定义。

/* Standard 3 column, px based widths (default). */

此时Firebug就派上用场了。因为使用这个工具可以非常直观的看出layou.css文件中所给出的定义。在你的Firefox浏览器的右上角点击Firebug图标。

Fitebug的界面就会如下图显示出来。打开HTML标签。

这里面显示的是页面的结构。此处的重要信息来自于下列语句:

<body thmr="thmr_78" id="genesis-1c">

这里使用的ID名称为genesis-1c,因此,页面样式是基于CSS中定义的#genesis-1c输出的——即直接指定像素值。在body中找到ID为#content-inner的div。

点击这个div元素,在右侧的窗口中就会显示出相对应的CSS定义。

在之前的章节中已经提过,使用Firebug可以让你直接在页面上修改代码而不用去改动实际的文件。你可以自己试一试。点击ID#genesis-1c,你就会发现这个ID现在可以被修改了。

如果现在你把ID genesis-1c改为genesis-2b,你就会发现页面输出会发生实时的变化。

通过这种方式你可以非常灵活的使用基主题。你只需要修改body的ID就能让页面排版发生根本的变化。正如我们之前说过的,使用基主题的好处就在于它已经为你定义好了很多东西。你可以想象,如果你不使用基主题而是自己从零开始写样式,你需要花费多少时间。同样的,我们通过上述过程也不难发现Firebug是开发主题时,非常必要的工具。

Drupal 版本: 

听晴空讲Drupal主题——第四章 德国人写的主题教程(4)

4.4 德国人写的主题教程(4)How to Make a Drupal Theme step by step  (4)

http://www.drupaltutorials.de/2013/06/28/drupal-themes-teil-5/

 

上一节讲述的在Firebug中调试及改变页面输出只能临时性的,如果你想永远的改变你的主题,你就必须修改相对应的原始文件,如下图所示的tpl模板文件。这一节,我们将讲述和模板文件有关的知识。

做Drupal主题的人或早或晚都要接触到模板引擎的概念。首先我们来说一下什么是模板引擎。模板引擎是用来将模板中预定义的占位符替换成相应的动态内容的软件。如果你使用过微软的Word,那你一定用过一个类似的功能:邮件合并。在这个功能中就使用到了占位符,它会被用实际的值所替换。模板引擎的工作方式和这个过程非常相似。只是这里使用的占位符是模板变量。在Drupal7中默认的模板引擎是PHPTemplate。

和传统的HTML静态模板不同的是,你所下载的Drupal主题包中包含了更多的文件。因为Drupal系统在浏览器上渲染一个页面的时候通常需要同时加载好几个文件。

总体说来你在制作Drupal主题的时候,你会频繁的和tpl.php文件打交道。让我们先来看看html.tpl.php这个文件,

你会发现这个文件是以HTML语句为主体的。

 

<!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>

<?php // modify the layout by changing the id, see layout.css ?>

<body id="genesis-1c" <?php print $attributes;?>>

  <?php if (!$in_overlay): // Hide the skip-link in overlay ?>

    <div id="skip-link">

      <a href="#main-content"><?php print t('Skip to main content'); ?></a>

    </div>

  <?php endif; ?>

  <?php print $page_top; ?>

  <div id="container" class="<?php print $classes; ?>">

    <?php print $page; ?>

  </div>

  <?php print $page_bottom; ?>

</body>

</html>

在你套主题之前,理解主题的基本规则是非常重要的。Html.tpl.php文件存在于modules/system文件夹。

但是你不应该修改这个文件,因为当你下一次升级你的Drupal系统的时候,你会丢失之前所作的改动。如果在你的主题中没有定义html.tpl.php文件的话,则系统会使用默认的的Html.tpl.php文件,即modules/system文件夹中的这个。但是我们现在使用的是Genesis的子主题,而Genesis主题就定义了自己的html.tpl.php文件。

因此,如果你使用Genesis的子主题的话,你也需要修改这个文件。只是这个时候你需要在子主题的文件夹中进行模板覆写。你需要做的是将sites/all/themes/genesis/templates文件夹拷贝至你的子主题文件夹中。在我们的例子中是拷贝至psdtutorials文件夹中。

你可以用你习惯的编辑软件打开这个位于templates文件夹中的html.tpl.php文件。你可以很明显的区分开HTML代码和占位符。让我们先来看看页面的头部。

<!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; ?>>

在我们详细介绍PHP调用之前,先说一下一般的语法规则。在HTML语句中,PHP段落都被特殊的标志标识出来了。< ?php表示php段落的开始,?>则表示结束。通过print将数据打印出来。Php变量则用前缀美元符$标明。对于进一步学习Drupal主题来说,知道以上这些php的基础知识,就已经足够了。

$language->language 和 $language->dir 是文件中出现的第一组PHP变量。$language->language指定了文件的语言。由于这是德国人写的教程,因此,在Drupal后台设置的语言为德语,所以在页面代码中自然给出的是德文的缩写:de。$language->dir定义的是语言方向,所以在页面代码中为ltr即从左到右(left to right)。如果你在后台定义的网站语言为阿拉伯语,此处则应为rtl即从右到左(right to left)。

最后在前台所生成的语句为如下所示:

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="de" version="XHTML+RDFa 1.0" dir="ltr"

接下来的代码是:

<head profile="<?php print $grddl_profile; ?>">

它在前端显示为如下:

<head profile="http://www.w3.org/1999/xhtml/vocab">

这里给出的是关于GRDDL的信息。

接下来是网页的通用头部信息。

<?php print $head; ?>

它包含了网页的meta语句,和其他一些信息。

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<meta about="/drupal/de/artikel/willkommen" property="sioc:num_replies" content="0" datatype="xsd:integer" />

<link rel="shortcut icon" href="http://localhost/drupal/misc/favicon.ico" type="image/vnd.microsoft.icon" />

<meta content="Willkommen" about="/drupal/de/artikel/willkommen" property="dc:title" />

<link rel="shortlink" href="/drupal/de/node/33" />

<meta name="Generator" content="Drupal 7 (http://drupal.org)" />

<link rel="canonical" href="/drupal/de/artikel/willkommen" />

接下来是网页的标题。

<title><?php print $head_title; ?></title>

在前端页面中代码如下:

<title>Willkommen | psd-tutorials.de</title>

这个标题是用来显示在浏览器标签上的,同时搜索引擎也会用到它。

与此同时,CSS样式表也是通过一个php占位符写入到模板文件中的。如下:

<?php print $styles; ?>

渲染页面的时候,主题机制会载入相应的CSS文件。

<link type="text/css" rel="stylesheet" href="http://localhost/drupal/sites/default/files/css/css_p3syK-T8t8V3ZGjB8swO5jedvKfBvVtkoAjYdXNLClw.css" media="all" />

<link type="text/css" rel="stylesheet" href="http://localhost/drupal/sites/default/files/css/css_1F_DWBEe6Y_Lcyjyw2nPG4eT_LqzZlakOP7KI72f2lc.css" media="all" />

<link type="text/css" rel="stylesheet" href="http://localhost/drupal/sites/default/files/css/css_2tTaFkDpg4SwEzf7fKntXDus0W90gh3TRtU3OOCMM_w.css" media="all" />

<link type="text/css" rel="stylesheet" href="http://localhost/drupal/sites/default/files/css/css_nRO6Ys3khj3ugc-sJVpMesAwCuAesICrUvNM0FcBfos.css" media="all" />

和CSS文件类似的,Javascript文件也是用类似的方法被动态的写入页面的。与之相对应的是如下的php语句:

<?php print $scripts; ?>

这条语句在前端页面会生成类似如下的代码:

<script type="text/javascript" src="http://localhost/drupal/sites/default/files/js/js_3jHghlMLrjr9xXAC0JufqSSch3oAbkZstSqYdc4uuck.js"></script>>

<script type="text/javascript" src="http://localhost/drupal/sites/default/files/js/js_yBooQ7AJkK6sDqhu5cy003gG6ik9Ps-P4Ov8YpNnU5w.js"></script>

<script type="text/javascript" src="http://localhost/drupal/sites/default/files/js/js_2KlXA4Z5El1IQFVP

在html.tpl.php文件中还有很多其他的PHP变量。但是我们还是按照文档的依次顺序,继续往下看。首先是body。

 

<body id="genesis-1c" <?php print $attributes;?>>

在这条语句中你会看到上一节中我们试图用Firebug修改过的ID。现在你可以根据自己的意愿来修改套用这个ID。上一节中我们已经讲过了你有哪些选择可以使用。

你可以在Genesis主题的layout.css文件中找到相应的ID名。如果改动后前端页面没有变化,则请清空你的缓存(设置>性能>清空缓存)。

在这个文件中你还能找到如下内容:

<?php print $page_top; ?>

  <div id="container" class="<?php print $classes; ?>">

    <?php print $page; ?>

  </div>

  <?php print $page_bottom; ?>

Drupal主题机制通过这段语句将不同的模板文件嵌套在一起,以此来渲染出最后的页面。这其中最重要的是变量$page。因为页面上几乎所有的内容都是通过这个变量渲染出来的。关于这个变量是如何调用如何执行的将涉及到page.tpl.php文件,相应的内容我们将在下一节中讲述。

Drupal 版本: 

听晴空讲Drupal主题——第四章 德国人写的主题教程(5)

4.5 德国人写的主题教程(5)How to Make a Drupal Theme step by step  (5)

http://www.drupaltutorials.de/2013/07/03/drupal-themes-teil-6/

现在你已经认识html.tpl.php文件了。但是在模板文件夹中还有很多其它的文件。我们将在这一节和下一节中详细讲述。只要你掌握了模板的规则并认识各种模板文件,你就可以非常轻易的套用模板,甚至可以自己从零开发一套主题。在这一节中我将重点讲述page.tpl.php和region.tpl.php。这两个文件都是非常重要的。

Page.tpl.php是最重要的模板文件之一。在前一节的学习中,你已经从genesis基主题拷贝了它的templates 文件夹到你新建的子主题文件夹中。因此你可以在自己的主题文件夹的templates 文件夹中找到这个文件。

Page.tpl.php文件中的内容会通过html.tpl.php文件中的$page变量渲染出来。

<div id="container" class="<?php print $classes; ?>">

  <?php print $page; ?>

</div>

仔细的研究page.tpl.php对于初学者学习主题是非常有必要的。首先来看看这个文件的第一段:

<?php if ($secondary_menu_links): ?>

      <div id="secondary-menu-wrapper" class="clearfix">

        <div class="secondary-menu-inner"><?php print $secondary_menu_links; ?></div>

      </div>

 <?php endif; ?>

在这里你会发现,Drupal模板文件中经常会出现的一个语法元素,也就是这段中的IF语句。它的意思是在判断$secondary_menu_links变量是否存在,换句话说,是在判断是否为页面设置了二级菜单。如果存在二级菜单,前端页面代码中才会出现相应的用来显示二级菜单的内容。每一个在模板文件中出现的元素都有着自己的ID或者Class(类)名,正因为如此才使得他们可以用css文件定义样式及外观。

Page.tpl.php.文件中接下来的语句是这样的:

<div id="header" class="clearfix">

      <?php if ($site_logo || $site_name || $site_slogan): ?>

        <div id="branding">

          <?php if ($site_logo or $site_name): ?>

            <?php if ($title): ?>

              <div class="logo-site-name"><strong>

                <?php if ($site_logo): ?><span id="logo"><?php print $site_logo; ?></span><?php endif; ?>

                <?php if ($site_name): ?><span id="site-name"><?php print $site_name; ?></span><?php endif; ?>

              </strong></div>

            <?php else: /* Use h2 when the content title is empty */ ?>

              <h2 class="logo-site-name">

                <?php if ($site_logo): ?><span id="logo"><?php print $site_logo; ?></span><?php endif; ?>

                <?php if ($site_name): ?><span id="site-name"><?php print $site_name; ?></span><?php endif; ?>

             </h2>

            <?php endif; ?>

          <?php endif; ?>

          <?php if ($site_slogan): ?>

            <div id="site-slogan"><?php print $site_slogan; ?></div>

          <?php endif; ?>

        </div> <!-- /branding -->

      <?php endif; ?>

      <?php if ($page['header']): ?>

        <div id="header-blocks"><?php print render($page['header']); ?></div>

      <?php endif; ?>

</div>

你们会发现类似的很多情况都是用IF语句判断的。比如这里就是否在后台设置了页面logo、标题、广告语进行了判断。

如果在后台的主题设置界面中你没有指定Logo图片,并且也没有选择使用默认的Logo,那么在前端页面中不会显示出相应的Logo。相对应的语句请读者自己多读两遍,其判断逻辑是非常简单,一看就会的。下面我们只对一些稍微复杂的细节进行分析。

<?php if ($site_logo || $site_name || $site_slogan): ?>

这条语句和运算符有关。意思是:当后台设置了$site_logo或者$site_name或者$site_slogan的时候,执行如下语句。

 

接下来你会看到很多和区域有关的语句:

  <div id="content">

            <?php print render($page['content']); ?>

          </div>

        </div>

      </div>

    </div>

    <?php if ($page['sidebar_first']): ?>

      <div id="sidebar-first" class="sidebar"><?php print render($page['sidebar_first']); ?></div>

    <?php endif; ?>

    <?php if ($page['sidebar_second']): ?>

      <div id="sidebar-second" class="sidebar"><?php print render($page['sidebar_second']); ?></div>

    <?php endif; ?>

  </div>

在这段代码中你又可以看到很多IF语句。下面是其中的一部分列子:

<?php if ($page['sidebar_first']): ?>

      <div id="sidebar-first" class="sidebar"><?php print render($page['sidebar_first']); ?></div>

<?php endif; ?>

IF语句判断sidebar_first区域是否被分配了内容(也就是区块)。如果有内容,则向前端页面代码流中写入语句中间的<div>内容。

我的经验是,在讲解区域的时候最好是引用一个例子。所以,请打开你的psdtutorials.info文件。

你需要注意的是info文件中用来设置区域的代码。并在这段代码中插入一行如下加粗代码。

  regions[secondary_content]  = Secondary

  regions[tertiary_content]   = Tertiary

  regions[psd]             = Eine PSD-Region

  regions[footer]             = Footer

  regions[help]               = Help

  regions[page_top]           = Page top

  regions[page_bottom]        = Page bottom

保存你做的修改,并在page.tpl.php文件的相应位置插入如下加粗代码:

<?php if ($page['tertiary_content']): ?>

      <div id="tertiary-content">

        <?php print render($page['tertiary_content']); ?>

      </div>

    <?php endif; ?>

<?php if ($page['psd']): ?>

<div id="psd" class="psd_region">

<?php print render ($page['psd']); ?></div>

<?php endif; ?>

    <?php if ($page['footer'] || $feed_icons): ?>

      <div id="footer">

        <?php print render($page['footer']); ?>

        <?php print $feed_icons; ?>

      </div>

    <?php endif; ?>

保存后请清空你的缓存。

进入区块管理页面,你可以看到在区域的下拉选框中出现了一个新的区域:Eine PSD-Region。

这个新建的区域和其他原有的区域一样,都可以在其中放入区块。保存之后,就可以看到网页的变化了。

最后你可以在前台通过Firebug看到页面代码中出现了应有的段落,如下:

<div id="psd" class="psd_region">

  <div class="region region-psd">

  ...

  </div>

</div>

通过上述的方式你可以根据自己的需求定义主题中的区域。负责渲染区域的模板文件是region.tpl.php文件。首先你应该确认在你自己创建的主题中是否有这个文件。在Genesis主题中就没有这个文件。Drupal主题系统是直接使用了modules/system路径下的同名文件来进行区域的渲染。可以想象得到的是,在这个文件中,代码非常的少。

<?php if ($content): ?>

  <div class="<?php print $classes; ?>">

    <?php print $content; ?>

  </div>

<?php endif; ?>

这段代码中最重要的是变量$content,因为Drupal主题系统就是通过这个变量在前端页面上渲染每一个区域的。你可以查看region.tpl.php文件中的注释部分来查看有哪些变量是可以使用的,同时你可以在https://api.drupal.org/api/drupal/modules%21system%21region.tpl.php/7页面上找到同样的说明。比如如果访问者在网站上登录了,那么$logged_in变量将会返回true。

同样的,如果你想覆写region.tpl.php 这个模板文件,你依然需要将他拷贝到你自己的主题的templates文件夹中。

这样的话,你对这个文件进行的改动只有在这个主题下才会生效。

Drupal 版本: 

听晴空讲Drupal主题——第四章 德国人写的主题教程(6)

4.6 德国人写的主题教程(6)How to Make a Drupal Theme step by step  (6)
 
http://www.drupaltutorials.de/2013/07/05/drupal-themes-teil-7/
 
在这个系列的最后一节中,我将介绍另外的几个模板文件,它们也是你做主题的时候会经常遇到的。它们分别是node.tpl.php,field.tpl.php和block.tpl.php。最后还将介绍template.php,通过这个文件你可以定义主题函数。我将会通过一个例子来展示,如何在页面中添加一段可以检测当前IE浏览器版本,并根据条件判断结果来启用一个专门针对IE浏览器的样式表。

 
首先我们来看看node.tpl.php文件。这个文件就是用来渲染节点的。如前面说过的那样,如果你已经从Genesis主题中拷贝了templates文件夹到你的主题中,你就可以在你自己的主题的templates文件夹中找到node.tpl.php文件。

 
 
你可以在这个文件中根据自己的需求来改写代码。

<div id="node-<?php print $node->nid; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>

  <div class="node-inner clearfix">

    <?php print render($title_prefix); ?>

    <?php if ($teaser): ?>

      <h2 class="node-title"<?php print $title_attributes; ?>>

        <a href="<?php print $node_url; ?>" rel="bookmark"><?php print $title; ?></a>

      </h2>

    <?php endif; ?>

    <?php print render($title_suffix); ?>

    <?php print $user_picture; ?>

    <?php if ($display_submitted): ?>

      <div class="node-submitted">

        <?php print $submitted; ?>

      </div>

    <?php endif; ?>

    <div class="node-content"<?php print $content_attributes; ?>>

      <?php

        // Hide comments and links and render them later.

        hide($content['comments']);

        hide($content['links']);

        print render($content);

      ?>

    </div>

    <?php if ($content['links']): ?>

      <div class="node-links">

        <?php print render($content['links']); ?>

      </div>

    <?php endif; ?>

    <?php print render($content['comments']); ?>

  </div>

</div>
 
在node.tpl.php文件中有很多的PHP变量。比如,你可以用$user_picture变量来输出节点创建者的用户头像。在比如,你也可以非常轻易的用$name变量来输出节点创建者的名字。下面这样的语句是另一个有趣的函数(或者叫方法):
 
hide($content['comments']);
 
这个语句的作用是通过调用hide()方法来欺骗drupal_render(),让它以为括号内的东西已经被渲染过了。其实根本就没有执行渲染,也就是说并没有将$content['comments'] 转化为HTML代码。因此在渲染$content数组的时候就会直接忽略掉数组中的comments。(晴空注:这里之所以要将comments隐藏起来,是为了让它和内容出现在不同的Div中,这样就可以用不到的Css类名分别为他们设定样式。)
 
 
 
因此,当内容(除了Link和Comment)渲染完成后,又紧接着对刚才隐藏的元素进行了渲染:
 
<?php print render($content['comments']); ?>
 
这样做就可以对内容和评论以及链接分开进行渲染。
 
 
FIELD.TPL.PHP
 
负责渲染字段的模板文件是field.tpl.php,你可以在你拷贝到子主题中的templates文件夹中找到它。
 

 
代码如下:

<div class="<?php print $classes; ?>"<?php print $attributes; ?>>

  <?php if (!$label_hidden) : ?>

    <h3 class="field-label"<?php print $title_attributes; ?>><?php print $label ?>: </h3>

  <?php endif; ?>

  <?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>
 
关于这个文件的详细信息你可以在官网的https://api.drupal.org/api/drupal/modules%21field%21theme%21field.tpl.php/7 页面找到。
 

 
这个文件中同样有很多变量可以使用。比如你可以用$label输出字段的标签。如果后台设置了隐藏字段标签,你可以用$label_hidden来进行判断。
 
BLOCK.TPL.PHP
 
接下来是block.tpl.php文件,它是负责渲染区块的。你可以在你的子主题的templates文件夹中找到。关于这个文件夹中需要用到的变量请参见官网https://api.drupal.org/api/drupal/modules%21block%21block.tpl.php/7 页面
 

 
<div id="block-<?php print $block->module . '-' . $block->delta; ?>" class="<?php print $classes; ?>"<?php print $attributes; ?>>

  <div class="block-inner">

    <?php print render($title_prefix); ?>

      <?php if ($title): ?>

        <h2 class="block-title"<?php print $title_attributes; ?>><?php print $title; ?></h2>

      <?php endif;?>

    <?php print render($title_suffix); ?>

    <div class="content"<?php print $content_attributes; ?>>

      <?php print $content ?>

    </div>

  </div>

</div>
 
这里最重要的变量显然是$content。通过这个变量可以输出区块的内容。如果你需要输出的是生成这个区块的模块,那么你应该使用变量$block->module。
 
TEMPLATE.PHP
 
在整个教程的结束部分,我们来看看template.php文件。在这个文件中你可以声明和定义你需要在主题中使用的变量和方法。如果你打开的新建的子主题中的这个文件,你会看到很多被注释了的方法。

/**

 * Override or insert variables into all templates.

 */

/* -- Delete this line if you want to use these functions

function genesis_SUBTHEME_preprocess(&$vars, $hook) {

}

function genesis_SUBTHEME_process(&$vars, $hook) {

}

// */
 
要使用其中的某个方法的话,你必须先将如下的语句整行删除
 
/* -- Delete this line if you want to use these functions
 
同时你还需要修改方法名称。在Genesis子主题中,template.php文件中的方法名如下:
 
function genesis_SUBTHEME_process()
 
你必须将此处的genesis_SUBTHEME修改成你自己建立的主题名字,在我们这个例子中是这样的:
 
function psdtutorials_process()
 
我们使用一个例子来讲述如何使用这些方法。通过以下一系列的步骤,我们可以在页面中添加一段可以检测当前IE浏览器版本,并根据条件判断结果来启用一个专门针对IE浏览器的样式表,其代码如下:
/**

 * Override or insert variables into the html templates.

 */

/* -- Delete this line if you want to use these functions

function genesis_SUBTHEME_preprocess_html(&$vars) {

  // Uncomment the folowing line to add a conditional stylesheet for IE 7 or less.

  // drupal_add_css(path_to_theme() . '/css/ie/ie-lte-7.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 7', '!IE' => FALSE), 'preprocess' => FALSE));

}

function genesis_SUBTHEME_process_html(&$vars) {

}

// */
 
将上面的代码按照之前讲述的规则修改成如下所示:

function psdtutorials_preprocess_html(&$vars) {

  // Uncomment the folowing line to add a conditional stylesheet for IE 7 or less.

 drupal_add_css(path_to_theme() . '/css/ie/ie-lte-7.css', array('weight' => CSS_THEME, 'browsers' => array('IE' => 'lte IE 7', '!IE' => FALSE), 'preprocess' => FALSE));



}
 
最后清空缓存。
 

 
在前台页面的代码中就会出现如下所示的代码:

<!--[if lte IE 7]>

<link type="text/css" rel="stylesheet" href="http://localhost/drupal/sites/all/themes/psdtutorials/css/ie/ie-lte-7.css?md2qg4" media="all" />

<![endif]-->
 
这段代码的意思是,IE7及其以下版本中启用代码中的css文件。
标签: 
Drupal 版本: