← Voltar ao blog

Como criar um child theme no Magento 2 passo a passo

Rodrigo Biazzi

Toda loja Magento 2 baseada no Luma deveria rodar em um tema próprio, mesmo quando o design é parecido com o Luma. Editar arquivos dentro de vendor/magento/theme-frontend-luma se perde no próximo Composer install, e alterar templates do core no lugar transforma os upgrades em adivinhação. Um child theme dá um lugar para cada customização enquanto o parent continua recebendo correções.

Este guia cria um child theme do Luma no Magento 2.4.8, passo a passo, e explica as partes que costumam dar errado.

Luma ou Blank como parent

Os dois são parents válidos. O Luma é ele mesmo um child do Blank e adiciona seu estilo visual por cima. Escolha o Luma quando o design é parecido com ele e você quer mudar cores, fontes e alguns componentes. Escolha o Blank quando o design é muito diferente, para não perder tempo desfazendo estilos do Luma.

Se você está começando uma loja nova e a performance importa, olhe também o Hyvä antes de se comprometer com qualquer um dos dois. A comparação Hyvä vs Luma cobre os prós e contras. O resto deste guia assume um parent Luma.

Passo 1: a pasta

Os temas ficam em app/design/frontend/<Vendor>/<theme>. Use o nome da sua empresa ou do cliente como vendor e um nome curto em minúsculas para o tema:

mkdir -p app/design/frontend/Acme/default/{etc,web/css/source,web/images,media,Magento_Theme/layout}

Você também pode distribuir um tema como pacote Composer em vendor/, que é como os fornecedores de temas os distribuem. Para um tema específico de uma loja, app/design é mais simples.

Passo 2: theme.xml

<?xml version="1.0"?>
<theme xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="urn:magento:framework:Config/etc/theme.xsd">
    <title>Acme Default</title>
    <parent>Magento/luma</parent>
    <media>
        <preview_image>media/preview.jpg</preview_image>
    </media>
</theme>

O valor de parent é o código do tema, Vendor/name. A imagem de preview é o que o admin mostra na lista de temas. É opcional, mas se você a declarar o arquivo precisa existir.

Passo 3: registration.php

<?php

declare(strict_types=1);

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(
    ComponentRegistrar::THEME,
    'frontend/Acme/default',
    __DIR__
);

O segundo argumento é a área seguida do caminho do tema. Um erro de digitação aqui é o motivo mais comum de um tema não aparecer no admin.

Passo 4: composer.json

Para um tema em app/design, o Composer não o carrega, mas um composer.json ainda documenta dependências e permite mover o tema para um pacote próprio depois:

{
    "name": "acme/theme-frontend-default",
    "description": "Acme storefront theme",
    "type": "magento2-theme",
    "require": {
        "magento/theme-frontend-luma": "*"
    },
    "autoload": {
        "files": [
            "registration.php"
        ]
    }
}

Passo 5: registre e aplique o tema

bin/magento setup:upgrade
bin/magento cache:flush

O setup:upgrade registra temas novos na tabela theme. Depois vá em Content, Design, Configuration no admin, edite a linha da store view, escolha o novo tema e salve. Você pode aplicar por website ou por store view, o que é útil quando você quer testar o tema novo primeiro em uma store view.

Aplicar um tema grava em core_config_data, em design/theme/theme_id. Se você gerencia a configuração em app/etc/config.php com app:config:dump, inclua o tema para que ele seja o mesmo em todos os ambientes.

Passo 6: imagens e view.xml

Um child theme herda o etc/view.xml do parent, que define os tamanhos das imagens de produto, as opções da galeria e as configurações de bundling de JS. Se você precisa mudar algum deles, copie o arquivo do parent de vendor/magento/theme-frontend-luma/etc/view.xml para Acme/default/etc/view.xml e edite lá. O arquivo do child é mesclado com o do parent, mas na prática as equipes copiam o arquivo inteiro para ficar legível.

Depois de mudar os tamanhos das imagens, redimensione as imagens do catálogo para que o cache bata com os novos tamanhos:

bin/magento catalog:images:resize

Em catálogos grandes isso demora bastante. Rode em um período tranquilo ou use a opção assíncrona, --async, que enfileira o trabalho para o consumer media.storage.catalog.image.resize.

Passo 7: logo

O logo é definido no layout XML. Coloque o arquivo em web/images/logo.svg e aponte o block do logo para ele em Magento_Theme/layout/default.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="logo">
            <arguments>
                <argument name="logo_file" xsi:type="string">images/logo.svg</argument>
                <argument name="logo_width" xsi:type="number">180</argument>
                <argument name="logo_height" xsi:type="number">48</argument>
            </arguments>
        </referenceBlock>
    </body>
</page>

Definir width e height ajuda o navegador a reservar espaço para o logo antes de ele carregar, o que evita um layout shift no header. Um logo enviado no admin em Content, Design, Configuration sobrescreve esse arquivo.

Como o fallback funciona

Quando o Magento procura um template, arquivo de layout, imagem ou stylesheet, ele confere primeiro o tema atual, depois cada tema parent e depois o módulo. Isso dá três formas de customizar o tema:

  • Templates: copie um template do módulo para o mesmo caminho relativo dentro da pasta do módulo no seu tema. vendor/magento/module-catalog/view/frontend/templates/product/view/details.phtml vira Acme/default/Magento_Catalog/templates/product/view/details.phtml.
  • Layout: adicione um arquivo com o mesmo handle em Magento_Catalog/layout/. Ele estende os arquivos do módulo e do parent em vez de substituí-los. O guia de layout XML explica as instruções.
  • Estilos: adicione web/css/source/_extend.less e _theme.less. O artigo de customização com LESS explica qual usar.

Copie o mínimo possível de templates. Cada template copiado deixa de receber as correções do módulo, inclusive correções de segurança em escaping. Antes de copiar, veja se um argumento de layout, um view model ou um plugin resolve. Quando copiar, mantenha uma lista e compare as cópias com a nova versão do core a cada upgrade.

Traduções no tema

Um tema pode ter seus próprios dicionários em i18n/en_US.csv, i18n/pt_BR.csv e assim por diante. As traduções do tema sobrescrevem as dos módulos, o que as torna um bom lugar para mudanças de texto específicas desta storefront. O guia de traduções cobre os detalhes.

Fazendo o deploy do tema

No developer mode, o Magento gera os arquivos estáticos sob demanda. No production mode, faça o deploy deles para o seu tema e para cada locale que você usa:

bin/magento setup:static-content:deploy en_US pt_BR --theme Acme/default --theme Magento/backend -f

A flag -f só é necessária fora do production mode. Fazer o deploy só dos temas que você usa é mais rápido do que de todos. O próprio Luma não precisa de deploy se nenhuma store view o usa diretamente, porque os arquivos dele já entram pelo fallback na saída do seu tema.

Problemas comuns

  • O tema não aparece na lista do admin. Confira o registration.php e rode o setup:upgrade de novo.
  • A loja fica sem estilo depois de trocar. O conteúdo estático não foi publicado para o novo tema, ou um _theme.less customizado substituiu o do parent sem copiar as variáveis dele.
  • As mudanças de template não aparecem. Limpe var/view_preprocessed e os caches de layout e de block, e confirme que o caminho bate exatamente com o caminho do módulo.

FAQ

Um child theme pode ter seu próprio child theme?

Pode. O fallback percorre todos os parents da cadeia. O Luma já é child do Blank, então um tema baseado no Luma é um tema de terceiro nível.

Preciso de um módulo para criar um tema?

Não. Um tema só precisa de theme.xml e registration.php. Use um módulo quando precisar de lógica PHP como view models, plugins ou controllers, e deixe o tema para a apresentação.

Por que meu tema some depois do deploy em outro servidor?

A tabela theme daquele servidor não foi atualizada. Rode bin/magento setup:upgrade como parte do deploy e mantenha a atribuição do tema no config.php se você gerencia a configuração em código.

Posso usar temas diferentes por store view?

Pode. Content, Design, Configuration permite atribuir um tema por website ou por store view, então uma store view B2B pode rodar um tema diferente do da loja principal.

Atendo como freelancer em Magento e Adobe Commerce, do setup de tema até storefronts completas. Se precisar de ajuda com isso, fale comigo.

Artigos relacionados