Como criar um widget personalizável no Magento 2

Lucas Teixeira dos Santos Santana - Jul 14 '22 - - Dev Community

Contextualizando

O que é um widget?

Widgets são utilizados para adicionar conteúdos dinâmicos ou estáticos às páginas da loja ou blocos de conteúdo do CMS. Os widgets são componentes reutilizáveis que podem ser adicionados em qualquer bloco ou página CMS do Magento 2. Por padrão os seguintes widgets já ficam disponiveis:

  • Link da página do CMS;
  • Bloco estático CMS;
  • Link da Categoria do Catálogo;
  • Lista de Novos Produtos do Catálogo;
  • Link do produto do catálogo;
  • Lista de produtos do catálogo;
  • Pedidos e Devoluções;
  • Produtos recentemente comparados;
  • Produtos vistos recentemente.

Código para criação do widget

É necessário adicionar ao módulo a dependência ao módulo Magento_Widget no arquivo \{Vendor}\{Module}\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="{Vendor}_{Module}">
        <sequence>
            ...
            <module name="Magento_Widget" />
        </sequence>
    </module>
</config>
Enter fullscreen mode Exit fullscreen mode

widget.xml

Este arquivo deve estar localizado na pasta \{Vendor}\{Module}\etc\widget.xml e declara a criação do modelo do widget para ser registrado nas opções no painel do administrador.

O nó <widget> declara um novo widget e deve ser filho do nó <widgets>, e pode ter um ou mais nós <parameter>, que representam campos com os valores necessários para a utilização no widget.

<?xml version="1.0"?>
<widgets xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Widget:etc/widget.xsd">
    <widget class="{Vendor}\{Module}\Block\Widget\{WidgetClassName}" id="{widget_name}">
        <label>{Widget Label}</label>
        <description>{Widget Desrcription}</description>
        <parameters>
            <parameter name="{parameter_name}" xsi:type="text" required="{true/false}" visible="{true/false}" sort_order="{integer}">
                <label>{Parameter Label}</label>
            </parameter>

            <parameter name="{parameter_name}" xsi:type="select" required="{true/false}" visible="{true/false}" sort_order="{integer}">
                <label>{Parameter Label}</label>
                <options>
                    <option name="{option_name}" value="{option_value}">
                        <label>{Option Label}</label>
                    </option>
                </options>
            </parameter>

            <parameter name="{parameter_name}" xsi:type="multiselect" required="{true/false}" visible="{true/false}" sort_order="{integer}">
                <label>{Parameter Label}</label>
                <options>
                    <option name="{option_name}" value="{option_value}">
                        <label>{Option Label}</label>
                    </option>
                </options>
            </parameter>

            <parameter name="{parameter_name}" xsi:type="multiselect" source_model="{Vendor}\{Module}\Model\{Directory}\{ClassName}" required="{true/false}" visible="{true/false}" sort_order="{integer}">
                <label>{Parameter Label}</label>
            </parameter>

            <parameter name="{parameter_name}" xsi:type="block" required="{true/false}" visible="{true/false}" sort_order="{integer}">
                <label>{Parameter Label}</label>
                <block class="{Vendor}\{Module}\Block\{Directory}\Widget\{ClassName}">
                    <data>
                        <item name="button" xsi:type="array">
                            <item name="open" xsi:type="string">Select Product...</item>
                        </item>
                    </data>
                </block>
                <depends>
                    <parameter name="display_mode" value="fixed" />
                </depends>
            </parameter>
        </parameters>

        <containers>
            ...
        </containers>
    </widget>
</widgets>
Enter fullscreen mode Exit fullscreen mode
Nós Descrição Tipo
label Legenda para identificar o nome do widget (Obrigatório). String
description Contém uma explicação concisa da finalidade do widget (Obrigatório). String
parameters Lista de opções do widget. Object
containers Lista de contêineres de layout, onde o widget pode ser injetado. Object

Bloco do Widget

Um arquivo Block deve conter toda a lógica de visualização necessária, é altamente recomendável não ter conter nenhum tipo de HTML ou CSS. Cada Bloco do widget deve extender a partir da classe \Magento\Framework\View\Element\Template e implementar a interface \Magento\Widget\Block\BlockInterface.

Nesta classe é obrigatório a definição da variável $_template para indicar qual o template que será renderizado pelo frontend.

<?php

namespace {Vendor}\{Module}\Block\Widget;

use Magento\Framework\View\Element\Template;
use Magento\Widget\Block\BlockInterface;

class {WidgetClassName} extends Template implements BlockInterface
{
    protected $_template = "widget/{file_name}.phtml";

    public function {methodName}() {
        // Widget code here
    }
}
Enter fullscreen mode Exit fullscreen mode

Para saber mais sobre Blocos e como funciona a exibição deles basta acessar o post "Como criar um bloco no Magento 2".

Template

Arquivos de template devem seguir a estrutura de pastas \{Vendor}\{Module}\view\{area}\templates\{paths}\{file_name}.phtml. No arquivo de template podemos usar a variável $block para acessar os métodos públicos que a classe Block disponibiliza.

Os arquivos de template com a extensão phtml são destinados a conteúdos dinâmicos, mesclando PHP (vindo da classe Block) com HTML (descrito no próprio template).

Para acessar o valor de algum parâmetro específico basta passar o nome do parâmetro dentro do método getData() através da variável $block.

<?php
/**
 * @var \{Vendor}\{Module}\Block\Widget\{WidgetClassName} $block 
**/

$block->{methodName}();

$parameterValue = $block->getData('{parameter_name}');
?>
Enter fullscreen mode Exit fullscreen mode

Finalizando

Valores entre chaves ({test}) devem ser alterados na implementação do código.

Habilitando as alterações

Execute o comando PHP para limpar todos os caches de armazenamento em cache do processos.

php bin/magento cache:clean
php bin/magento flush
Enter fullscreen mode Exit fullscreen mode

Diretórios e Arquivos

Segue a a lista de diretórios e arquivos que devem ser criados.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .