Досить часто при роботі з Magento 2 з’являється необхідність у власному (кастомному) віджеті. По дефолту система має досить широкий набір віджетів з простим функціоналом. Однак, коли вам потрібно змінити функціональність віджета або збільшити вибір параметрів налаштування, для цього вам доведеться створити свій власний.
У сьогоднішній статті ми розглянемо на практиці, як створити віджет, який розширює функціональність системного (дефолтного) віджета. Ми будемо розширювати функціональність віджета «Список товарів каталогу», і змінимо порядок представлення товарів.
Перш ніж ми зможемо створити віджет, нам потрібно кудись його помістити. Для цього нам знадобиться новий (або вже готовий) модуль. Інструкцію по створенню модуля в Мадженто2 ви знайдете за посиланням. Для практики ми будемо використовувати модуль app/code/Sebweo/SortProductsWidget
. В папці модуля нам потрібно створити два файли: registration.php
та etc/module.xml
.
Код файлу registration.php
<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Sebweo_SortProductsWidget', __DIR__ );
Код файлу etc/module.xml
<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Sebweo_SortProductsWidget" setup_version="1.0.0" > <sequence> <module name="Magento_CatalogWidget"/> </sequence> </module> </config>
Якщо ви читали статтю про створення модуля в Мадженто2, тут передбачається, що ви знаєте, чому ці файли повинні бути присутніми і ми не будемо заглиблюватися в їх код. Єдине, що варто відзначити, це тег <sequence>
в etc/module.xml
, який в основному говорить системі завантажувати модуль Magento_CatalogWidget
перед нашим розширенням.
Тепер, коли ми створили модуль, ми можемо почати створювати віджет. Для того, щоб створити макет віджета, ми повинні створити файл etc/widget.xml
.
Код файлу etc/widget.xml
<?xml version="1.0" encoding="UTF-8"?> <widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd"> <widget id="sebweo_products_list" class="Sebweo\SortProductsWidget\Block\Product\ProductsList" placeholder_image="Sebweo_SortProductsWidget::images/sebweo_widget_block.png"> <label translate="true">Sorted Products List</label> <description>Sorted Catalog Products List</description> <parameters> <parameter name="title" xsi:type="text" required="false" visible="true"> <label translate="true">Title</label> </parameter> <parameter name="products_sort_by" xsi:type="select" visible="true" source_model="Sebweo\SortProductsWidget\Model\SortBy"> <label translate="true">Sort Products By</label> </parameter> <parameter name="products_sort_order" xsi:type="select" visible="true" source_model="Sebweo\SortProductsWidget\Model\SortOrder"> <label translate="true">Sort Products Order</label> </parameter> <parameter name="show_pager" xsi:type="select" visible="true" source_model="Magento\Config\Model\Config\Source\Yesno"> <label translate="true">Display Page Control</label> </parameter> <parameter name="products_per_page" xsi:type="text" required="true" visible="true"> <label translate="true">Number of Products per Page</label> <depends> <parameter name="show_pager" value="1" /> </depends> <value>5</value> </parameter> <parameter name="products_count" xsi:type="text" required="true" visible="true"> <label translate="true">Number of Products to Display</label> <value>10</value> </parameter> <parameter name="template" xsi:type="select" required="true" visible="true"> <label translate="true">Template</label> <options> <option name="default" value="Magento_CatalogWidget::product/widget/content/grid.phtml" selected="true"> <label translate="true">Products Grid Template</label> </option> </options> </parameter> <parameter name="cache_lifetime" xsi:type="text" visible="true"> <label translate="true">Cache Lifetime (Seconds)</label> <description translate="true">86400 by default, if not set. To refresh instantly, clear the Blocks HTML Output cache.</description> </parameter> <parameter name="condition" xsi:type="conditions" visible="true" required="true" sort_order="10" class="Magento\CatalogWidget\Block\Product\Widget\Conditions"> <label translate="true">Conditions</label> </parameter> </parameters> </widget> </widgets>
Тут ми створюємо нод <widget>
всередині тега <widgets>
. Тег <widget>
містить параметри для конфігурації нашого віджета. Ідентифікатор віджета – це унікальне ім’я, яке ви хочете використовувати для свого віджета. Це може бути що завгодно, але для цього уроку ми назвали його sebweo_products_list
. Тег class
– це блок, який ми створимо пізніше; він контролює, як насправді функціонує віджет (ми будемо розширювати функціональність блоку Magento/CatalogWidget/Block/Product/ProductsList
). Тег placeholder_image
– це просто зображення, яке відображається в редакторі WYSIWYG бекенду Magento. Це не обов’язково, але додає приємний штрих при перегляді WYSIWYG.
Всередині віджета ви можете бачити, що ми перерахували параметри, які є вхідними даними, що потрібні для WYSIWYG редактора. Кожен з цих параметрів має name
, type
, required
та visible
властивості. Ім’я (name
) має бути логічним, постільки вам потрібно буде посилатися на нього в блоці віджета. Оскільки ми розширюємо базовий блок Magento, ми використовували ті ж імена, що і в системному віджеті списка товарів. Тип (type
) – це просто тип введення, який ви хочете використовувати в бекенді при налаштуванні віджета. Видимість (visible
) керує видимістю опції у формі під час налаштування. Усередині кожного тега параметра є тег <label>
, який встановлює мітку (ярлик) для параметра. Ви також помітите, що деякі параметри мають тег <depends>
. Це означає, що даний параметр буде відображатися тільки в тому випадку, якщо параметр, вказаний в тезі залежності, має значення, встановлене в цьому тезі. Деякі параметри також мають тег <value>
, який встановлює значення за замовчуванням для даного параметра. Нарешті, параметри, які мають свій тип вибору (select
), потребують однієї з двох речей. Їм потрібен або source_model
, як вказано в наших параметрах products_sort_by
і products_sort_order
, або тег <options>
, такий як наш template
параметр.
Тепер, коли ми розібралися з файлом widget.xml
, ми можемо створити файл ProductsList.php
. Він повинен знаходитися за адресою Block/Product/ProductsList.php
.
Код файлу Block/Product/ProductsList.php
<?php namespace Sebweo\SortProductsWidget\Block\Product; class ProductsList extends \Magento\CatalogWidget\Block\Product\ProductsList { const DEFAULT_SORT_BY = 'id'; const DEFAULT_SORT_ORDER = 'asc'; public function createCollection() { $collection = $this->productCollectionFactory->create(); $collection->setVisibility($this->catalogProductVisibility->getVisibleInCatalogIds()); $collection = $this->_addProductAttributesAndPrices($collection) ->addStoreFilter() ->setPageSize($this->getPageSize()) ->setCurPage($this->getRequest()->getParam($this->getData('page_var_name'), 1)) ->setOrder($this->getSortBy(), $this->getSortOrder()); $conditions = $this->getConditions(); $conditions->collectValidatedAttributes($collection); $this->sqlBuilder->attachConditionToCollection($collection, $conditions); return $collection; } public function getSortBy() { if (!$this->hasData('products_sort_by')) { $this->setData('products_sort_by', self::DEFAULT_SORT_BY); } return $this->getData('products_sort_by'); } public function getSortOrder() { if (!$this->hasData('products_sort_order')) { $this->setData('products_sort_order', self::DEFAULT_SORT_ORDER); } return $this->getData('products_sort_order'); } }
Як ми вже згадували, ми розширюємо файл /Magento/CatalogWidget/Block/Product/ProductsList.php
, тому нам не потрібно переписувати будь-які методи, які вже написані в цьому класі. Однак ми переписали функцію createCollection()
і додали дві нові функції. Функція createCollection()
не сильно змінилася, ми просто встановлюємо порядок відображення колекції за допомогою setOrder()
. Ця функція приймає два параметри: рядок, що містить те, що ви хочете відсортувати, і рядок, що містить порядок, в якому ви хочете сортувати (по зростанню або по спадаючій).
Якщо ви подивіться на одну з наших нових функцій, ви побачите те, що саме вони роблять.
public function getSortBy() { if (!$this->hasData('products_sort_by')) { $this->setData('products_sort_by', self::DEFAULT_SORT_BY); } return $this->getData('products_sort_by'); }
Перше, що робить цей метод, це перевіряє, чи встановив користувач параметр віджету з ім’ям products_sort_by
. Якщо ні, то він встановлює products_sort_by
в значення за замовчуванням, яке ми визначили раніше в коді. Нарешті, він повертає дані, пов’язані з products_sort_by
.
Тепер, коли ми створили макет нашого віджета і його Блок, ми можемо створити Моделі. Ці Моделі представляють собою файли, які призначаються як source_model
для параметрів нашого віджета в макеті. Ці файли прості, їх єдине завдання – повернути масив опцій. Для цього уроку вам буде потрібно створити два файли Моделі: Model/SortBy.php
та Model/SortOrder.php
.
Код файлу Model/SortBy.php
<?php namespace Sebweo\SortProductsWidget\Model; class SortBy implements \Magento\Framework\Option\ArrayInterface { public function toOptionArray() { return [ ['value' => 'id', 'label' => __('Product ID')], ['value' => 'name', 'label' => __('Name')], ['value' => 'price', 'label' => __('Price')] ]; } }
Код файлу Model/SortOrder.php
<?php namespace Sebweo\SortProductsWidget\Model; class SortOrder implements \Magento\Framework\Option\ArrayInterface { public function toOptionArray() { return [ ['value' => 'asc', 'label' => __('Ascending')], ['value' => 'desc', 'label' => __('Descending')] ]; } }
Ці файли мають тільки один метод: toOptionArray()
. Він повертає масив можливих опцій для параметра вашого віджета. Кожен параметр має значення, яким є значення параметра, і мітку (ярлик), яку користувач бачить при перегляді параметрів.
Тепер, коли ми створили наш віджет, ми можемо перевірити його і переконатися, що все працює як треба. Для цього додайте віджет на головну сторінку свого інтернет-магазину. Перейдіть в адмінпанелі до WYSIWYG редактору для домашньої сторінки і додайте новий віджет. Ви повинні побачити нові налаштування, які ми додали в наш кастомний віджет.
Після того, як ви створили і налаштували новий віджет, перейдіть на головну сторінку сайту і подивіться, чи працює він! А він повинен працювати!
Вітаємо, ви щойно створили власний віджет в Magento 2!
Якщо хочеш пізнати людину, не слухай, що про неї говорять інші, послухай, що вона говорить…
Вибачення — не означає, що ти не правий, а інша людина має рацію. Це всього…
Атмосферу паперової книги, запах свіжого чорнила і паперу, що трохи залежався, складно замінити гаджетами. Але…