Python Django HTML Template Inheritance Frage

Falc410

Vice Admiral
Registriert
Juni 2006
Beiträge
6.660
Ich habe ein Problem, dass ich immer nur von einem Template erben kann, zumindest ist in der Doku nichts zu mehrfach-vererbung angegeben.

Ich habe ein Base Template, in das wollte ich eigentlich <head> reinnehmen aber auch teilweise Sachen aus <body>, also z.B. meinen Header (Menu-Band zur Navigation) und meinen Footer). Der eigentliche Content wird dann in den Subpages dargestellt, die extenden dann alle von meinem Base Template.

Jetzt habe ich aber das Problem, dass ich bei meinem <body> Tag noch ein class Attribut fuer manche Subpages hinzufuegen will, bei anderen aber nicht.

Also war meine Idee das ich ein Base Template habe, dann zwei Templates einmal mainpage und subpage, welche beide von base erben. z.B. so:
Code:
{% extends 'base.html' %}

{% block body_class %}
    <body class="subpage">
{% block body_block %}{% endblock %}
</body>

{% endblock %}
Nun kann ich zwar meinen Footer und Header in diese Templates reinziehen, aber dann hab ich die Info ja immer noch doppelt und muss es zweimal aendern ggf.

Wie kann ich schaffen, dass ich den <body> Tag dynamisch mache, aber ansonsten statischen HTML Code so weit nach in der Vererbungskette ziehe, das ich es eben nur einmal vorliegen habe?

Hoffe das war einigermassen verstaendlich :)
 
Du kannst nur von einem Template vererben.

Dafür kannst du aber so viele Vererbung Templates machen wie du willst. Sprich in die base.html bzw. index.html packst du alles rein.

Danach kannst du mit bodyohneclass.html das Template ohne Klasse auswählen und per bodymitclass.html das Template mit Klasse.

bodyohneclass.html:

Code:
{% extends 'base.html' %}
{% block body_class %}
     <body>
         <placholder hier rein>
     </body>
{% block body_block %}

bodymitclass.html:

Code:
{% extends 'base.html' %}
{% block body_class %}
     <body class="whatever and ever">
         <placholder hier rein>
     </body>
{% block body_block %}

Alternativ kannst du auch mit if-Abragen arbeiten:

Code:
{% ifequal request.current_page.get_title 'Dein Seiten name hier rein'  %}
     <body>
          
     </body>
{% endifequal %}

bzw.:

Code:
{% ifequal request.current_page.get_title 'Dein Seiten name hier rein'  %}
     <body class="blub">
          
     </body>
{% endifequal %}
 
So wie du es im ersten Beispiel beschreibst habe ich ja gemacht. Aber dann müssen eben Teile des <body> die identisch sind bei beiden Templates drin stehen.

Das mit der if-Abfrage ist auch unschön und kein gutes Design.
Normalerweise hat man ja in der base.html
Code:
...
<head>
<script>Javascript + css</script>
...
</head>
<body>
<!-- statischer html code z.b. header-->
{% block body_block %}{% endblock %}
<!-- statischer html code z.b. footer-->
</body>
</html>

Diese beiden statischen Blöcke möchte ich natürlich nur 1x haben damit ich diese nicht mehrmals pflegen muss. Diese müssen aber innerhalb des <body> Tags sein
 
Ahhhh ok nun verstehe ich was du willst :)

Code:
<body class="{% block body_class %}{% endblock %}">

Code:
{% block body_class %}klassen-name-hier-rein{% endblock %}

Ich würde das ganze aber anders lösen und zwar per JQuery.

Code:
$( "body" ).addClass( "myClass" );

bzw.

Code:
$( "#body" ).addClass( "myClass" );

Schön im Head jquery laden, im Base.html ein block erstellen für JS (ganz unten vor dem </body>) und im neuen Template einen der JQuery Befehle nutzen.
 
Ah ich wusste nicht dass ich das nachträglich noch ändern kann. Perfekt, danke dir.

Zwei kleine Fragen habe ich noch.
- Wo ist der Unterschied zwischen "body" und "#body" ?
- Macht es wirklich einen Unterschied ob ich mein Javascript erst am Ende der Seite oder bereits im <head> Teil lade?
 
Falc410 schrieb:
- Wo ist der Unterschied zwischen "body" und "#body" ?

body greift auf den Body zu.

#body wäre wenn du dem body zusätzlich noch die ID "body" verpasst hättest. Ich mach das gerne einfach weil es mMn sauberer ist auf klassen und/oder IDs zuzugreifen.

Falc410 schrieb:
- Macht es wirklich einen Unterschied ob ich mein Javascript erst am Ende der Seite oder bereits im <head> Teil lade?

Ja tut es. Webseiten werden von oben nach unten geladen sprich oben in den Head gehören die Framework Daten rein also jquery, jquery-ui etc... Wenn du nun den code unten einfügst werden dieser 100% ausgeführt. Wenn du z.B.

Code:
$( "body" ).addClass( "myClass" );

im Head ausführst und die Seite noch nicht geladen wurde feuert das Script nicht da es noch kein body gab um etwas hinzuzufügen. Deswegen gilt statische sachen oben einbauen alles was nur im Ansatz Dynamisch ist unten vor dem </body> tag.
 
Vielen Dank für die tolle Erklärung! Dann baue ich das gleich mal um.
 
Hinzu kommt dass Javascripts im Gegensatz zu bildern synchron und nicht asynchron geladen werden.

Wenn der Browser also beim parsen auf Javascripts stößt, dann lädt er diese erst vollständig und initialisiert sie, bevor der Rest des HTML geparst wird. Eigentlich sollten deshalb auch die Frameworks erst vor dem close des Body-Tags hinzugefügt werden, da nun der User wenigstens schon "was sieht". Die Seitenladezeit "erscheint" daher viel kürzer.
 
Ja tut es. Webseiten werden von oben nach unten geladen sprich oben in den Head gehören die Framework Daten rein also jquery, jquery-ui etc... Wenn du nun den code unten einfügst werden dieser 100% ausgeführt. Wenn du z.B.

Deine zwei Frameworks blockieren den Seitenaufbau. Das ist zu dem Zeitpunkt total unnötig, da sie erstmal geladen und dann geparst werden müssen. Dadurch das die beiden sowieso meist mit dem DOM arbeiten, sollten diese am Ende des Bodys platziert werden. Das hat dann den Vorteil das andere Resourcen wie Bilder eher fertig sind.

Oder noch schlechter wenn bspw. dein CDN ausfällt oder Probleme hat, dann hast du für eine bestimmte Zeit zwei Verbindungen weniger.

Hinzu kommt dass Javascripts im Gegensatz zu bildern synchron und nicht asynchron geladen werden.

Im Normalfall ja, außer das Async Attribut oder ein Scriptloader wird verwendet.
 
Zurück
Oben