Como criar arquivos de layout Magento 2
Tags: php, magento2, braziliandevs, tutorial
Published: 2021-11-26 14:35:41

## Contextualizando

### O que é a Visualização?

A visualização (*view*) faz parte da camada de controle do padrão de arquitetura de software MVC (*Model*-*Controller*-*View*).

A camada de visualização é responsável por uma interface, onde o usuário pode interagir, e exibir os dados da camada de modelo (*Model*). Os dados, quando alterados na camda de modelo, devem refletir os novos valores na camada de visualização.

---

## Código

O **Layout** é o principal caminho da camada de visão no módulo. O arquivo de *layout* fornece a estrutura para páginas web usando um arquivo XML que identifica todos os contêineres e blocos que compõem a página, deve ser localizado como: `\{Vendor}\{Module}\view\{area}\layout\{route_id}_{controller_directory}_{controller_name}.xml`.

O caminho da área pode ser *frontend* ou *adminhtml* que define onde o *layout* será aplicado. Para inserir blocos no painel administrativo do Magento utilizá-se a área *adminhtml*, e para inserir blocos na parte visual da loja do site utilizá-se a área *frontend*. Existe um arquivo de layout especial, o `default.xml`, que é utilizado quando é necessário fazer uma alteração em todas as páginas da sua área.

```xml
<?xml version="1.0"?>
<layout xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/layout_generic.xsd">
    <body>
        <referenceContainer name="{container_name}">
            <uiComponent name="{ui_component_name}"/>

            <block class="{Vendor}\{Module}\Block\{Directory}\{Class}" name="{block_name}" template="{Vendor_Module}::{path}/{file_name}.phtml" />

            <block name="{block_name}" template="{Vendor_Module}::{path}/{file_name}.phtml">
                <arguments>
                    <argument name="{view_model_name}" xsi:type="object">{Vendor}\{Module}\ViewModel\{ClassName}</argument>
                </arguments>
            </block>

            <referenceBlock name="{block_name}" template="Vendor_Module::{path}/{file_name}.phtml"/>

            <container name="{container_name}" as="{alias_name}" label="{Label Name}" htmlTag="{tag_name}" htmlClass="{class-name}" htmlId="{idName}">
                <uiComponent name="{ui_component_name}"/>

                <block class="{Vendor}\{Module}\Block\{Directory}\{Class}" name="{block_name}" template="{Vendor_Module}::{path}/{file_name}.phtml" />

                <block name="{block_name}" template="{Vendor_Module}::{path}/{file_name}.phtml">
                    <arguments>
                        <argument name="{view_model_name}" xsi:type="object">{Vendor}\{Module}\ViewModel\{ClassName}</argument>
                    </arguments>
                </block>

                <referenceBlock name="{block_name}" template="Vendor_Module::{path}/{file_name}.phtml"/>
            </container>
        </referenceContainer>
    </body>
</layout>
```

### Ui Component

O nó `<uiComponent>` possui o atributo `name` que é usado para referenciar um arquivo XML que especifica as definições de configuração do componente e a estrutura interna que herda das classes bases do *Ui Components* do Magento.

### Move

O arquivo *layout* fornece a estrutura para páginas web usando um arquivo XML que identifica todos os contêineres e blocos que compõem a página.

O nó `<move>` muda a ordem de um bloco ou contêiner específico já declarado como filho de outro específico elemento. Caso o elemento não for definido, este nó será ignorada na renderização. Durante a geração do *layout*, o nó `<move>` é processado antes do nó  `<remove>`. Isso significa que se algum elemento for movido para outro elemento programado para ser removido, o elemento movido será removido junto.

Se o atributo `as` não for definido, o valor atual do alias do elemento será usado. Se isso não for possível, o valor do nome do atributo usado em seu lugar.

#### Atributos do nó ‘move’

| Name        | Descrição                                                                                                                                                                                                                                                                        | Valor                                                                                                  | Obrigatório? |
|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|--------------|
| element     | Nome do elemento que será movido.                                                                                                                                                                                                                                                | Nome do elemento.                                                                                      | true         |
| destination | Nome do elemento pai que receberá o elemento.                                                                                                                                                                                                                                    | Nome do elemento.                                                                                      | true         |
| as          | Alias ou nome do elemento na nova localização.                                                                                                                                                                                                                                   | 0-9, A-Z, a-z, sublinhado (_), ponto (.), sinal de menos (-). Deve iniciar com letras. Case-sensitive. | false        |
| after       | Específica a posição do elemento relativa aos seus irmãos. Use o sinal de menos (-) para posicionar o elemento depois de todos os outros elementos irmãos do mesmo nível de aninhamento. Se o atributo for omitido, o elemento será exibido depois de todos os elementos irmãos. | Nome do elemento.                                                                                      | false        |
| before      | Específica a posição do elemento relativa aos seus irmãos. Use o sinal de menos (-) para posicionar o elemento antes de todos os outros elementos irmãos do mesmo nível de aninhamento. Se o atributo for omitido, o elemento será exibido depois de todos os elementos irmãos.  | Nome do elemento.                                                                                      | false        |

### Remover

O nó `<remove>` é usado somente para remover os recursos estáticos vinculados a uma seção `<head>` da página (CSS, JS, etc). Para remover blocos ou contêineres, use o atributo `remove` nos nós `<referenceBlock>` e `<referenceContainer>`.

### Update

O nó `<update>` inclui um específico arquivo de *layout*. O atributo `handle` específica qual layout será incluído. 

### Contêiner

Contêineres atribuem a estrutura do conteúdo para a página usando nós dentro do arquivo *layout* XML. Um contêiner não possui conteúdo adicional, exceto o conteúdo incluído no elemento, mas que encapsula os elementos de blocos e outros contêineres.

Um contêiner renderiza um elemento filho durante a geração da saída de visualização. O elemento gerado pode estar vazio ou pode conter um conjunto arbitrário de elementos `<block>`, `<container>`, `<referenceBlock>` e `<referenceContainer>`. Se o contêiner estiver vazio e não houver filhos disponíveis, o contêiner não será exibido no código fonte do navegador.

#### Atributos do nó ‘container’

| Atributo  | Descrição                                                                                                                                                                                                                                               | Valor                                                                                                  | Obrigatório? |
|-----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|--------------|
| name      | Nome que poderá ser usado para endereçar o contêiner. O nome deve ser único por página gerada. Se não for especificado, será gerado automaticamente.                                                                                                    | 0-9, A-Z, a-z, sublinhado (_), ponto (.), sinal de menos (-). Deve iniciar com letras. Case-sensitive. | false        |
| label     | Descreve a finalidade do contêiner.                                                                                                                                                                                                                     | Qualquer um.                                                                                           | false        |
| before    | Usado para posicionar o contêiner antes de um elemento com o mesmo pai. O nome do elemento ou alias é especificado como valor. Use o sinal de menos (-) para posicionar o contêiner antes de todos os outros elementos do mesmo nível de aninhamento.   | Nome do elemento ou sinal de menos (-).                                                                | false        |
| after     | Usado para posicionar o contêiner depois de um elemento com o mesmo pai. O nome do elemento ou alias é especificado como valor. Use o sinal de menos (-) para posicionar o contêiner depois de todos os outros elementos do mesmo nível de aninhamento. | Nome do elemento ou sinal de menos (-).                                                                | false        |
| as        | Um alias que serve para identificar no escopo o elemento.                                                                                                                                                                                               | 0-9, A-Z, a-z, sublinhado (_), ponto (.), sinal de menos (-). Deve iniciar com letras. Case-sensitive. | false        |
| output    | Define se o elemento root deve ser gerado. Se sim, o elemento será adicionado à lista de saída (se não for especificado, o elemento pai é responsável por renderizar seus filhos).                                                                      | Qualquer valor, exceto toHtml obsoletos ("1" é o valor recomendado).                                   | false        |
| htmlTag   | Parâmetro de saída. Se especificado, a saída é agrupada dentro da tag HTML especificada.                                                                                                                                                                | aside, dd, div, dl, fieldset, main, nav, header, footer, ol, p, section, table, tfoot e ul             | false        |
| htmlId    | Parâmetro de saída. Se especificado, a saída é agrupado. Se não houver nenhum elemento agrupado, este atributo não tem efeito.                                                                                                                          | Qualquer id válido para HTML5.                                                                         | false        |
| htmlClass | Parâmetro de saída. Se especificado, a saída é agrupado. Se não houver nenhum elemento agrupado, este atributo não tem efeito.                                                                                                                          | Qualquer id válido para HTML5.                                                                         | false        |

### Bloco

Blocos renderizam conteúdos dos elementos da interface dos usuários na página utilizando nós `<block>` dentro do arquivo *layout* XML. Blocos usam templates para gerar o HTML e serem inseridos no pai da estrutura do bloco.

O nó `block` é uma unidade de saída da página que renderiza algum conteúdo (qualquer coisa visualmente tangível para o usuário final).

Blocos são uma unidade de construção fundamental para layouts no Magento. Eles são o link entre a classe de Bloco do PHP (que contém o lógica do negócio) e o *template* (que renderiza o conteúdo). Blocos podem ter diversas ramificações (filhos, netos, etc).

> É recomendável sempre adicionar um atributo `name` ao bloco, ou o Magento nomeará aleatoriamente.

Se não for especificado, um nome automático será atribuído no formato ANONYMOUS_{n}.

#### Atributos do nó ‘block’

| Atributo  | Descrição                                                                                                                                                                                                                                      | Valor                                                                                                  | Obrigatório? |
|-----------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|--------------|
| before    | Usado para posicionar o bloco antes de um elemento com o mesmo pai. O nome do elemento ou alias é especificado como valor. Use o sinal de menos (-) para posicionar o bloco antes de todos os outros elementos do mesmo nível de aninhamento.  | Nome do elemento ou sinal de menos (-).                                                                | false        |
| after     | Usado para posicionar o bloco depois de um elemento com o mesmo pai. O nome do elemento ou alias é especificado como valor. Use o sinal de menos (-) para posicionar o bloco depoi de todos os outros elementos do mesmo nível de aninhamento. | Nome do elemento ou sinal de menos (-).                                                                | false        |
| template  | Um template que representa a funcionalidade do bloco para o qual o atributo é atribuído. Se o atributo for omitido, o bloco não renderizará nenhuma saída, a menos que o bloco (ou pai) tenha a variável $_template definida corretamente.     | {Vendor}_{Module}::{pastas}/{arquivo}.phtml                                                            | false        |
| as        | Um alias que serve para identificar no escopo o elemento.                                                                                                                                                                                      | 0-9, A-Z, a-z, sublinhado (_), ponto (.), sinal de menos (-). Deve iniciar com letras. Case-sensitive. | false        |
| cacheable | Define se o emento bloco é cacheavel. Isto não pode ser usado para fins de desenvolvimento e tornar dinâmicos os elementos necessários da página.                                                                                              | true (padrão) / false                                                                                  | false        |
| ifconfig  | Faz a visibilidade do bloco depender de uma configuração.                                                                                                                                                                                      | Caminho da configuração.                                                                               | false        |

Dados podem ser passados do arquivo *layout* XML para o bloco usando o nó `<arguments>` no nó filho. Os valores dos argumentos definidos em um arquivo de layout podem ser acessados em *templates* usando os métodos `$block->getData('{argument_name}')` e `$block->hasData('{argument_name}')` (retorna um valor boleano verificando se o valor foi definido). O `{argument_name}` é obtido do atributo `name` do nó `<argument>`.

#### Argumentos do nó ‘block’

| Atributo  | Descrição                                                    | Valor                                                                                                  | Obrigatório? |
|-----------|--------------------------------------------------------------|--------------------------------------------------------------------------------------------------------|--------------|
| name      | Nome do argumento.                                           | 0-9, A-Z, a-z, sublinhado (_), ponto (.), sinal de menos (-). Deve iniciar com letras. Case-sensitive. | true         |
| shared    | Se falso, cria uma nova instância do bloco.                  | false                                                                                                  | false        |
| translate | Específica se a valor (deve ser tipo string) será traduzido. | true (padrão) / false                                                                                  | false        |
| xsi:type  | Tipo do argumento.                                           | string, boolean, object, number, null, array, options, url, helper                                     | true         |

### Referências

Para atualizar contêineres e blocos são utilizados os nós `<referenceBlock>` e `<referenceContainer>`. O nó `<referenceBlock>` contém todos os atributos do nó `<block>` e o nó `<referenceContainer>` contém todos os atributos do nó `<container>`.

#### Atributos das Referências

| Atributo | Descrição                                                                                                                                                                                                   | Valor        | Obrigatório? |
|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|--------------|--------------|
| remove   | Permite remover ou cancelar a remoção do elemento. Quando um contêiner é removido, os elementos filhos são removidos também.                                                                                | true / false | false        |
| display  | Permite desabilitar a renderização de um específico bloco ou contêiner com todos os seus filhos. Os objetos PHP do bloco, contêiner ou seus filhos ainda serão gerados e disponibilizados para manipulação. | true / false | false        |

---

## 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.

```bash
php bin/magento cache:clean
php bin/magento flush
```

### Diretórios e Arquivos

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

```
- app/
  - code/
    - {Vendor}/
        - {Module}/
          - etc/
            - module.xml
          - view/
            - {area}/
              - layout/
               - {route_id}_{controller_directory}_{controller_name}.xml
          - registration.php
          - composer.json
```