Gibt es im Allgemeinen einen "guten" Weg, um diese Funktionalität zu erreichen? Ich habe über das "use" -Tag gelesen, das bisher die beste Option zu sein scheint, aber ich mag es immer noch nicht, dass ich keine HTML-Dateien von außen einführen kann, sondern nur Blöcke.
Ich werde im folgenden Beispiel das 'include' -Tag verwenden, um die Absicht zu veranschaulichen, die ich zu beschreiben versuche.
#base.html.twig
{% include 'elements/header.html.twig' %}
{% block content %}{% endblock %}
{% include 'elements/footer.html.twig' %}
#header.html.twig
<h1>This is my header</h1>
{% block page_title %} Default Page Title {% endblock %}
#index.html.twig
{% extends 'layouts/base.html.twig' %}
{# I want to be able to do this somehow #}
{% block page_title %} This is my overridden page title {% endblock %}
{% block content %} here is the index page content {% endblock %}
Ich habe eine Lösung gefunden. Verwenden Sie die Funktion block (), um den Blockinhalt des untergeordneten Objekts abzurufen und als Variable in der include-Anweisung an header.html.twig zu übergeben:
#base.html.twig
{% include 'elements/header.html.twig' with {page_title: block('page_title')} %}
{% block content %}{% endblock %}
{% include 'elements/footer.html.twig' %}
#header.html.twig
<h1>This is my header</h1>
{% if page_title is empty %}
Default Page Title
{% else %}
{{ page_title }}
{% endif %}
#index.html.twig
{% extends 'layouts/base.html.twig' %}
{% block page_title %} This is my overridden page title {% endblock %}
{% block content %} here is the index page content {% endblock %}
Ich habe eine gute und echte -Lösung gefunden, die die -Dokumentation für das embed -Tag liest. Ich verwende Twig 2.0 in Symfony 4.
#templates/base.html.twig
{% block navbar %}
<nav>
{% block menu %}
{% include '_menu' %}
{% endblock menu %}
</nav>
{% endblock navbar %}
{% block content %}
{# several blocks defined #}
{% block footer '' %}
{% endblock content %}
#templates/_menu.html.twig
<ul>
{% block sub_app_menu_itens %}
<li>Main App Menu Item</li>
{% endblock sub_app_menu_itens %}
<li>Menu item</li>
<li>Another menu item</li>
<li>Yet another menu item</li>
</ul>
Mit dem obigen Code ist beim Erstellen meines index.html.twig der einzige Code, der zum Anzeigen der Standardeinstellungen erforderlich ist
#templates/index.html.twig
{% extends 'base.html.twig' %}
und überschriebene Blöcke überschreiben . Wenn ich jedoch eine andere Seite erstellen muss, die diese Skelette verwendet, wenn ich versuche, block sub_app_menu_itens in einer anderen enthaltenen _partial-Vorlage zu überschreiben, funktioniert dies nicht. <li>Main App Menu Item</li>
wird immer angezeigt und niemals überschrieben (Code oben)
#templates/subapp/index.html.twig
{% extends 'base.html.twig' %}
{% block title %}{{ 'agencia.homepage'|trans }}{% endblock %}
{% block menu %}
{% include 'subapp/_menu.html.twig' %}
{% endblock menu %}
{% block user_content %}Content Here{% endblock %}
#templates/subapp/_menu.html.twig
{% extends '_menu.html.twig' %}
{% block sub_app_menu_itens %}
<li>SubApp Menu Item</li>
{% endblock sub_app_menu_itens %}
<li>SubApp Menu Item</li>
wird nie angezeigt. Habe eine Menge Dinge wie extends
und sogar Bedingungen ohne Glück versucht.
Das embed -Tag löst die zu überschreibenden untergeordneten Teilvorlagenblöcke auf.
#templates/subapp/index.html.twig
{% block menu %}
{% embed '_menu.html.twig' %}
{% block sub_app_menu_itens %}
{% include 'subapp/_menu.html.twig' %}
{% endblock sub_app_menu_itens %}
{% endembed %}
{% endblock menu %}
Und die Vereinfachung der _partial-Vorlage, um nur die HTML-Datei zu benötigen
#templates/subapp/_menu.html.twig
<li>SubApp Menu Item</li>
Jetzt wird <li>SubApp Menu Item</li>
an der richtigen Stelle der _menu-Vorlage angezeigt.
Wenn Sie in Ebenen denken, funktioniert eine include
wie eine untergeordnete Ebene (analysiert) und alle Dinge werden nur auf derselben Ebene überschrieben, sodass include
das Überschreiben in einem anderen Include nicht zulässt. Stattdessen werden embed
-Vorlagen auf die gleiche Ebene gebracht (nicht analysiert), sodass Sie die Dinge überschreiben können.
Es kann gemacht werden. Hier ist meine Lösung für das Problem, indem Sie eine Variable an die Ansicht übergeben.
#layout.twig
{% if sidebar is empty %}
This is the default sidebar text.
{% else %}
{% block sidebar %}{% endblock %}
{% endif %}
{% block content %}{% endblock %}
#index.twig
{% extends "layout.twig" %}
{% block sidebar %}
This is the sidebar. It will override the default text.
{% endblock %}
{% block content %}
This is the content.
{% endblock %}
#index.php (SlimPHP)
$app->render('index.twig', ['sidebar' => true]);
Da ich SlimPHP benutze, benutze ich sidebar
an die Ansicht. Dies kann durch die Verwendung verschiedener Variablen, die an die Ansicht übergeben werden, erweitert werden, sodass Sie sidebar1
, sidebar2
usw. auswählen können.
Ich bekam es mit einem sehr einfachen Hack zu arbeiten:
Im Prinzip verhält es sich so, weil es ohne einen {% extends "foo.html.twig" %}
die Blöcke nicht versteht und sie einfach an Ort und Stelle rendert.
Also lass uns erweitern ... nichts:
{% extends "nothing.html.twig" %}
Dieses Nichts ist wirklich nur ein Block:
# nothing.html.twig
{% block main %}
{% endblock %}
Die einzige Sache ist, dass Sie alles in einen Block einwickeln müssen, diesen gefälschten "Haupt" -Block.