Django-Vorlagen: Einschließen und Erweitern

108

Ich möchte den gleichen Inhalt in 2 verschiedenen Basisdateien bereitstellen.

Also versuche ich das zu tun:

page1.html:

{% extends "base1.html" %}
{% include "commondata.html" %}

page2.html:

{% extends "base2.html" %} 
{% include "commondata.html" %}

Das Problem ist, dass ich nicht beide Extends und Include verwenden kann. Gibt es eine Möglichkeit, das zu tun? Und wenn nicht, wie kann ich das oben genannte erreichen?

commondata.html überschreibt einen Block, der sowohl in base1.html als auch in base2.html angegeben ist

Dies dient dazu, dieselbe Seite sowohl im PDF- als auch im HTML-Format bereitzustellen, wobei die Formatierung geringfügig abweicht. Die obige Frage vereinfacht jedoch, was ich versuche, wenn ich eine Antwort darauf bekomme, wird dies mein Problem lösen.

Netzbürger
quelle

Antworten:

110

Wenn Sie das Tag "Erweiterte Vorlage" verwenden, sagen Sie, dass die aktuelle Vorlage eine andere erweitert - dass es sich um eine untergeordnete Vorlage handelt, die von einer übergeordneten Vorlage abhängt. Django überprüft Ihre untergeordnete Vorlage und verwendet deren Inhalt, um die übergeordnete Vorlage zu füllen.

Alles, was Sie in einer untergeordneten Vorlage verwenden möchten, sollte sich in Blöcken befinden, mit denen Django das übergeordnete Element auffüllt. Wenn Sie eine include-Anweisung in dieser untergeordneten Vorlage verwenden möchten, müssen Sie sie in einen Block einfügen, damit Django einen Sinn daraus ergibt. Sonst macht es einfach keinen Sinn und Django weiß nicht, was er damit anfangen soll.

Die Django-Dokumentation enthält einige wirklich gute Beispiele für die Verwendung von Blöcken zum Ersetzen von Blöcken in der übergeordneten Vorlage.

https://docs.djangoproject.com/de/dev/ref/templates/language/#template-inheritance

Matt Howell
quelle
1
In meiner commondata.html ist der Block definiert. Aber es ersetzt nicht den Block des übergeordneten Tempaltes ... Wenn ich anstelle eines Includes die genauen Daten zweimal sowohl in page1.html als auch in page2.html schreibe, funktioniert es natürlich. Aber ich möchte diese Gemeinsamkeit in commondata.html herausrechnen.
Net Citizen
Scheint zu funktionieren, ich erinnere mich, dass ich das versucht habe, aber ich muss zu der Zeit einen Tippfehler oder etwas anderes gehabt haben, was dazu geführt hat, dass es nicht funktioniert hat.
Net Citizen
1
In meiner Antwort unten erfahren Sie, warum es beim ersten Mal bei mir nicht funktioniert hat. Ich werde Ihnen jedoch die akzeptierte Antwort überlassen, da Sie die von mir gestellte Frage richtig beantwortet haben.
Net Citizen
80

Aus Django-Dokumenten:

Das Include-Tag sollte als Implementierung von "Diese Untervorlage rendern und den HTML-Code einschließen" und nicht als "Diese Untervorlage analysieren und ihren Inhalt so einschließen, als ob sie Teil der übergeordneten Vorlage wäre" betrachtet werden. Dies bedeutet, dass zwischen den enthaltenen Vorlagen kein gemeinsamer Status besteht. Jedes Include ist ein völlig unabhängiger Renderprozess.

Django greift also nicht nach Blöcken aus Ihrer commondata.html und weiß nicht, was mit gerendertem HTML außerhalb von Blöcken zu tun ist.

Podshumok
quelle
32

Dies sollte den Trick für Sie tun: Fügen Sie das include-Tag in einen Blockabschnitt ein.

page1.html:

{% extends "base1.html" %}

{% block foo %}
   {% include "commondata.html" %}
{% endblock %}

page2.html:

{% extends "base2.html" %}

{% block bar %}
   {% include "commondata.html" %}
{% endblock %}
Pavel Černý
quelle
1
Perfekt. Funktioniert bei mir.
Trupti M Panchal
13

Weitere Informationen darüber, warum es bei mir nicht funktioniert hat, falls es zukünftigen Menschen hilft:

Der Grund, warum es nicht funktioniert hat, ist, dass {% include%} in Django keine Sonderzeichen wie ausgefallene Apostrophe mag. Die Vorlagendaten, die ich einschließen wollte, wurden aus Word eingefügt. Ich musste alle diese Sonderzeichen manuell entfernen und dann erfolgreich einschließen.

Netzbürger
quelle
3

Sie können keine Blöcke aus einer enthaltenen Datei in eine untergeordnete Vorlage ziehen, um die Blöcke der übergeordneten Vorlage zu überschreiben. Sie können jedoch ein übergeordnetes Element in einer Variablen angeben und die Basisvorlage im Kontext angeben.

Aus der Dokumentation :

{% erweitert Variable%} verwendet den Wert der Variablen. Wenn die Variable eine Zeichenfolge ergibt, verwendet Django diese Zeichenfolge als Namen der übergeordneten Vorlage. Wenn die Variable zu einem Vorlagenobjekt ausgewertet wird, verwendet Django dieses Objekt als übergeordnete Vorlage.

Anstatt "page1.html" und "page2.html" zu trennen, setzen Sie {% extends base_template %}oben in "commondata.html". Definieren Sie dann in Ihrer Ansicht base_templateentweder "base1.html" oder "base2.html".

Schmirgel
quelle
2

Als Referenz für zukünftige Personen hinzugefügt, die dies über Google finden: In solchen Fällen sollten Sie sich das von der Mezzanine-Bibliothek bereitgestellte Tag {% overextend%} ansehen.

Ted
quelle
1

Edit 10th Dec 2015 : Wie in den Kommentaren erwähnt, ist ssi seit Version 1.8 veraltet. Laut Dokumentation:

Dieses Tag ist veraltet und wird in Django 1.10 entfernt. Verwenden Sie stattdessen das Include-Tag.


Meiner Meinung nach ist die richtige (beste) Antwort auf diese Frage die von podshumok , da sie erklärt, warum das Verhalten von include zusammen mit der Vererbung verwendet wird.

Ich war jedoch etwas überrascht, dass niemand das ssi- Tag erwähnte, das vom Django-Template-System bereitgestellt wird, das speziell für Inline einschließlich eines externen Textes entwickelt wurde . Inline bedeutet hier, dass der externe Text nicht interpretiert, analysiert oder interpoliert wird, sondern einfach in die aufrufende Vorlage "kopiert" wird.

Weitere Informationen finden Sie in der Dokumentation (überprüfen Sie Ihre entsprechende Version von Django in der Auswahl unten rechts auf der Seite).

https://docs.djangoproject.com/de/dev/ref/templates/builtins/#ssi

Aus der Dokumentation:

ssi
Outputs the contents of a given file into the page.
Like a simple include tag, {% ssi %} includes the contents of another file
 which must be specified using an absolute path  in the current page

Beachten Sie auch die Sicherheitsauswirkungen dieser Technik und die erforderliche ALLOWED_INCLUDE_ROOTS-Definition, die zu Ihren Einstellungsdateien hinzugefügt werden muss.

jose.angel.jimenez
quelle
1
Beachten Sie, dass ab 1.8 ssi zugunsten von Include veraltet ist. https://docs.djangoproject.com/de/1.8/ref/templates/builtins/#std:templatetag-include
Tim S.