рдпрд╣ рдПрдХ рд╕рдВрдХреНрд╖рд┐рдкреНрдд рдЯрд┐рдкреНрдкрдгреА рд╣реИ рдХрд┐ рдЖрдк рд╕рд┐рдЧрдиреА рдХреЗ рдЙрджрд╛рд╣рд░рдг рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЯреНрд╡рд┐рдЧ рдореЗрдВ рдкреГрд╖реНрдареЛрдВ рдХреА рдЦрд╛рд▓ рдХреЗ рдЙрдкрдпреЛрдЧ рдХреЛ рдХреИрд╕реЗ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдпрд╣ рд╕рдорд╛рдзрд╛рди рд╕рд┐рдореНрдлрдиреА рд╕реЗ рдмрдВрдзрд╛ рдирд╣реАрдВ рд╣реИред рд╕рд╛рджреГрд╢реНрдп рд╕реЗ, рдЖрдк рдЯрд╣рдиреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдХрд┐рд╕реА рднреА рдкрд░рд┐рдпреЛрдЬрдирд╛ рдореЗрдВ рдЦрд╛рд▓ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЖрдкрдХреЗ рдкрд╛рд╕ рдПрдХ рдСрдирд▓рд╛рдЗрди рд╕реНрдЯреЛрд░, рдПрдХ рдСрдирд▓рд╛рдЗрди рдореВрд╡реА рдерд┐рдпреЗрдЯрд░, рдШрдЯрдирд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдПрдХ рдкреЛрд╕реНрдЯрд░, рдЯреАрд╡реА рд╢реЛ рдХреА рдПрдХ рд╕реВрдЪреА, рдЖрджрд┐ред рдПрдХ рдареАрдХ рджрд┐рди, рдЖрдкрдХреЛ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛рдУрдВ рдХреЛ рдЖрдХрд░реНрд╖рд┐рдд рдХрд░рдиреЗ рдФрд░ рдХрд┐рд╕реА рдкреНрд░рдХрд╛рд░ рдХреА рдХрд╛рд░реНрд░рд╡рд╛рдИ рдХреЗ рд▓рд┐рдП рдмрд┐рдХреНрд░реА рдмрдврд╝рд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рдХреИрдЯрд▓реЙрдЧ рдкреГрд╖реНрда рдХреЛ рдмреНрд░рд╛рдВрдб рдХрд░рдиреЗ рдХрд╛ рдХрд╛рд░реНрдп рдорд┐рд▓рддрд╛ рд╣реИред рдпрд╣ рдХреИрд╕реЗ рдХрд░реЗрдВ рдпрджрд┐ рдХреИрдЯрд▓реЙрдЧ рдХреЗ рд╕рднреА рдЙрддреНрдкрд╛рдж рдЗрдВрдЬрди рдХреЗ рд▓рд┐рдП рдмрд░рд╛рдмрд░ рд╣реИрдВ?
рд╕рдмрд╕реЗ рд╕рд░рд▓ рдЙрдкрд╛рдп рдХреИрдЯрд▓реЙрдЧ рд╕реЗ рдЙрддреНрдкрд╛рдж рдЖрдИрдбреА рдХреЛ рд╣рд╛рд░реНрдбрдХреЛрдб рдХрд░рдирд╛ рд╣реИред рдЖрдк рдЯреЗрдореНрдкреНрд▓реЗрдЯ рдореЗрдВ рдПрдХ рд╢рд░реНрдд рдЬреЛрдбрд╝ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ body
рдЯреИрдЧ рдкрд░ рдПрдХ рдЕрддрд┐рд░рд┐рдХреНрдд рд╕реАрдПрд╕рдПрд╕ рдХреНрд▓рд╛рд╕ рд▓рдЧрд╛ рд╕рдХрддреЗ рд╣реИрдВ , рдЬрд┐рд╕рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдлрд┐рд░ рдЖрдк рд╕рд╛рдорд╛рдиреНрдп рд╢реИрд▓рд┐рдпреЛрдВ рдореЗрдВ рдкреЗрдЬ рдХреЛ рд╕реНрдЯрд╛рдЗрд▓ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
{% block body_class -%}
{{ parent () }} product-{{ product.id }}
{%- endblock %}
body.product-12345 {
# custom style
}
рд╢реИрд▓рд┐рдпрд╛рдБ рдмрд╣реБрдд рдХреБрдЫ рдХрд░ рд╕рдХрддреА рд╣реИрдВ, рдЦрд╛рд╕рдХрд░ рдпрджрд┐ рдЖрдк рдлреНрд▓реЗрдХреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╢реИрд▓рд┐рдпрд╛рдБ рд╕рд░реНрд╡рд╢рдХреНрддрд┐рдорд╛рди рдирд╣реАрдВ рд╣реИрдВред рдХрднреА-рдХрднреА рдХрд┐рд╕реА рдкреГрд╖реНрда рдХреА рдмреНрд░рд╛рдВрдбрд┐рдВрдЧ рдХреЗ рд▓рд┐рдП рд╢реИрд▓рд┐рдпреЛрдВ рдХреА рд╕рдВрднрд╛рд╡рдирд╛рдПрдБ рдкрд░реНрдпрд╛рдкреНрдд рдирд╣реАрдВ рд╣реЛрддреА рд╣реИрдВ рдФрд░ рдЖрдкрдХреЛ рдкреГрд╖реНрда рдХреЗ HTML рдорд╛рд░реНрдХрдЕрдк (рд▓реЗрдЖрдЙрдЯ) рдХреЛ рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реЛрддреА рд╣реИ, рдФрд░ рдпрд╣ рд╢реИрд▓рд┐рдпреЛрдВ рдХреЗ рд╕рд╛рде рд╕рд╛рджреГрд╢реНрдп рджреНрд╡рд╛рд░рд╛ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
{% 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',
] %}
{# ... #}
рдПрдХ рдФрд░ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди рдЕрд▓рдЧ-рдЕрд▓рдЧ рдлрд╝рд╛рдЗрд▓реЛрдВ рдореЗрдВ рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЦрд╛рд▓ рдХреА рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдмрдирд╛рдиреЗ рдФрд░ рдХреЗрд╡рд▓ рдПрдХ рдмреНрд░рд╛рдВрдбреЗрдб рдкреГрд╖реНрда рдкрд░ рдХрдиреЗрдХреНрдЯ рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдЗрд╕рд▓рд┐рдП рд╣рдо рдореБрдЦреНрдп рд╢реИрд▓рд┐рдпреЛрдВ рдХреЛ рдХрдЪрд░реЗ рдХреЗ рд╕рд╛рде рдирд╣реАрдВ рд░рдЦреЗрдВрдЧреЗ, рдЬрд┐рд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдХреБрдЫ рдкреГрд╖реНрдареЛрдВ рдкрд░ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред рдЕрдЧрд░ рдХрд┐рд╕реА рдХреЛ рджрд┐рд▓рдЪрд╕реНрдкреА рд╣реИ, рддреЛ рдореИрдВ рдЖрдкрдХреЛ рдПрдХ рдЕрд▓рдЧ рд▓реЗрдЦ рдореЗрдВ рдмрддрд╛ рд╕рдХрддрд╛ рд╣реВрдВ рдХрд┐ рдмрдбрд╝реА рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдЦрд╛рд▓ рдХреЛ рдПрдХ рд╕рд╛рде рдФрд░ рдЕрд▓рдЧ рд╕реЗ рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЧрд▓реНрдк рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛рдПред рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдкрд░рд┐рдпреЛрдЬрдирд╛ рдкрд░ 300 рд╕реЗ рдЕрдзрд┐рдХ рдРрд╕реА рдЦрд╛рд▓реЗрдВ рд╣реИрдВред