创建子主题
子主题跟其他主题类似,只有一点区别:他们继承了父主题的资源。子主题和父主题的层次是没有限制的。一个子主题可能是另外一个子主题的父主题,也可能存在分支的关系,这种随意性给了子主题很大的操作空间。
想象一下,从线框图做一个父主题,然后在子主题中应用和实现所有的细节。然后利用同样的线框图,出一份不同的分支的子主题。在一个多站点Drupal上,需要一份具有一致性的主题?利用子主题,很多设计资源都可以进行分享。每站点的变化都可以应用到一个子主题中,共享资源的变化则可以应用到所有的子主题中。在合理的规划之下,子主题具有无穷的可能。
##创建一个子主题
一个子主题必须有一个跟父主题不同的内部名称。这个名字不能包含任何空格和特殊字符。子主题的名字必须以字母开始,并只能包含小写字母、数字和下划线。我们假设我们的子主题命名为”my_subtheme”。
###目录:my_subtheme
子主题应该保存在自己的目录中。这个目录应该和名称一致。
子主题的文件夹应该放在sites/example.com/themes/(”example.com”代表你的站点名称),如果要在多个站点使用这个子主题,可以放在sites/all/themes/里面。
###my_subtheme.info文件
要声明一个主题是另外一个主题的子主题,必须在my_subtheme文件夹里面放置一个my_subtheme.info文件。最简单的办法是把父主题的info文件拷贝过来,把名字改成my_subtheme.info。然后在my_subtheme.info中添加”base theme”来声明这个子主题的父主题或者说父主题;把”theme_name”改成父主题的机读名称。
base theme = theme_name
修改name = 这行的内容,来起个供人阅读的名称也是个好主意。还可以修改description的值来对子主题做一个描述:
name = My sub-theme
description = This is a sub-theme of theme Bartik, made by John for the web site example.com (red, responsive).
core = 7.x
base theme = bartik
子主题从父主题继承了大部分的属性。最大的例外是区域、核心版本和颜色。你可能想要从父主题赋值区域以及核心一节的内容。如果你的父主题支持Color模块,并且你希望你的子主题也支持他,你可能还要把color目录拷贝过来,并且把父主题的info文件中相应的内容拷贝到子主题的info文件中:
stylesheets[all][] = css/colors.css
然后把colors.css从你的父主题赋值到子主题的css目录中。
##继承样式表
只要在子主题info文件中声明最少一个样式表,所有父主题中定义的样式表都会被继承。
覆盖继承的样式表:给子主题中的一个样式表指定同样的文件名。例如要覆盖父主题继承来的style.css,只要在子主题的info文件里加入以下内容:
stylesheets[all][] = style.css
如果你只是想禁用引入的样式,只要创建一个同名空文件就可以了。
###继承JavaScript
所有父主题中的JavaScript都会被继承。
覆盖继承的JavaScript:在子主题的info文件里指定一个同名的文件。例如要覆盖父主题中的script.js,在info文件中加入这一行:
scripts[] = script.js
如果只是想要禁用引入的脚本,只要创建一个同名空文件。(原作应该就是copy过来的——译者注)
###Template.php函数的继承
父主题中template.php定义的任何内容都会被继承,其中包括主题函数覆盖、预处理函数以及其他的任何东西。每个子主题也应该有自己的template.php,可以在这里添加自己的函数,或覆盖继承来的函数。
template.php中包含两种主要类型:主题函数覆盖,以及预处理函数。模板系统用截然不同的方式来处理这两种函数。
主题函数通过调用theme('[hook]', $var, ....)
的方式进行。当子主题覆盖了一个主题函数后,其他版本的这一函数就不会再执行了。
而预处理函数会在处理tpl文件之前执行。例如,[theme]_preprocess_page
会在page.tpl.php渲染之前执行。而且,父主题的预处理函数会先于子主题的预处理函数被调用。
综上所述,覆盖父主题的主题函数是可行的;而覆盖的方式无法阻止父主题预处理函数的执行,但可以通过hook_theme_registry_alter()
来移除一个父主题的预处理函数。
###页面、节点、Block以及其他模板文件的继承
Drupal提供了大量的文件,子主题可以用这些文件来继承属性。通过指定某种文件名或者结构,能够达到继承或覆盖模板的目的,这一技巧称为模板预测。
Drupal 7 中会继承父主题中所有.tpl.php文件。可以添加更加明确指向的模板,例如用node--blog.tpl.php
在node.tpl.php的基础上工作。
单独的连字符还是用于普通的分隔单词的目的,例如user-picture.tpl.php
或者node--long-content-type-name.tpl.php
,而一对连字符则代表对符号之前的类型的某一子类型的指示。
Drupal 6 同7类似,也同样会继承父主题中的模板,但是如果想要进行更具针对性的渲染,必须首先把父主题中的这一模板(例如Node.tpl.php)拷贝到本主题之中。例如,要在子主题中添加一个node-blog.tpl.php
,必须先把node.tpl.php从父主题中拷贝出来。这其实是个Bug,在Drupal 7中已经修复,在Drupal 6中则不会进行修复了。
覆盖继承的模板:在子主题中添加一个和父主题名字相同的模板,会覆盖掉父主题的同名模板。
###截屏,Logo以及favicon的继承
父主题的截屏会被继承,而Logo和favicon则不会被继承。
覆盖继承来的截屏:用info文件指定一个新的。
###区域的继承
子主题并不会继承父主题的区域定义。如果希望复用父主题的区域,需要从父主题的info文件中复制区域定义信息到自己的info文件重。如果你在使用非缺省的features,也应该将features的声明从父主题的info文件中拷贝出来。
###颜色的继承
color目录中对Color.module的支持不会被继承。
###配置的继承
theme-settings.php中的主题设置不会被继承,除非把设置声明从父主题info文件里拷贝到子主题info中。