Cómo organizar skins en Symfony

Esta es una breve nota sobre cómo puede organizar el uso de máscaras para páginas de marca en Twig usando el ejemplo de Symfony. Esta solución no está vinculada a Symfony. Por analogía, puede implementar máscaras en cualquier proyecto utilizando Twig.


Tiene una tienda en línea, una sala de cine en línea, un póster para eventos, un catálogo de programas de televisión, etc. Un buen día, tiene la tarea de marcar una página de catálogo para atraer a los usuarios y aumentar las ventas para algún tipo de acción. ¿Cómo hacer esto si todos los productos del catálogo son equivalentes para el motor?


La solución más simple es codificar el ID del producto del catálogo. Puede agregar una condición a la plantilla e imponer bodyuna clase CSS adicional en la etiqueta, de acuerdo con la cual puede estilizar la página en estilos generales.


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

body.product-12345 {
   # custom style
}

Los estilos pueden hacer mucho, especialmente si usa flex, pero los estilos no son omnipotentes. A veces, las posibilidades de los estilos no son suficientes para marcar una página y necesita cambiar el marcado HTML (diseño) de la página, y esto se hace por analogía con los 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',
] %}

{# ... #}

Otra buena solución sería colocar los estilos de máscaras específicas en archivos separados y conectarse solo en una página de marca. Por lo tanto, no ensuciaremos los estilos principales con basura, que se usa solo en un par de páginas. Si alguien está interesado, entonces, en un artículo separado, puedo decirle cómo configurar Gulp para construir una gran cantidad de máscaras juntas y por separado. Tenemos más de 300 máscaras de este tipo en el proyecto.


All Articles