如何从零开始创建一个Magento 2主题





5.00/5 (2投票s)
学习如何使用 Magento 2 为您的电子商务网站创建一个新主题。
在这篇文章中,我想分享一些关于使用 Magento 2 创建全新主题的知识和专业技能。与 Magento 的第一个版本相比,这个 CMS 有很多优点。其中大部分与客户端有关。以下是其中一些优点:
- 全面支持 HTML5 和 CSS3;
- 内置 LESS 预处理器;
- 使用 RequireJS 进行异步模块上传(无需手动将代码添加到 head 中);
- 使用 jQuery/jQuery UI 代替 Prototype 库;
- 使用 MagentoUI 库(它包含简单灵活地渲染用户界面所需的所有组件)。
至于新主题的开发,Magento 2 为其脚本和代码提供了新的模块结构。现在,所有静态的 css、js 和图像文件都存储在特殊的 web 主题文件夹中。Skin 文件夹已从 Magento 的根目录中删除。引入了 View 文件夹以存储为特定模块提供 MVC 访问的布局和文件。
因此,让我们尝试使用 Magento 2 创建一个全新主题,更详细地了解目录和文件的结构。
主题目录的创建
Magento 2 主题存储在 <M2 根目录>/app/design/frontend 目录中。首先,您应该创建 Vendor 文件夹(在 Magento 1 中是这样称呼的),然后在其内部为您的主题创建一个新文件夹。
例如:<M2 根目录>/app/design/frontend/Singree/walkbeyond。其中 Singree 是供应商,walkbeyond 是主题代码。您可以在代码部分使用字母和数字的任意组合。
创建上述目录后,您需要声明主题以在后端激活它。
声明和注册
为了让 Magento 2 “看到”新创建的主题,您应该创建以下文件:<Magento 2 根目录>/app/design/frontend/<vendor>/<theme codename>/theme.xml,其中包含以下代码:
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd"> <title>walkbeyond</title> <parent>Magento/blank</parent> <media> <preview_image>media/walkbeyond.jpg</preview_image> </media> </theme>
在 <title>
标签中包含主题名称;在 <parent>
中包含父主题。(所有未找到的静态文件和布局文件都将从父主题中获取。)在此示例中,您可以看到 Magento 2 随附的 blank 主题,它充当基本主题。它没有父主题。然而,Magento 2 中的继承级别数量不受限制;没有限制,这使得它比 Magento 1 更有用。
在 <preview_image>
标签中,您可以选择并设置主题的预览图像。它将显示在管理部分。要在系统中注册主题,您需要在根目录中创建 registration.php 文件。如下所示:
<?php
\Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::THEME,
'frontend/Singree/walkbeyond',
__DIR__
);
这不是必需的,但您也可以创建 composer.json 文件以将主题作为 composer 包共享。这是一个示例:
{
"name": "Singree/walkbeyond",
"description": "N/A",
"require": {
"php": "~5.5.0|~5.6.0|~7.0.0",
"Singree/walkbeyond”: "100.0.*",
"magento/framework": "100.0.*"
},
"type": "magento2-theme",
"version": "100.0.1",
"license": [
"OSL-3.0",
"AFL-3.0"
],
"autoload": {
"files": [
"registration.php"
]
}
}
静态文件目录的创建
为了存储样式、JavaScript 代码、图像和字体,您应该在主题的根目录中创建 web 文件夹。它需要具有以下结构:
app/design/frontend/Singree/walkbeyond/ ├── web/ │ ├── css/ │ │ ├── source/ │ ├── fonts/ │ ├── images/ │ ├── js/
所有这些文件夹都不是必须拥有的。在 images 文件夹中存储所有静态文件。您还可以添加 logo.svg(默认名称)到该文件夹中以重新声明主题的标志。
根据空白父主题的特性,您可以在 css/source 文件夹中创建 _theme.less 文件,并重新声明 MagentoUI 的基本变量。然后,在 <magento-root>/lib/web/css/source/lib/variables/ 文件夹中,在原始文件中进行一些搜索。您需要找到要重新声明的变量的默认值。在 css/source 文件夹中,您可以在 _module.less 文件中为您的模块设置和声明样式,并在 _widgets.less 文件中为小部件设置和声明样式。创建 _extend.less 文件用于小范围定制。
图像配置
您的主题必须包含 etc/view.xml 文件(如果未在父主题中声明),该文件存储产品图像所有必要的值,例如宽度、高度、背景颜色、不透明度等。您可以使用元素内的 ID 属性和类型来设置值。以下是操作方法:
<images module="Magento_Catalog">
...
<images/>
例如,利用上述过程,您可以轻松更改目录表格视图中的图像大小(如下所示)。
<?xml version="1.0"?>
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/view.xsd">
<media>
<images module="Magento_Catalog">
<image id="category_page_grid" type="small_image">
<width>200</width>
<height>200</height>
</image>
</media>
</view>
Category_page_grid
ID 在主题中是唯一的。Small_image
类型对应于管理端的“小图像角色”。以下是一些可用于图像类型的值:image
、small_image
、swatch_image
、swatch_thumb
和 thumbnail
。
保存产品时,所有图像都会被缓存。更改图像大小后,您可以执行命令 php <magento install dir>/bin/magento catalog:images:resize
来生成图像。结果,我们将得到以下结构:
管理端的主题激活
主题在文件系统中创建后,您可以在设置中激活它。为此,只需遵循“内容 > 设计 > 主题”的路径,并检查主题是否在列表中。
然后,访问“内容 > 设计 > 配置”,并为选定的网站或电子商务平台按编辑。选择我们的主题(已应用主题)并按“保存配置”。
如果您的缓存已开启,请在应用主题时刷新它。为此,请转到“系统 > 缓存管理”并更新所有无效的缓存类型。
结果,我们将得到经过验证的 magento/blank 主题,其中包含不同的标志和调整大小的图像。
使用 LESS 进行样式编辑
创建主题本身后,您可以对样式进行一些修改,以视觉上更改网站页面。要编辑项目的样式,您可以使用 Magento 2 中的两种 LESS 预处理类型之一:
- LESS 的服务器端编译;
- 使用 less.js 进行 LESS 的客户端编译。
客户端编译通常用于开发模式,因为所有更改和编辑都可以立即可视化:每当您引用样式文件时,浏览器都会开始编译文件。同时,当服务器端编译到位时,您需要手动删除 pub/static 和 var/view_preprocessed 文件夹的内容。不过,您可以使用 Grunt 任务运行器优化此过程。它可以跟踪文件中的每个操作,“清理”选定的文件夹并自动编译 less。
要更改编译类型,请访问管理面板:“商店 > 配置 > 高级 > 开发者 > 前端开发工作流 > 工作流”。
我们的示例非常简单,因此我们将使用服务器端编译(默认设置)。
让我们在 _theme.less 文件中为我们的网站应用背景颜色和字体:
@page__background-color: #484848;
@text__color: #fff;
@font-family__base: 'Arial', sans-serif;
删除 /pub/static/frontend/Singree/walkbeyond/en_US 和 var/view_preprocessed 目录中的内容后,您可以看到网站的视觉部分发生了变化。
使用 Magento 2 进行主题布局
Magento 2 使您能够扩展和覆盖特定主题的布局。您不需要从父主题复制与页面相关或通用的布局。您只需在主题文件夹中引用选定的布局,如下所示:
<theme_dir> |__/<Namespace>_<Module> |__/layout |--<layout1>.xml |--<layout2>.xml
例如,要扩展存储在 <сatalog_module_dir>/view/frontend/layout/catalog_category_view.xml 中的 Catalog 模块的布局 catalog_category_view,您应该创建以下路由文件:
<theme_dir>/Magento_Catalog/layout/catalog_category_view.xml.
要从布局中删除任何块(例如类别描述),您可以:
<?xml version="1.0"?>
<page xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceBlock name="category.description" remove="true"/>
</body>
</page>
然而,布局扩展不能用于所有定制任务。如果您需要定制很多东西,最好是覆盖布局。也就是说,创建和使用新文件比使用父主题(您的主要布局)中的文件更容易。以下是一些您最好覆盖布局的定制示例:
- 请求一个“主导”父布局中另一个方法的方法;
- 更改方法的参数数量;
- 使用 remove 属性取消块/容器的删除命令;
- 为块/容器安装 XML 属性;
- 删除块的参数;
- 通过使用“空白”布局句柄覆盖布局文件来删除布局句柄;
- 修改布局句柄的激活。
您可以通过在模块的主题文件夹中创建 override/base 文件夹来覆盖基本布局,如下所示:
<theme_dir> |__/<Namespace_Module> |__/layout |__/override |__/base |--<layout1>.xml |--<layout2>.xml
这些文件能够覆盖布局:
- <module_dir>/view/frontend/layout/<layout1>.xml
- <module_dir>/view/frontend/layout/<layout2>.xml
此外,您可以通过在模块的主题文件夹中创建 override/theme 文件夹来覆盖父主题的布局:
<theme_dir> |__/<Namespace_Module> |__/layout |__/override |__/theme |__/<Parent_Vendor> |__/<parent_theme> |--<layout1>.xml |--<layout2>.xml
这些文件能够覆盖通过以下路径存储的布局:
- <parent_theme_dir>/<Namespace>_<Module>/layout/<layout1>.xml
- <parent_theme_dir>/<Namespace>_<Module>/layout/<layout1>.xml
主题模板
Magento 2 主题不仅可以覆盖布局模块,还可以覆盖模板。要覆盖模块模板 <module_dir>/view/frontend/templates/<path_to_templates>,请在主题的模块文件夹中创建一个新文件夹 templates:<theme_dir>/<Namespace>_<Module>/templates/<path_to_templates>
让我们尝试为购物车文件 Singree/walkbeyond/Magento_Checkout/templates/cart/minicart.html 添加一条文本消息。消息应该包含购物车中的产品数量。如下所示:
<div data-block="minicart" class="minicart-wrapper">
<a class="action showcart" href="<?php /* @escapeNotVerified */ echo $block->getShoppingCartUrl(); ?>"
data-bind="scope: 'minicart_content'">
<span class="cart-title hidden-xs"><?php /* @escapeNotVerified */ echo __('Shopping cart'); ?></span>
<span class="counter total-qty empty"
data-bind="css: { empty: cart().summary_count == 0 }, blockLoader: isLoading">
<?php /* @escapeNotVerified */ echo __('Products count:'); ?> <span class="counter-number"><!-- ko text: cart().summary_count --><!-- /ko --></span>
<span class="counter-label">
<!-- ko if: cart().summary_count -->
<!-- ko text: cart().summary_count --><!-- /ko -->
<!-- ko i18n: 'items' --><!-- /ko -->
<!-- /ko -->
</span>
</span>
</a>
<?php if ($block->getIsNeedToDisplaySideBar()): ?>
<div class="block block-minicart empty"
data-role="dropdownDialog"
data-mage-init='{"dropdownDialog":{
"appendTo":"[data-block=minicart]", "triggerTarget":".showcart",
"timeout": "2000", "closeOnMouseLeave": false,
"closeOnEscape": true, "triggerClass":"active",
"parentClass":"active", "buttons":[]}}'>
<div id="minicart-content-wrapper" data-bind="scope: 'minicart_content'">
<!-- ko template: getTemplate() --><!-- /ko -->
</div>
</div>
<?php endif ?>
<script>
window.checkout = <?php /* @escapeNotVerified */ echo \Zend_Json::encode($block->getConfig()); ?>;
</script>
<script type="text/x-magento-init">
{
"[data-block='minicart']": {
"Magento_Ui/js/core/app": <?php /* @escapeNotVerified */ echo $block->getJsLayout();?>
},
"*": {
"Magento_Ui/js/block-loader": "<?php /* @escapeNotVerified */ echo $block->getViewFileUrl('images/loader-1.gif'); ?>"
}
}
</script>
</div>
主题本地化
主题本地化是利用词汇表数组完成的。您可以在此处搜索词汇表:
- <parent_theme_dir>/i18n/ (查看所有父主题)
- <current_theme_dir>/i18n/
I18n 文件夹可以存储在每个模块中,也可以全局存储在应用程序文件夹中。带有主题文件夹的词汇表在搜索翻译栏时具有高优先级。
要在主题文件夹中生成翻译文件,您可以使用 i18n 工具。您还可以在 Magento 2 的根目录中执行以下命令:
php bin/magento i18n:collect-phrases --output="app/design/frontend/Singree/walkbeyond/i18n/en_US.csv" app/design/frontend/Singree/walkbeyond
这些命令会将所有字符串收集到一个词汇表中。文件如下:
app/design/frontend/OrangeCo/orange/i18n/en_US.csv
您可以使用任何表格编辑器(例如 Excel)打开它,并更改右栏中每个短语的翻译值。应用主题后,您将能够看到翻译后的字符串。
主题删除
如果您的主题是 Composer 包,您可以使用以下命令从根目录中删除它:
php bin/magento theme:uninstall [-c|--clear-static-content] {theme path} ... {theme path}
{theme path} 是您主题的大致路径。在我们的例子中是 frontend/Singree/walkbeyond。
--clear-static-content 删除不需要自动生成的静态文件:css、js、图像。
如果您的主题不是 Composer 包,您将需要执行以下操作来删除它:
- 删除主题文件夹 app/design/frontend/<Vendor>/;
- 删除 var/view_preprocessed/ 的内容;
- 删除 pub/static/frontend/ 的内容;
- 打开 Magento 2 数据库并找到主题表以删除包含主题名称的字符串;
- 使用 php bin/magento cache:flush 命令刷新和删除缓存。
总结
在这篇文章中,我讨论了使用 Magento 2 创建主题的主要组件。我描述了如何创建目录和文件(主题、图像、预览)的结构。此外,我还提到了如何覆盖给定主题的样式、模板和布局的过程。我展示了如何使用在线词汇表翻译网站。
以下是创建主题所需的文件夹列表:
- /<Vendor>_<Module> (非必需;存储给定模块的样式、模板和布局)
- /<Vendor>_<Module>/web/css/source (非必需;存储特定模块:.ccs 和 .less 文件)
- /<Vendor>_<Module>/layout (非必需;存储主要的扩展包或父主题布局)
- /<Vendor>_<Module>/layout/override/base (非必需;存储主主题的覆盖布局)
- /<Vendor>_<Module>/layout/override/<parent_theme> (非必需;存储父主题的覆盖布局)
- /<Vendor>_<Module>/templates (非必需;存储覆盖主模块模板或父模板的模板)
- /etc/view.xml (如果主题未声明则必需;存储图像配置数据)
- /i18n (非必需;存储用于翻译的 .csv 词汇表)
- /media (非必需;存储预览)
- /web (非必需;可从前端上传的静态文件)
- /web/css/source (非必需;存储 Magento UI 库的全局元素和 _theme.less 文件,该文件默认覆盖变量的值)
- /web/fonts (非必需;存储主题的字体)
- /web/images (非必需;存储主题的图像)
- /web/js (非必需;存储 javascript 文件)
- /composer.json (非必需;描述主题的变量和元数据)
- /registration.php (必需;用于主题注册)
- /theme.xml (非必需;存储主题的基本数据和元数据;如果主题声明为系统组件则使用它)
我已经在上面的文章中描述了大部分结构。此外,提一下使用 javascript 客户端库(如 require.js)的一些规则或描述如何操作块和容器也是有意义的,但这会使文章过于庞大。我希望我上面提供的信息足够了。
感谢您的时间!