65.9K
CodeProject 正在变化。 阅读更多。
Home

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

starIconstarIconstarIconstarIconstarIcon

5.00/5 (2投票s)

2016年10月4日

CPOL

10分钟阅读

viewsIcon

19234

学习如何使用 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 类型对应于管理端的“小图像角色”。以下是一些可用于图像类型的值:imagesmall_imageswatch_imageswatch_thumbthumbnail

保存产品时,所有图像都会被缓存。更改图像大小后,您可以执行命令 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_USvar/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>

然而,布局扩展不能用于所有定制任务。如果您需要定制很多东西,最好是覆盖布局。也就是说,创建和使用新文件比使用父主题(您的主要布局)中的文件更容易。以下是一些您最好覆盖布局的定制示例:

  1. 请求一个“主导”父布局中另一个方法的方法;
  2. 更改方法的参数数量;
  3. 使用 remove 属性取消块/容器的删除命令;
  4. 为块/容器安装 XML 属性;
  5. 删除块的参数;
  6. 通过使用“空白”布局句柄覆盖布局文件来删除布局句柄;
  7. 修改布局句柄的激活。

您可以通过在模块的主题文件夹中创建 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 创建主题的主要组件。我描述了如何创建目录和文件(主题、图像、预览)的结构。此外,我还提到了如何覆盖给定主题的样式、模板和布局的过程。我展示了如何使用在线词汇表翻译网站。

以下是创建主题所需的文件夹列表:

  1. /<Vendor>_<Module> (非必需;存储给定模块的样式、模板和布局)
  2. /<Vendor>_<Module>/web/css/source (非必需;存储特定模块:.ccs 和 .less 文件)
  3. /<Vendor>_<Module>/layout (非必需;存储主要的扩展包或父主题布局)
  4. /<Vendor>_<Module>/layout/override/base (非必需;存储主主题的覆盖布局)
  5. /<Vendor>_<Module>/layout/override/<parent_theme> (非必需;存储父主题的覆盖布局)
  6. /<Vendor>_<Module>/templates (非必需;存储覆盖主模块模板或父模板的模板)
  7. /etc/view.xml (如果主题未声明则必需;存储图像配置数据)
  8. /i18n (非必需;存储用于翻译的 .csv 词汇表)
  9. /media (非必需;存储预览)
  10. /web (非必需;可从前端上传的静态文件)
  11. /web/css/source (非必需;存储 Magento UI 库的全局元素和 _theme.less 文件,该文件默认覆盖变量的值)
  12. /web/fonts (非必需;存储主题的字体)
  13. /web/images (非必需;存储主题的图像)
  14. /web/js (非必需;存储 javascript 文件)
  15. /composer.json (非必需;描述主题的变量和元数据)
  16. /registration.php (必需;用于主题注册)
  17. /theme.xml (非必需;存储主题的基本数据和元数据;如果主题声明为系统组件则使用它)

我已经在上面的文章中描述了大部分结构。此外,提一下使用 javascript 客户端库(如 require.js)的一些规则或描述如何操作块和容器也是有意义的,但这会使文章过于庞大。我希望我上面提供的信息足够了。

感谢您的时间!

© . All rights reserved.