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 body
uma 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.