主题继承使你可以轻松地扩展主题和减少维护工作。你可以使用现有的主题作为定制开发的基础,或者细微的店面设计更新,像节假日装饰。你可以添加重写和扩展文件,而不是复制原主题文件做修改。
主题继承的级别是不限定的。
主题继承是基于回退机制(保证如果一个视图文件没有在当前主题中被找到,系统就会在祖先主题,模型视图文件或者库中搜索)。 回退的顺序与静态文件(CSS,JavaScript,字体和图像),其它类型主题文件略有不同。本文描述每种主题文件的回退并提供如何重写祖先主题和模型设计的概念。
有关开发主题组件的全面信息,请参阅Magento2教程的后续章节。
设置一个父主题
一个父主题在子主题的theme.xml
声明文件中被指明。
例如:OrangeCo的Orange主题继承自Magento的Blank主题。继承被声明在app/design/frontend/OrangeCo/orange/theme.xml
,代码如下:
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
<title>Orange</title>
<parent>Magento/blank</parent>
<media>
<preview_image>media/preview.jpg</preview_image>
</media>
</theme>
父主题和子主题可以属于不同的供应商。例如,你自定义的主题可以继承Magento的Blank主题。
重写静态资产
静态资产,或静态视图文件,是样式,JavaScript,图像和字体。
要自定义父主题、模型视图或库文件里的视图文件,你可以通过添加一个相同名字的文件到相关位置来重写它们。特定的目录(系统在回退过程中搜索的地方)取决于模型内容是否对文件已知。下面是对两种情况的描述:
如果模型内容没有为文件做定义:
- 当前主题静态文件:
<theme_dir>/web/
- 祖先静态文件,递归,直到到达一个没有父类的主题:
<parent_theme_dir>/web/
- 库静态视图文件:
lib/web/
如果模型内容为文件做了定义:
- 当前主题模型静态文件:
<ttheme_dir>/<Namespace>_<Module>/web/
. 例如:app/design/frontend/OrangeCorp/orange/Magento_Catalog/web/
- 祖先静态文件,递归,直到到达一个没有父类的主题:
<parent_theme_dir>/<Namespace>_<Module>/web/
- 前端模型静态视图文件:
<module_dir>/view/frontend/web/
- base区域模型静态视图文件:
<module_dir>/view/base/web/
示例:
一家名为OrangeCo的公司有一个名为Orange的主题。主题文件位于:app/design/frontend/OrangeCo/orange
。Orange继承自Magento的Blank主题。
让我们想像一下,OrangeCo需要添加一些冬季假期装饰。所以它创建以一个继承自Orange的新主题orange_winter
,位于app/design/frontend/OrangeCo/orange_winter
。在Orange主题中底部背景图位于app/design/frontend/OrangeCo/orange/web/images/background.jpg
。
OrangeCo希望它被替换成一个节日的背景。于是一个有同样名字的新的背景图被放在app/design/frontend/OrangeCo/orange_winter/web/images/background.jpg
当Orange Winter主题被应用,新的节日图片就会重写Orange主题中的图片,那么前台效果就是这样:
重写模板
模板的回退计划如下(模型内容对它们来说是已知的):
- 当前主题模块:
<theme_dir>/<Namespace>_<Module>/templates
- 祖先主题模块,递归,直到到达一个没有父类的主题:
<parent_theme_dir>/<Namespace>_<Module>/templates
- 模型模板:
<module_dir>/view/frontend/templates
所以如果你需要自定义一个特定的模板,你需要创建一个同样名字的模板放在主题模型文件../templates/<path_to_template>
目录下。其中,<path_to_template>
是原始模板的路径。
例如:你想要重写<Magento_Catalog_module_dir>/view/frontend/templates/category/widget/link/link_block.phtml
,那么<path_to_template>
就是category/widget/link/
。
示例:在默认情况下,根据模型文件,迷你购物车中的产品是在Checkout按钮之下的:
顺序是在<Magento_Checkout_module_dir>/view/frontend/templates/cart/minicart.phtml
模型文件中被定义的。Blank主题没有重写这个模板。OrangeCo希望他们的产品展示在Go to Checkout按钮之前。他们需要在Orange主题文件夹内为对应的模型添加一个重写模板:app/design/frontend/OrangeCo/orange/Magento_Checkout/templates/cart/minicart.phtml
。注意,主题templates
目录中的模块路径与模型相对应。改变顺序之后,OrangeCo的购物车看起来是这样的:
你可以在之后的文章中找到详细的代码和其它任务。
扩展布局
布局进程机制不涉及回退。系统按下面的顺序收集主题文件:
- 当前主题布局:
<theme_dir>/<Vendor>_<Module>/layout/
- 祖先主题布局,递归,直到到达一个没有父类的主题:
<parent_theme_dir>/<Vendor>_<Module>/layout/
- 前端区域的模型主题:
<module_dir>/view/frontend/layout/
- Base区域的模型主题:
<module_dir>/view/base/layout/
与模板、图片不同,主题不仅能被重写还能被扩展。推荐的自定义布局是通过创建主题扩展布局文件来扩展它。 要添加一个扩展布局文件:把你自定义的布局文件放在:<theme_dir>/<Vendor>_<Module>/layout/
目录下。
例如:
OrangeCo决定移除<Magento_Theme_module_dir>/view/frontend/layout/default.xml
中定义的底部“Report bugs”链接。要实现它,他们添加了一个扩展主题文件在app/design/frontend/OrangeCo/orange/Magento_Theme/layout/default.xml
。
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<remove name="report.bugs"/>
</body>
</page>
更多关于主题扩展的知识将会在《扩展主题》中提到。
重写布局
虽然不推荐重写布局,但这也是特定自定义任务的一种解决方式。要重写祖先主题的布局文件:
- 创建同样名字的布局文件到
<theme_dir>/<Vendor>_<Module>/layout/override/theme/<Vendor>/<ancestor_theme>
目录下
要重写模型布局文件(base布局)
- 创建同样名字的布局文件到
<theme_dir>/<Vendor>_<Module>/layout/override/base