Saya baru saja membuat webapp kecil pertama saya di Django dan saya menyukainya. Saya akan mulai mengubah situs PHP produksi lama menjadi django dan sebagai bagian dari templatnya, terdapat bilah navigasi.
Di PHP, saya memeriksa setiap URL opsi nav terhadap URL saat ini, di kode template dan menerapkan kelas CSS jika mereka berbaris. Ini sangat berantakan.
Apakah ada yang lebih baik untuk django atau cara yang baik untuk menangani kode di templat?
Untuk memulai, bagaimana saya mendapatkan URL saat ini?
django
navigation
Oli
sumber
sumber
<a href="{% url "view:name" %}" {% active_class "view:name" %}>
. Anda dapat menggunakannya untuk menghasilkan hanya satu" active"
nilai (dengan melewatiFalse
sebagai argumen kedua untuk tag) untuk append ke atribut kelas yang ada, tetapi untuk sebagian besar link nav bahwa contoh adalah apa yang saya gunakan.Jawaban:
Saya menggunakan warisan template untuk menyesuaikan navigasi. Sebagai contoh:
base.html
about.html
sumber
<ul id="nav">....</ul>
ke file yang berbeda, katakanlah tabs.html. Jadi sekarang base.html berisi{%block nav%}{%include "tabs.html"%}{%endblock%}
dan kemudian sorotan dari tab aktif berhenti bekerja (di about.html di atas). Apakah saya melewatkan sesuatu?include
tag. Lihat catatan yang disertakan dalam dokumen: docs.djangoproject.com/en/dev/ref/templates/builtins/#include Dalam kasus Anda, pada saat Anda mencoba mengganti template dasarabout.html
, saya rasa Anda sudah sudah mendapat blok HTML yang telah dirender, daripada blok cetakan Django menunggu untuk diproses.Anda tidak perlu jika untuk melakukan itu, lihat kode berikut:
tags.py
urls.py
base.html
itu dia. untuk detail implementasi, lihat:
gnuvince.wordpress.com
110j.wordpress.com
sumber
django.core.context_processors.request
ke AndaTEMPLATE_CONTEXT_PROCESSORS
disettings.py
mysite.com
(sebagai rumah) danmysite.com/blog
, karena jalur akan ditampilkan sebagai/
dan/blog/
(masing-masing) menghasilkan kecocokan untuk yang pertama setiap kali. Jika Anda tidak menggunakan/
sebagai pendaratan, itu mungkin baik-baik saja jika tidak saya hanya menggunakanreturn 'active' if pattern == request.path else ''
(saya belum melihat masalah dengan ini, tetapi saya hanya mengatur menggunakan ini).Saya menyukai kebersihan 110j di atas jadi saya mengambil sebagian besar dan memfaktorkan ulang untuk menyelesaikan 3 masalah yang saya miliki dengannya:
Ini dia:
tags.py:
urls.py:
base.html:
sumber
Saya penulis garis silsilah django yang saya tulis secara khusus untuk menjawab pertanyaan ini: D
Saya menjadi kesal menggunakan metode jpwatts (yang dapat diterima) dalam proyek saya sendiri dan mendapatkan inspirasi dari jawaban 110j. Silsilah terlihat seperti ini:
ancestor
hanya diganti dengan "aktif" jika argumennya cocok dengan awal URL halaman saat ini.Argumen variabel, dan
{% url %}
resolusi terbalik tipe penuh , juga didukung. Saya menaburkan beberapa opsi konfigurasi dan menyempurnakannya sedikit dan mengemasnya untuk digunakan semua orang.Jika ada yang tertarik, baca lebih lanjut di:
>> github.com/marcuswhybrow/django-lineage
sumber
Sejak Django 1.5 :
Jadi jika Anda menggunakan tampilan seperti itu, Anda dapat menambahkan sesuatu
breadcrumbs
seperti bidang tingkat kelas dan menggunakannya di templat Anda.Contoh kode tampilan:
Di template Anda, Anda bisa menggunakannya dengan cara ini:
Jika Anda ingin "menyorot" item navigasi induk, Anda perlu memperluas
breadcrumbs
daftar:... dan di template Anda:
Ini adalah solusi yang mudah dan bersih dan bekerja cukup baik dengan navigasi bersarang.
sumber
.active
?breadcrumbs
jika Anda mau. Tapi Anda benar - contoh saya bukanlah yang terbaik.Anda bisa menerapkan kelas atau id ke elemen tubuh halaman, daripada ke item navigasi tertentu.
HTML:
CSS:
sumber
Saya melakukannya seperti ini:
dan kemudian yang harus saya lakukan adalah menambahkan tampilan
{'active_tab': 'statistics'}
ke kamus konteks saya.Jika Anda menggunakan
RequestContext
Anda bisa mendapatkan jalur saat ini di template Anda sebagai:Dan menurut pandangan Anda:
sumber
Saya mengambil kode dari nivhab di atas dan menghapus beberapa kejanggalan dan membuatnya menjadi templatetag yang bersih, memodifikasinya sehingga / akun / edit / akan tetap membuat / akun / tab aktif.
sumber
Ini hanyalah varian dari solusi css yang diusulkan oleh Toba di atas:
Sertakan berikut ini di template dasar Anda:
Kemudian di template Anda yang memperluas penggunaan dasar:
Anda kemudian dapat menggunakan css untuk menyorot area saat ini berdasarkan tag tubuh (misalnya jika kami memiliki tautan dengan id nav-home):
sumber
Anda dapat menggunakan fungsi sebaliknya dengan parameter yang sesuai untuk mendapatkan url saat ini.
sumber
Terima kasih atas jawaban Anda sejauh ini, tuan-tuan. Aku telah melakukan sesuatu yang sedikit berbeda lagi ..
Di template saya:
Setelah saya mengetahui halaman mana yang saya masuki dalam logika (biasanya di urls.py), saya meneruskan
class="selected"
sebagai bagian dari konteks di bawah nama yang tepat ke template.Misalnya jika saya berada di halaman link1, saya akan menambahkan
{'link1_active':' class="selected"'}
konteks untuk template untuk mengambil dan menyuntikkan.Tampaknya berfungsi dan cukup bersih.
Edit: untuk mencegah HTML dari controller / view saya, saya telah memodifikasi ini sedikit:
Itu membuat template sedikit kurang dapat dibaca, tetapi saya setuju, lebih baik tidak mendorong HTML mentah dari file url.
sumber
Saya memiliki beberapa menu di halaman yang sama yang dibuat secara dinamis melalui loop. Posting di atas yang berkaitan dengan konteks memberi saya perbaikan cepat. Semoga ini bisa membantu seseorang. (Saya menggunakan ini selain tag template aktif - perbaikan saya memecahkan masalah dinamis). Sepertinya perbandingan yang konyol, tetapi berhasil. Saya memilih untuk menamai variabel active_something-unique dan sesuatu-unique, cara ini bekerja dengan menu bersarang.
Berikut ini sebagian dari pandangannya (cukup untuk memahami apa yang saya lakukan):
Dan ini dari template:
sumber
Solusi saya adalah menulis prosesor konteks sederhana untuk mengatur variabel berdasarkan jalur permintaan:
(Jangan lupa untuk menambahkan prosesor kustom Anda ke TEMPLATE_CONTEXT_PROCESSORS di settings.py.)
Kemudian di template dasar saya menggunakan tag ifequal per link untuk menentukan apakah akan menambahkan kelas "aktif". Memang pendekatan ini sangat terbatas pada fleksibilitas struktur jalur Anda, tetapi berfungsi untuk penerapan saya yang relatif sederhana.
sumber
Saya hanya ingin membagikan peningkatan kecil saya ke pos nivhab. Dalam aplikasi saya, saya memiliki subnavigasi dan saya tidak ingin menyembunyikannya hanya dengan menggunakan CSS, jadi saya memerlukan semacam tag "jika" untuk menampilkan subnavigasi suatu item atau tidak.
Pada dasarnya Anda dapat menggunakan ini dengan cara yang sama seperti tag aktif:
sumber
Hanya peningkatan lain dari solusi asli.
Ini menerima beberapa pola dan pola yang paling baik juga tanpa nama yang ditulis sebagai URL relatif yang dibungkus dengan '"', seperti berikut:
Tag berjalan seperti ini:
sumber
Saya menggunakan jquery untuk menyorot navbar saya. Solusi ini hanya menambahkan kelas css "aktif" ke item yang sesuai dengan pemilih css.
sumber
Sedikit peningkatan pada jawaban @tback , tanpa
%if%
tag apa pun :Gunakan di template Anda seperti itu:
Dan sertakan
"django.core.context_processors.request"
dalamTEMPLATE_CONTEXT_PROCESSORS
pengaturan Anda .sumber
Saya menemukan yang terbaik adalah menggunakan tag inklusi:
templates/fnf/nav_item.html
Ini hanya item navigasi bootstrap dasar yang ingin saya render.
Itu mendapat nilai href, dan secara opsional nilai link_name.
is_active
dihitung berdasarkan permintaan saat ini.templatetags/nav.py
Kemudian gunakan di navigasi:
templates/fnf/nav.html
sumber
/about/company-history/
atau/about/what-we-do/
is_active
bisa diganti dan kunci lain yang ditambahkan ke kamus dikembalikan. Juga, ceknya bisacontext.request.resolver_match.url_name.startswith(x)
atau apa saja. Juga, Anda dapat memiliki kode sebelum pernyataan return untuk menetapkan nilai dict. Selain itu, Anda dapat menggunakan template yang berbeda, yaitu template untuktop_level_nav.html
dengan logika berbeda, dll.Sedikit memodifikasi jawaban Andreas, sepertinya Anda dapat meneruskan nama rute dari urls.py ke tag template. Dalam contoh saya
my_tasks
, dan kemudian dalam fungsi tag template gunakan fungsi reverse untuk mengetahui apa URL yang seharusnya, maka Anda dapat mencocokkannya dengan URL di objek permintaan (tersedia dalam konteks template)urls.py
template.html
sumber
Saya tahu saya terlambat ke pesta. Saya tidak menyukai salah satu solusi populer:
The metode blok tampaknya salah: Saya pikir navigasi harus mandiri.
The Metode template_tag tampaknya salah: Saya tidak suka bahwa saya harus mendapatkan url dari url-tag pertama. Juga, saya pikir kelas css harus didefinisikan dalam template, bukan tagnya.
Oleh karena itu saya menulis filter yang tidak memiliki kekurangan yang saya jelaskan di atas. Ia kembali
True
jika url aktif dan oleh karena itu dapat digunakan dengan{% if %}
:Kode:
Pastikan untuk menggunakan
RequestContext
pada halaman dengan navigasi atau untuk mengaktifkan permintaan context_processor disettings.py
sumber
Saya telah melihat jawaban jpwatts ', 110j , nivhab & Marcus Whybrow , tetapi semuanya tampaknya kurang dalam sesuatu: bagaimana dengan jalur root? Kenapa selalu aktif?
Jadi saya telah membuat cara lain, lebih mudah, yang membuat "pengontrol" memutuskan dengan sendirinya dan menurut saya cara ini menyelesaikan sebagian besar masalah besar.
Ini tag kustom saya:
Kemudian, "controller" mendeklarasikan class CSS yang dibutuhkan (sebenarnya, yang paling penting adalah mendeklarasikan keberadaannya ke template)
Dan akhirnya, saya merendernya di bilah navigasi saya:
Jadi setiap halaman memiliki nilainya sendiri
nav_css_class
untuk disetel, dan jika disetel, templat akan merender aktif: tidak perlurequest
dalam konteks templat, tidak ada pengupasan URL dan tidak ada lagi masalah tentang halaman multi-URL atau halaman root.sumber
Terinspirasi oleh solusi ini , saya mulai menggunakan pendekatan ini:
sumber
Inilah tujuan saya. Saya akhirnya menerapkan kelas dalam pandangan saya yang berisi struktur navigasi saya (datar dengan beberapa metadata). Saya kemudian menyuntikkan ini ke templat dan merendernya.
Solusi saya berkaitan dengan i18n. Ini mungkin harus disarikan sedikit lagi tetapi saya tidak terlalu peduli dengan itu.
views.py:
Saya mendefinisikan logika template menggunakan termasuk seperti ini. Template dasar:
Sebenarnya termasuk (termasuk / navigation.html):
Semoga seseorang akan merasakan manfaatnya! Saya kira akan sangat mudah untuk memperluas ide itu untuk mendukung hierarki bersarang dll.
sumber
Buat template penyertaan "intranet / nav_item.html":
Dan sertakan di elemen nav:
Dan Anda perlu menambahkan ini ke pengaturan:
sumber
berikut adalah solusi yang cukup sederhana, https://github.com/hellysmile/django-activeurl
sumber
dari SO Pertanyaan ini
Ulangi seperlunya untuk setiap tautan.
sumber
/blog/posts/2021/04/12
url item / blog / nav akan aktif.Questions
,Tags
,Users
,Badges
,Unanswered
,Ask Question
. ini tidak akan berhasilQuestions
, tetapi untuk semua navigasi lain ini akan bekerja dengan baik.Saya juga menggunakan jQuery untuk menyorotnya dan menganggapnya lebih elegan daripada mengacaukan template dengan tag template Django non-semantik.
Kode di bawah ini bekerja dengan dropdown bersarang di bootstrap 3 (menyoroti elemen induk dan anak
<li>
.Ini juga cukup mudah untuk menambahkan
click
acara kereturn false
(atau mengubahhref
atribut ke#
) untuk halaman saat ini, tanpa mengubah markup template / html:sumber
Saya menggunakan kombinasi dari mixin ini untuk tampilan berbasis kelas:
dengan ini di template:
sumber
Milik saya agak mirip dengan pendekatan JS lain yang dikirimkan sebelumnya .. hanya tanpa jQuery ...
Katakanlah kita memiliki di base.html yang berikut:
Saya baru saja membuat hierarki saya mengikuti pola URL tertentu ... setelah alamat host ... saya memiliki kategori utama saya, misalnya, beranda, berita, analisis, dll. Dan regex hanya menarik kata pertama keluar dari lokasi
sumber