Saya ingin menggunakan {% block%} yang sama dua kali dalam template Django yang sama. Saya ingin blok ini muncul lebih dari satu kali di templat dasar saya:
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
Dan kemudian memperluasnya:
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
Saya akan mendapatkan pengecualian, karena Django ingin blok hanya muncul sekali:
TemplateSyntaxError di /
tag 'blokir' dengan nama 'judul' muncul lebih dari satu kali
Solusi cepat dan kotor akan menduplikasi judul blok ke title1 dan title2 :
# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}
Tapi ini merupakan pelanggaran prinsip KERING . Ini akan sangat sulit karena saya memiliki banyak template yang mewarisi, dan juga karena saya tidak ingin pergi ke neraka ;-)
Apakah ada trik atau penyelesaian masalah ini? Bagaimana saya bisa mengulangi blok yang sama di template saya, tanpa menduplikasi semua kode?
django
django-templates
dry
David Arcos
sumber
sumber
Jawaban:
Saya pikir bahwa penggunaan pengolah konteks dalam hal ini adalah pembunuhan yang berlebihan. Anda dapat dengan mudah melakukan ini:
lalu:
dan seterusnya ... Sepertinya kompatibel KERING.
sumber
h1
konten di dalam blok yang mendefinisikantitle
. Atau blok yang mendefinisikan bagian darititle
.Gunakan plugin macro template Django:
https://gist.github.com/1715202 (django> = 1.4)
atau
http://www.djangosnippets.org/snippets/363/ (django <1.4)
django> = 1.4
dan
django <1.4
dan
sumber
Anda mungkin tidak benar-benar ingin menggunakan blok melainkan hanya menggunakan variabel:
Anda kemudian mengatur judul melalui konteksnya.
sumber
Inilah cara yang saya temukan ketika mencoba melakukan hal yang sama sendiri:
Sayangnya, membutuhkan file tambahan, tetapi tidak mengharuskan Anda meneruskan judul dari tampilan.
sumber
<tr>
barisannya agak rumit.Anda bisa menggunakan
{% include subtemplate.html %}
lebih dari satu kali. itu tidak sama dengan balok, tetapi melakukan trik.sumber
include
ini lebih lambat daripadablock
. docs.djangoproject.com/en/1.10/topics/performance/…Ada beberapa diskusi di sini: http://code.djangoproject.com/ticket/4529 Jelas tim inti Django menolak tiket ini karena mereka pikir ini bukan skenario yang umum digunakan, namun saya tidak setuju.
blok berulang adalah implementasi sederhana dan bersih untuk ini: https://github.com/SmileyChris/django-repeatblock
makro template adalah satu lagi, namun penulis menyebutkan itu tidak diuji dengan hati-hati: http://www.djangosnippets.org/snippets/363/
Saya menggunakan repeatblock.
sumber
Sebagai pembaruan bagi siapa pun yang menemukan ini, saya telah mengambil cuplikan yang disebutkan di atas dan mengubahnya menjadi pustaka tag templat, Django-macro, membuat makro lebih kuat dan juga menerapkan pola blok berulang secara eksplisit: Django-makro .
sumber
Berikut ini adalah solusi ringan mirip dengan jawaban tag templat di atas
do_set
dando_get
. Django memungkinkan Anda untuk melewatkan seluruh konteks templat ke dalam sebuah tag yang memungkinkan Anda untuk mendefinisikan variabel global.base.html:
page.html:
tag khusus (ada idenya di sini: https://stackoverflow.com/a/33564990/2747924 ):
Juga jangan lupa pada
{% load %}
tag khusus Anda atau tambahkan ke daftar opsi bawaan templat sehingga Anda tidak perlu memuatnya di setiap templat. Satu-satunya batasan untuk pendekatan ini adalah{% define %}
harus dipanggil dari dalam tag blok karena template anak hanya membuat tag blok yang cocok dengan tag induk. Tidak yakin apakah ada jalan keluarnya. Pastikan jugadefine
panggilan datang sebelum Anda mencoba menggunakannya dengan jelas.sumber
Berdasarkan saran Van Gale, Anda bisa membuat get and set tag dengan menambahkan yang berikut ke file templatetags.py Anda:
Kemudian atur nilai dalam satu templat melalui
{% set foo %}put data here{% endset %}
dan tempel templat-templat{% get foo %}
lain.sumber
Saya juga menemukan kebutuhan yang sama untuk pengulangan {% block%} di file templat saya. Masalahnya adalah bahwa saya ingin Django {% block%} untuk digunakan dalam kedua kasus kondisional Django, dan saya ingin {% block%} menjadi terlalu bisa ditulis oleh file-file berikutnya yang dapat memperpanjang file saat ini. (Jadi dalam hal ini, apa yang saya inginkan jelas lebih merupakan sebuah blok daripada variabel karena saya tidak secara teknis menggunakannya kembali, itu hanya muncul di kedua ujung kondisi.
Masalah:
Kode template Django berikut akan menghasilkan Kesalahan Sintaksis Templat, tetapi saya pikir itu adalah "keinginan" yang sah untuk memiliki {% block%} yang digunakan kembali dalam kondisi (IE, mengapa parser Django memvalidasi sintaks pada KEDUA ujung kondisional, bukankah itu hanya memvalidasi kondisi KEBENARAN?)
Solusinya:
Anda dapat menggunakan {% include%} untuk memasukkan {% block%} lebih dari satu syarat. Ini bekerja untuk saya karena pemeriksa sintaksis Django hanya menyertakan TRUTHY {% include%}. Lihat hasilnya di bawah ini:
sumber
Saya menggunakan jawaban ini untuk menjaga semuanya tetap kering.
sumber
Ada dua solusi mudah untuk ini.
Cara termudah adalah menempatkan judul Anda ke dalam variabel konteks. Anda akan mengatur variabel konteks dalam tampilan Anda.
Jika Anda menggunakan sesuatu seperti tampilan umum dan tidak memiliki views.py untuk gambar, kucing, dll. Maka Anda dapat menggunakan tag templat kustom yang menetapkan variabel dalam konteks .
Melewati rute ini akan memungkinkan Anda melakukan sesuatu seperti:
Kemudian di base.html Anda:
sumber
Any variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.
Jawaban yang dipilih menyinggung solusi yang mudah untuk membungkus satu tag di dalam yang lain dalam template anak untuk memberikan keduanya nilai yang sama. Saya menggunakan ini untuk gambar sosial seperti itu.
Template anak:
Kemudian di induk
base.html
:sumber
Dalam ranting Anda dapat membuat ini seperti:
sumber