template django: termasuk dan meluas

108

Saya ingin memberikan konten yang sama di dalam 2 file dasar yang berbeda.

Jadi saya mencoba melakukan ini:

halaman1.html:

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

halaman2.html:

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

Masalahnya adalah saya tidak bisa menggunakan keduanya meluas dan menyertakan. Apakah ada cara untuk melakukannya? Dan jika tidak, bagaimana saya bisa mencapai hal di atas?

commondata.html menimpa blok yang ditentukan di base1.html dan base2.html

Tujuannya adalah untuk menyediakan halaman yang sama dalam format pdf dan html, yang formatnya sedikit berbeda. Pertanyaan di atas meskipun menyederhanakan apa yang saya coba lakukan jadi jika saya bisa mendapatkan jawaban itu akan menyelesaikan masalah saya.

Warga Net
sumber

Jawaban:

110

Saat Anda menggunakan tag templat yang diperluas, Anda mengatakan bahwa templat saat ini meluas yang lain - itu adalah templat anak, bergantung pada templat induk. Django akan melihat templat anak Anda dan menggunakan isinya untuk mengisi induk.

Segala sesuatu yang ingin Anda gunakan dalam templat anak harus berada di dalam blok, yang digunakan Django untuk mengisi induknya. Jika Anda ingin menggunakan pernyataan include di templat anak itu, Anda harus meletakkannya di dalam blok, agar Django memahaminya. Kalau tidak, itu tidak masuk akal dan Django tidak tahu apa yang harus dilakukan dengannya.

Dokumentasi Django mempunyai beberapa contoh yang sangat bagus dalam menggunakan blok untuk menggantikan blok dalam cetakan induk.

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

Matt Howell
sumber
1
commondata.html saya memiliki blok yang ditentukan di dalamnya. Tetapi itu tidak menggantikan blok induk tempalte ... Jika alih-alih melakukan penyertaan saya menulis data yang tepat dua kali di kedua halaman1.html dan halaman2.html maka tentu saja itu berhasil. Tapi saya ingin memfaktorkan kesamaan itu menjadi commondata.html.
Warga Negara Net
Sepertinya berhasil, saya ingat mencoba ini tetapi saya pasti mengalami kesalahan ketik atau sesuatu pada saat itu yang menyebabkannya tidak berfungsi.
Warga Negara Net
1
lihat jawaban saya di bawah untuk mengapa itu tidak berhasil untuk saya pertama kali, saya akan meninggalkan Anda dengan jawaban yang diterima karena Anda menjawab pertanyaan yang saya ajukan dengan benar.
Warga Negara Net
80

Dari dokumen Django:

Tag include harus dianggap sebagai implementasi dari "render subtemplate ini dan sertakan HTML", bukan sebagai "parse subtemplate ini dan sertakan isinya seolah-olah itu adalah bagian dari induk". Artinya, tidak ada status bersama antara template yang disertakan - setiap penyertaan adalah proses rendering yang sepenuhnya independen.

Jadi Django tidak mengambil blok apa pun dari commondata.html Anda dan tidak tahu apa yang harus dilakukan dengan html yang dirender di luar blok.

podshumok.dll
sumber
32

Ini akan melakukan trik untuk Anda: letakkan tag include di dalam bagian blok.

halaman1.html:

{% extends "base1.html" %}

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

halaman2.html:

{% extends "base2.html" %}

{% block bar %}
   {% include "commondata.html" %}
{% endblock %}
Pavel Černý
sumber
1
Sempurna. Bekerja untuk saya.
Trupti M Panchal
13

Info lebih lanjut tentang mengapa itu tidak berhasil untuk saya seandainya itu membantu orang di masa depan:

Alasan mengapa tidak berhasil adalah karena {% include%} dalam django tidak menyukai karakter khusus seperti apostrof yang mewah. Data templat yang saya coba masukkan ditempelkan dari kata. Saya harus secara manual menghapus semua karakter khusus ini dan kemudian berhasil dimasukkan.

Warga Net
sumber
3

Anda tidak dapat menarik blok dari file yang disertakan ke dalam template anak untuk mengganti blok template induk. Namun, Anda dapat menentukan induk dalam variabel dan memiliki templat dasar yang ditentukan dalam konteks.

Dari dokumentasi :

{% extends variable%} menggunakan nilai variabel. Jika variabel mengevaluasi ke string, Django akan menggunakan string itu sebagai nama templat induk. Jika variabel mengevaluasi ke objek Templat, Django akan menggunakan objek itu sebagai templat induk.

Alih-alih memisahkan "halaman1.html" dan "halaman2.html", letakkan {% extends base_template %}di bagian atas "commondata.html". Dan kemudian dalam tampilan Anda, tentukan base_templatemenjadi "base1.html" atau "base2.html".

amril
sumber
2

Ditambahkan untuk referensi bagi orang-orang mendatang yang menemukan ini melalui google: Anda mungkin ingin melihat tag {% overextend%} yang disediakan oleh perpustakaan mezanin untuk kasus seperti ini.

Ted
sumber
1

Edit 10 Des 2015 : Seperti yang ditunjukkan di komentar, ssi tidak digunakan lagi sejak versi 1.8. Menurut dokumentasi:

Tag ini tidak digunakan lagi dan akan dihapus di Django 1.10. Gunakan tag include sebagai gantinya.


Menurut saya, jawaban yang tepat (terbaik) untuk pertanyaan ini adalah dari podshumok , karena menjelaskan mengapa perilaku include saat digunakan bersama dengan pewarisan.

Namun, saya agak terkejut bahwa tidak ada yang menyebutkan tag ssi yang disediakan oleh sistem template Django, yang secara khusus dirancang untuk sebaris termasuk bagian teks eksternal . Di sini, inline berarti teks eksternal tidak akan diinterpretasikan, diurai, atau diinterpolasi, tetapi hanya "disalin" di dalam template pemanggil.

Mohon, rujuk ke dokumentasi untuk detil lebih lanjut (pastikan untuk memeriksa versi Django Anda yang sesuai di selektor di bagian kanan bawah halaman).

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

Dari dokumentasi:

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

Waspadalah juga terhadap implikasi keamanan dari teknik ini dan juga definisi ALLOWED_INCLUDE_ROOTS yang diperlukan, yang harus ditambahkan ke file pengaturan Anda.

jose.angel.jimenez
sumber
1
Catatan, mulai 1.8, ssi tidak lagi digunakan untuk mendukung Include. https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include
Tim S.