Здравствуйте, уважаемые хабрапользователи! В этой публикации хочу описать процесс создания темы для Magento 2 с нуля. Magento 2 имеет достаточно большое количество нововведений и улучшений по сравнению с первой версией. По большей части они относятся к клиентской части.
Вот некоторые из них:
- Полная поддержка HTML5 и CSS3;
- Встроенный препроцессор LESS;
- Асинхронная загрузка модулей с помощью RequireJS (без ручного добавления скриптов в cекцию head);
- jQuery/jQuery UI вместо библиотеки Prototype;
- 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 может быть сколько угодно, и здесь нет никаких ограничений в отличие от первой версии.
В теге 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/>
Для примера можно изменить размер изображения в табличном представлении товаров каталога.
Файл 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.
После сохранения товара, все изображения являются закешированными. После изменения размеров можно выполнить команду php (M2_root)/bin/magento catalog:images:resize для регенерации картинок.
Итак, в результате была получена такую структуру:
Применение темы в административной части
Тему можно активировать в настройках магазина после создания в файловой системе. Для этого переходим в раздел Content — Design — Themes и проверяем, что созданная тема присутствует в списке:
Если мы видим созданную тему в списке, переходим в Content → Design → Configuration и там нажимаем edit для определенного вебсайта или выбранного магазина:
Выбираем тему (Applied Theme) и нажимаем Save configuration:
Если у вас включен кеш, необходимо очистить его после применения темы. Для этого перейдем в раздел System — Cache Management и обновляем все невалидные типы кеша:
В результате, мы получим все ту же тему magento/blank, но с другим логотипом и размером картинок:
Использование 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:
В нашем простом примере будет использоваться серверная компиляция, которая установлена по умолчанию. Установим цвет фона сайта, а также шрифт в созданном _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
Например, чтобы расширить макет 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.
Вывод
В статье были рассмотрены основные составляющие части темы: как создать с нуля структуру директорий и файлов темы, картинку предпросмотра. Также был рассмотрен процесс переопределения стилей, макетов и шаблонов темы: был переведен сайт с помощью словарей перевода. Далее следует рассмотреть таблицу составляющих темы:
Большая часть данной структуры была затронута в нашей статье. Также стоило бы упомянуть о правилах работы с клиентскими библиотеками Javascript (например, require.js) или детальнее описать работу с блоками и контейнерами макетов, но тогда размер статьи слишком увеличился бы и читать ее стало бы совершенно неудобно.
Благодарю всех за внимание!
Автор: greebn9k