Как создать тему для Magento 2 с нуля

в 11:56, , рубрики: magento2, php, Разработка под e-commerce, разработка сайтов, метки:

Как создать тему для Magento 2 с нуля - 1

Здравствуйте, уважаемые хабрапользователи! В этой публикации хочу описать процесс создания темы для Magento 2 с нуля. Magento 2 имеет достаточно большое количество нововведений и улучшений по сравнению с первой версией. По большей части они относятся к клиентской части.

Вот некоторые из них:

  1. Полная поддержка HTML5 и CSS3;
  2. Встроенный препроцессор LESS;
  3. Асинхронная загрузка модулей с помощью RequireJS (без ручного добавления скриптов в cекцию head);
  4. jQuery/jQuery UI вместо библиотеки Prototype;
  5. Magento UI библиотека (набор компонентов для простого и гибкого рендеринга пользовательского интерфейса).

Самое интересное – под катом!

Касательно разработки тем, в Magento 2 была введена новая модульная структура кода. Теперь все статические сss, js, а также файлы изображений размещаются в папке web темы, а папка skin была удалена с корневого каталога Magento. Кроме этого, была введена папка view в модулях, которая хранит шаблоны и файлы, которые относятся к уровню представления MVC конкретно для каждого модуля.

Следует создать новую тему и более детально рассмотреть структуру директорий и файлов. Поехали!

Создание директории темы

Темы в Magento 2 находятся в каталоге (M2_root)/app/design/frontend. Сначала необходимо создать папку Vendor (называлась Package в Magento 1) и уже в ней создать папку для темы.

Например: (M2_root)/app/design/frontend/Singree/walkbeyond. Где Singree – vendor, а walkbeyond – код темы. В коде можно использовать любые комбинации из букв и цифр.

После создания этих директорий тему необходимо объявить, чтобы ее можно было сделать активной в административной части.

Объявление и регистрация

Чтобы Magento 2 смогла увидеть созданную тему, необходимо создать файл: (M2_root)/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 указывается тема, которая устанавливается как родительская (все ненайденные статические файлы/файлы шаблонов будут браться с родительской темы). В примере указывается blank, которая поставляется вместе с M2. Она является базовой и своей родительской не имеет. Тем не менее, уровней наследования в Magento 2 может быть сколько угодно, и здесь нет никаких ограничений в отличие от первой версии.

Как создать тему для Magento 2 с нуля - 2

В теге preview_image указывается миниатюра для представления темы в администраторской части.

Для регистрации темы в системе необходимо создать файл registration.php в корне:

<?php
MagentoFrameworkComponentComponentRegistrar::register(
    MagentoFrameworkComponentComponentRegistrar::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 (имя по умолчанию) для переопределения логотипа темы. В папке сss/source, согласно родительской теме blank, можно создать _theme.less файл c переопределением базовых переменных Magento UI. В папке (magento-root)/lib/web/css/source/lib/variables/ в исходных файлах можно найти значения по умолчанию для тех переменных, которые можно переопределить. В сss/source можно задавать стили для модулей в файле _module.less и для виджетов в файле _widgets.less. Для небольших правок можно создавать файл _extend.less.

Конфигурация изображений

Обязательным для темы является файл etc/view.xml (если он не определен в родительской теме), который содержит значения свойств для изображений товаров, таких как высота, ширина, прозрачность, цвет фона и т.п. Этот файл необходимо полностью скопировать с базовой темы (значения не наследуются) Свойства изображений задаются по атрибутам идентификатора и типа в рамках элемента:

<images module="Magento_Catalog">
...
<images/>

Для примера можно изменить размер изображения в табличном представлении товаров каталога.

Как создать тему для Magento 2 с нуля - 3

Файл etc/view.xml:

<?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 – уникальный в рамках темы. Тип small_image соответствует Small Image Role в администраторской части. Допустимые значения типов изображений: image, small_image, swatch_image, swatch_thumb и thumbnail.

Как создать тему для Magento 2 с нуля - 4

После сохранения товара, все изображения являются закешированными. После изменения размеров можно выполнить команду php (M2_root)/bin/magento catalog:images:resize для регенерации картинок.

Итак, в результате была получена такую структуру:

Как создать тему для Magento 2 с нуля - 5

Применение темы в административной части

Тему можно активировать в настройках магазина после создания в файловой системе. Для этого переходим в раздел Content — Design — Themes и проверяем, что созданная тема присутствует в списке:

Как создать тему для Magento 2 с нуля - 6

Если мы видим созданную тему в списке, переходим в Content → Design → Configuration и там нажимаем edit для определенного вебсайта или выбранного магазина:

Как создать тему для Magento 2 с нуля - 7

Выбираем тему (Applied Theme) и нажимаем Save configuration:

Как создать тему для Magento 2 с нуля - 8

Если у вас включен кеш, необходимо очистить его после применения темы. Для этого перейдем в раздел System — Cache Management и обновляем все невалидные типы кеша:

Как создать тему для Magento 2 с нуля - 9

В результате, мы получим все ту же тему magento/blank, но с другим логотипом и размером картинок:

Как создать тему для Magento 2 с нуля - 10

Использование LESS для изменения стилей

После создания темы можно приступить к изменению внешнего вида страниц. Чтобы отредактировать стили проекта, необходимо использовать один из нескольких типов препроцессинга LESS в Magento 2:

  • Серверная компиляция LESS;
  • Клиентская компиляция LESS c помощью less.js.

Клиентская компиляция чаще используется в режиме разработки, так как все изменения будут видны сразу: браузер будет выполнять компиляцию каждый раз при обращении к файлам стилей. При серверной компиляции необходимо вручную каждый раз удалять содержимое папок pub/static и var/view_preprocessed. Эти действия можно оптимизировать с помощью таскраннера Grunt. Он будет отслеживать изменения в файлах, очищать указанные папки и компилировать less автоматически.

Изменить тип компиляции можно в админ части по пути: Stores → Configuration → Advanced → Developer → Front-end development workflow → Workflow:

Как создать тему для Magento 2 с нуля - 11

В нашем простом примере будет использоваться серверная компиляция, которая установлена по умолчанию. Установим цвет фона сайта, а также шрифт в созданном _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 с нуля - 12

Magento 2: использование макетов в теме

Как создать тему для Magento 2 с нуля - 13

В Magento 2 в определенной теме можно как расширять, так и переопределять макеты. Чтобы полностью не копировать страничные или общие макеты с базовой темы, необходимо указать только макет расширения в папке темы по таким путям:

<theme_dir>
 |__/<Namespace>_<Module>
   |__/layout
     |--<layout1>.xml
     |--<layout2>.xml

Например, чтобы расширить макет catalog_category_view модуля Catalog, который находится по пути (сatalog_module_dir)/view/frontend/layout/catalog_category_view.xml, необходимо создать файл по пути: (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 атрибутов блоков/контейнеров (некоторые атрибуты, такие как htmlClass, htmlId, label могут быть изменены в расширяющих макетах);
  • Удаление аргументов блоков;
  • Удаление всех дескрипторов путем переопределения макетного файла с пустым дескриптором;
  • Модифицирование включения дескрипторов.

Можно переопределить основные базовые макеты путем создания папки 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/<layout2>.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 может находиться в каждом модуле или глобально в папке app. Словари с папками темы имеют более высокий приоритет в поиске переведенной строки.

Чтобы сгенерировать файл с переводами в папке темы можно использовать i18n tool.

Можно запустить такую команду в корневом каталоге 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. Его можно открыть любым редактором таблиц и изменить перевод любых строк в правой колонке. Переведённые строки, вместо основных, можно будет увидеть после применения темы.

Удаление темы

Если тема является Composer пакетом, ее можно удалить командой (с корневого каталога):


php bin/magento theme:uninstall [-c|--clear-static-content] {theme path} ... {theme path}

{theme path} – относительный путь к теме, начиная с имя area (frontend). В нашем случае: frontend/Singree/walkbeyond.

--clear-static-content – удаляет статические файлы (для которых не нужна автоматическая генерация: css, js, images).

В случае, если тема не является Сomposer пакетом, для ее удаления необходимо выполнить такие шаги:

  • Удалить папку темы app/design/frontend/(Vendor);
  • Удалить содержимое var/view_preprocessed;
  • Удалить содержимое of pub/static/frontend/;
  • Открыть базу данных мадженто 2, найти theme таблицу и удалить строку с названием темы;
  • Удалить кеш командой php bin/magento cache:flush.

Вывод

В статье были рассмотрены основные составляющие части темы: как создать с нуля структуру директорий и файлов темы, картинку предпросмотра. Также был рассмотрен процесс переопределения стилей, макетов и шаблонов темы: был переведен сайт с помощью словарей перевода. Далее следует рассмотреть таблицу составляющих темы:

Как создать тему для Magento 2 с нуля - 14

Большая часть данной структуры была затронута в нашей статье. Также стоило бы упомянуть о правилах работы с клиентскими библиотеками Javascript (например, require.js) или детальнее описать работу с блоками и контейнерами макетов, но тогда размер статьи слишком увеличился бы и читать ее стало бы совершенно неудобно.

Благодарю всех за внимание!

Автор: greebn9k

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js