Досить часто при роботі з 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!
Дуже багато людей недооцінюють те, що у них є, і переоцінюють те, чого у них…
Варто тільки повірити, що ви можете – і ви вже на півдорозі до цілі Теодор…
Успішний бізнес у 2025 році неможливо уявити без стабільної ІТ-інфраструктури. Від корпоративного сайту до CRM-системи…
WordPress роками був неперевершеним "монолітом": він відповідав і за зручну адмін-панель, і за збереження даних,…
У світі веб-серверів часто говорять про протистояння Nginx vs Apache. Але що, якби я сказав…