Como organizar skins no symfony

Esta é uma breve observação sobre como você pode organizar o uso de skins para páginas de marca no Twig usando o exemplo do Symfony. Esta solução não está ligada ao Symfony. Por analogia, você pode implementar skins em qualquer projeto usando o Twig.


Você tem uma loja on-line, um cinema on-line, um pôster para eventos, um catálogo de programas de TV etc. Um belo dia, você tem a tarefa de criar uma marca de página de catálogo para atrair usuários e aumentar as vendas para algum tipo de ação. Como fazer isso se todos os produtos no catálogo são equivalentes ao mecanismo?


A solução mais simples é codificar o código do produto no catálogo. Você pode adicionar uma condição ao modelo e impor bodyuma classe CSS adicional na tag, de acordo com a qual poderá estilizar a página em estilos gerais.


{% block body_class -%}
    {{ parent () }} product-{{ product.id }}
{%- endblock %}

body.product-12345 {
   # custom style
}

Os estilos podem fazer muito, especialmente se você usar o flex, mas os estilos não são onipotentes. Às vezes, as possibilidades de estilos não são suficientes para marcar uma página e você precisa alterar a marcação HTML (layout) da página, e isso é feito por analogia com os estilos.


{% if product.id == 12345 %}
    {# custom code #}
{% else %}
    {# original code #}
{% endif %}

, , , (YAGNI KISS). — . , , .


, , — . , . . , . , . , - (DRY).


. , , , . , , .


product/show.html.twig. product/skin/<skin_name>/, <skin_name> — . default product/skin/default/show.html.twig. , .


public function show(Product $product): Response
{
    return $this->render(sprintf('product/skin/%s/show.html.twig', $product->skin), [
        'product' => $product,
    ]);
}

, , .


{# product/skin/custom_skin/show.html.twig #}

{% extends 'product/skin/default/show.html.twig' %}

{% blocksome_block %}
    {{ parent() }}
    {# customise something #}
{% endblock %}

, . , , , , . . , . , .


{# product/skin/default/show.html.twig #}

{% extends 'product/skin/' ~ product.skin ~ '/layout.html.twig' %}

{# ... #}

{# product/skin/custom_skin/layout.html.twig #}

{% extends 'product/skin/default/layout.html.twig' %}

{# ... #}

:


  • product/skin/<skin_name>/show.html.twig ️▼
  • product/skin/default/show.html.twig ️▼
  • product/skin/<skin_name>/layout.html.twig ️▼
  • product/skin/default/layout.html.twig ️▼
  • ...

— .


  • default
    • layout.html.twig
    • show.html.twig
    • qa.html.twig
    • similar.html.twig
  • first_skin
    • layout.html.twig
    • show.html.twig
    • qa.html.twig
    • similar.html.twig
  • second_skin
    • layout.html.twig
    • show.html.twig
    • qa.html.twig
    • similar.html.twig

, . Twig.


public function show(Product $product, Twig $twig): Response
{
    $template = $twig->resolveTemplate([
        sprintf('product/skin/%s/show.html.twig', $product->skin),
        'product/skin/default/show.html.twig',
    ]);
    $content = $template->render([
        'product' => $product,
    ]);

    return new Response($content);
}

resolveTemplate() . , , — . , Symfony , .


product/skin/default/show.html.twig , layout.html.twig. , Twig extends , extends resolveTemplate() . - .


{# product/skin/default/show.html.twig #}

{% extends [
    'product/skin/' ~ product.skin ~ '/layout.html.twig',
    'product/skin/default/layout.html.twig',
] %}

{# ... #}

Outra boa solução seria colocar os estilos de capas específicas em arquivos separados e conectar-se apenas a uma página de marca. Portanto, não vamos sujar os principais estilos com lixo, que é usado apenas em algumas páginas. Se alguém estiver interessado, em um artigo separado, posso dizer como configurar o gulp para criar um grande número de skins juntos e separadamente. Temos mais de 300 skins desse tipo no projeto.


All Articles