Django में नेविगेशन


104

मैंने अभी-अभी django में अपना पहला छोटा webapp किया है और मुझे यह पसंद है। मैं एक पुराने उत्पादन PHP साइट को django में बदलने और इसके टेम्पलेट के हिस्से के रूप में शुरू करने वाला हूं, एक नेविगेशन बार है।

PHP में, मैं प्रत्येक URL विकल्प को मौजूदा URL के खिलाफ टेम्प्लेट कोड में जांचता हूं और यदि वे लाइन में हैं तो CSS क्लास लगाते हैं। यह भयावह रूप से गड़बड़ है।

क्या django के लिए कुछ बेहतर है या टेम्पलेट में कोड को संभालने का एक अच्छा तरीका है?

शुरू करने के लिए, मैं वर्तमान URL प्राप्त करने के बारे में कैसे जाऊँगा?


मैंने इसके लिए github.com/orokusaki/django-active-menu बनाया - यह नेस्टेड URL संरचनाओं का समर्थन करता है, और कन्वेंशन पर कॉन्फ़िगरेशन पर निर्भर करता है (जैसा कि लगता है कि बुराई है), इसलिए आप अपनी साइट के पदानुक्रम को परिभाषित कर सकते हैं जो आप चाहते हैं। आप बस इस्तेमाल करें <a href="{% url "view:name" %}" {% active_class "view:name" %}>। आप वैकल्पिक रूप से इसका इस्तेमाल करते हैं उत्पन्न करने के लिए कर सकते हैं बस" active" मूल्य (पास करके Falseएक मौजूदा वर्ग विशेषता को संलग्न करने के लिए टैग के लिए एक दूसरा तर्क के रूप में), लेकिन सबसे एनएवी लिंक के लिए उदाहरण मैं क्या उपयोग है।
orokusaki


शायद यह ग्रिड मदद करता है: djangopackages.org/grids/g/navigation
guettli

जवाबों:


74

मैं नेविगेशन को अनुकूलित करने के लिए टेम्पलेट वंशानुक्रम का उपयोग करता हूं। उदाहरण के लिए:

base.html

<html>
    <head>...</head>
    <body>
        ...
        {% block nav %}
        <ul id="nav">
            <li>{% block nav-home %}<a href="{% url home %}">Home</a>{% endblock %}</li>
            <li>{% block nav-about %}<a href="{% url about %}">About</a>{% endblock %}</li>
            <li>{% block nav-contact %}<a href="{% url contact %}">Contact</a>{% endblock %}</li>
        </ul>
        {% endblock %}
        ...
    </body>
</html>

about.html

{% extends "base.html" %}

{% block nav-about %}<strong class="nav-active">About</strong>{% endblock %}

मुझे यह विचार बहुत पसंद है, खासकर लचीलेपन के लिए, लेकिन यह कम-डीआरवाई व्यापार-बंद के साथ आता है। मैंने हालांकि एक साइट में इसका उपयोग शुरू किया था।
गुमनाम कायर

22
मैं इस दृष्टिकोण के बारे में उत्साही नहीं हूं क्योंकि एक ही उप-टेम्पलेट द्वारा कई साइट अनुभागों को संभालना असामान्य नहीं है। इसलिए आप टेम्प्लेट में दृश्य और सशर्त में कस्टम संस्करण डाल रहे हैं, या उप-टेम्प्लेट को फिर से व्यवस्थित कर रहे हैं ताकि वे सभी अद्वितीय हों ... सभी केवल वर्तमान साइट अनुभाग का पता लगाने के लिए। टेम्पलेट टैग दृष्टिकोण अंत में क्लीनर होने के नाते समाप्त होता है।
शेकर

मैंने कुछ अन्य समाधानों को देखा, और ऐसा लगता है कि वे सभी एक हैक के एक बिट हैं। यह एक, कम से कम, बहुत सीधा और सरल है / लागू करने के लिए स्क्रैप।
1

मैंने <ul id="nav">....</ul>एक अलग फाइल के लिए रिफलैक्ट किया है, जो tabs.html कहती है। तो अब base.html सम्‍मिलित है {%block nav%}{%include "tabs.html"%}{%endblock%}और फिर सक्रिय टैब के हाइलाइटिंग ने काम करना बंद कर दिया (ऊपर के बारे में html में)। क्या मुझे कुछ याद आ रहा है?
कोई नहीं-दा

@ मैडी आपको काफी इनडायरेक्ट हो गया है कि मैं बिल्कुल निश्चित नहीं हूं कि मैं इसे सीधे अपने सिर में रख रहा हूं, लेकिन मुझे लगता है कि इसका जवाब includeटैग के साथ क्या करना है । डॉक्स में शामिल नोट देखें: docs.djangoproject.com/en/dev/ref/templates/builtins/#include अपने मामले में, जब तक आप बेस टेम्प्लेट को ओवरराइड करने की कोशिश कर रहे हैं about.html, तब तक मुझे लगता है कि आप पहले से ही एक प्रदान किए गए HTML ब्लॉक को संसाधित करने की प्रतीक्षा कर रहे Django टेम्पलेट ब्लॉक के बजाय मिला।
jpwatts

117

आपको ऐसा करने की आवश्यकता नहीं है, निम्नलिखित कोड पर एक नज़र डालें:

tags.py

@register.simple_tag
def active(request, pattern):
    import re
    if re.search(pattern, request.path):
        return 'active'
    return ''

urls.py

urlpatterns += patterns('',
    (r'/$', view_home_method, 'home_url_name'),
    (r'/services/$', view_services_method, 'services_url_name'),
    (r'/contact/$', view_contact_method, 'contact_url_name'),
)

base.html

{% load tags %}

{% url 'home_url_name' as home %}
{% url 'services_url_name' as services %}
{% url 'contact_url_name' as contact %}

<div id="navigation">
    <a class="{% active request home %}" href="{{ home }}">Home</a>
    <a class="{% active request services %}" href="{{ services }}">Services</a>
    <a class="{% active request contact %}" href="{{ contact }}">Contact</a>
</div>

बस। कार्यान्वयन के विवरण के लिए इस पर एक नज़र है:
gnuvince.wordpress.com
110j.wordpress.com


2
Href के गुण django टेम्पलेट कोष्ठक {{,}} से गायब हैं। उदाहरण के लिए, <a class="lights% सक्रिय अनुरोध मुख%% href="home"> होम </a> होना चाहिए, <a class = "{% सक्रिय अनुरोध घर%}" href = "{{home} } "> होम </a> टैग्स फ़ाइल में कुछ शामिल करने की आवश्यकता होगी। अन्यथा, महान समाधान!
bsk

2
+1 यह अनुप्रयोगों से अधिक शिथिल है। एक शुरुआत के रूप में मुझे लगा कि टैग की जरूरत है कि यह खुद का ऐप है, आप इसे सिर्फ एक ग्लोबल टैगशो फाइल में डंप नहीं कर सकते। मैंने टैग्स नामक एक नया ऐप बनाया और सब कुछ सुचारू रूप से चला। docs.djangoproject.com/en/dev/howto/custom-template-tags
कीओ

3
@Keyo, अपनी परियोजना में एक templatetags निर्देशिका बनाएं, और अपनी परियोजना को इंस्टॉलप्स में जोड़ें। वह भी चाल चलेंगे। वैकल्पिक रूप से, जैसा आपने कहा, अपनी मुख्य साइट को अपनी परियोजना के भीतर एक ऐप के रूप में बनाएं।
जोश स्मेटन

5
जोड़ने के लिए मत भूलना django.core.context_processors.requestअपने को TEMPLATE_CONTEXT_PROCESSORSमेंsettings.py
amigcamel

1
यह उन राज्यों के लिए अमान्य है, जिन्हें घोंसला दिया जा सकता है, जैसे mysite.com(घर के रूप में) और mysite.com/blog, जैसा कि रास्ता दिखाएगा /और /blog/(क्रमशः) प्रत्येक बार पूर्व के लिए एक मैच का उत्पादन करेगा। यदि आप /लैंडिंग के रूप में उपयोग नहीं करते हैं , तो यह ठीक हो सकता है अन्यथा मैं सिर्फ उपयोग करता return 'active' if pattern == request.path else ''हूं (मैंने अभी तक इस मुद्दे को नहीं देखा है, लेकिन मैं अभी उपयोग कर रहा हूं)।
nerdwaller

33

मुझे ऊपर 110j की साफ-सफाई पसंद थी, इसलिए मैंने इसे सबसे ज्यादा लिया और इसके साथ 3 समस्याओं को हल करने के लिए मना किया:

  1. नियमित अभिव्यक्ति अन्य लोगों के खिलाफ 'घर' के यूआरएल से मेल खा रही थी
  2. मुझे एक नेविगेशन टैब पर मैप किए गए कई URL की आवश्यकता थी , इसलिए मुझे अधिक जटिल टैग की आवश्यकता थी जो मापदंडों की चर राशि लेता हो
  3. कुछ url समस्याओं को ठीक किया

यह रहा:

tags.py:

from django import template

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, patterns):
        self.patterns = patterns
    def render(self, context):
        path = context['request'].path
        for p in self.patterns:
            pValue = template.Variable(p).resolve(context)
            if path == pValue:
                return "active" # change this if needed for other bootstrap version (compatible with 3.2)
        return ""

urls.py:

urlpatterns += patterns('',
    url(r'/$', view_home_method, {}, name='home_url_name'),
    url(r'/services/$', view_services_method, {}, name='services_url_name'),
    url(r'/contact/$', view_contact_method, {}, name='contact_url_name'),
    url(r'/contact/$', view_contact2_method, {}, name='contact2_url_name'),
)

base.html:

{% load tags %}

{% url home_url_name as home %}
{% url services_url_name as services %}
{% url contact_url_name as contact %}
{% url contact2_url_name as contact2 %}

<div id="navigation">
    <a class="{% active request home %}" href="home">Home</a>
    <a class="{% active request services %}" href="services">Services</a>
    <a class="{% active request contact contact2 %}" href="contact">Contact</a>
</div>

यह शायद हम मार्कस के साथ सबसे अच्छा जवाब दे सकते हैं, लेकिन यह "घर" के साथ कैसे काम करता है? यह हमेशा सक्रिय है? केवल रूट url कॉल (www.toto.com/ और www.toto.com/index) पर इसे कैसे सक्रिय किया जाए? दोनों जवाब इस समस्या का परिणाम नहीं है ...
DestyNova

20

मैं django- वंश का लेखक हूं जो मैंने विशेष रूप से इस प्रश्न को हल करने के लिए लिखा था: डी

मैं अपनी परियोजनाओं में (पूरी तरह से स्वीकार्य) jpwatts पद्धति का उपयोग करके नाराज हो गया और 110j के उत्तर से प्रेरणा प्राप्त की। वंश इस तरह दिखता है:

{% load lineage %}
<div id="navigation">
    <a class="{% ancestor '/home/' %}" href="/home/">Home</a>
    <a class="{% ancestor '/services/' %}" href="/services/">Services</a>
    <a class="{% ancestor '/contact/' %}" href="/contact/">Contact</a>
</div>

ancestor यदि तर्क वर्तमान पृष्ठ URL के प्रारंभ से मेल खाता है, तो इसे केवल "सक्रिय" से बदल दिया जाता है।

परिवर्तनीय तर्क, और पूर्ण {% url %}प्रकार रिवर्स रिज़ॉल्यूशन, भी समर्थित है। मैंने कुछ कॉन्फ़िगरेशन विकल्पों में छिड़का और इसे थोड़ा बाहर निकाल दिया और इसे सभी के उपयोग के लिए पैक कर दिया।

अगर किसी को दिलचस्पी है, तो इसके बारे में थोड़ा और पढ़ें:

>> github.com/marcuswhybrow/django-lineage


1
टेम्प्लेट में कठिन कोडिंग पथ :(
CpILL

10

Django 1.5 के बाद से :

सभी जेनेरिक क्लास-आधारित विचारों (या किसी भी क्लास-आधारित दृश्य जो कॉन्टेक्स्ट मैक्सीन से विरासत में मिला है) में, संदर्भ शब्दकोश में एक दृश्य चर होता है जो व्यू इंस्टेंस को इंगित करता है।

इसलिए यदि आप इस तरह के विचारों का उपयोग कर रहे हैं, तो आप breadcrumbsक्लास लेवल फ़ील्ड के रूप में कुछ लाइक जोड़ सकते हैं और अपने टेम्प्लेट में इसका उपयोग कर सकते हैं।

उदाहरण दृश्य कोड:

class YourDetailView(DetailView):
     breadcrumbs = ['detail']
     (...)

अपने टेम्पलेट में आप इसे इस तरह से उपयोग कर सकते हैं:

<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>

यदि आप मूल नेविगेशन आइटम को "हाइलाइट" करना चाहते हैं, तो आपको breadcrumbsसूची का विस्तार करना होगा :

class YourDetailView(DetailView):
     breadcrumbs = ['dashboard', 'list', 'detail']
     (...)

... और आपके खाके में:

<a href="/dashboard/" {% if 'dashboard' in view.breadcrumbs %}class="active"{% endif %}>Dashboard</a>
<a href="/list/" {% if 'list' in view.breadcrumbs %}class="active"{% endif %}>List</a>
<a href="/detail/" {% if 'detail' in view.breadcrumbs %}class="active"{% endif %}>Detail</a>

यह आसान और साफ समाधान है और नेस्टेड नेविगेशन के साथ बहुत अच्छी तरह से काम करता है।


उस उदाहरण में, सभी तीन नेविगेशन आइटम नहीं होंगे .active?
ओली

हां, लेकिन यह आमतौर पर वही होता है जो आप बहु-स्तरीय नेविगेशन के साथ प्राप्त करना चाहते हैं। breadcrumbsयदि आप चाहें तो आप निश्चित रूप से एक आइटम डाल सकते हैं। लेकिन आपके पास सही है - मेरा उदाहरण सबसे अच्छा नहीं है।
कोनराड हालास

@ ओली ने बेहतर उदाहरण दिया।
कोनराड हालास

9

आप किसी विशिष्ट नेवी आइटम की बजाय पेज के बॉडी एलिमेंट पर एक क्लास या आईडी लगा सकते हैं।

HTML:

<body class="{{ nav_class }}">

सीएसएस:

body.home #nav_home,
body.about #nav_about { */ Current nav styles */ }

8

मैं इसे इस तरह से करता हूं:

<a class="tab {% ifequal active_tab "statistics" %}active{% endifequal %}" href="{% url Member.Statistics %}">Statistics</a>

और फिर मुझे बस इतना करना है कि मैं {'active_tab': 'statistics'}अपने संदर्भ शब्दकोश में अपने विचार जोड़ दूं।

यदि आप उपयोग कर रहे हैं तो आप RequestContextअपने टेम्पलेट में वर्तमान पथ प्राप्त कर सकते हैं:

{{ request.path }}

और आपके विचार में:

from django.template import RequestContext

def my_view(request):
    # do something awesome here
    return template.render(RequestContext(request, context_dict))

इस जानकारी को साझा करने के लिए धन्यवाद। मैंने इस पद्धति का उपयोग किया, लेकिन मेरी नौसेना पट्टी में एक फ्लैटपेज भी था, इसलिए इसका पता लगाने और इसे सही ढंग से उजागर करने के लिए, मैंने {% ifequal flatpage.url '/ about /'%) का उपयोग किया। मुझे URL का हार्डकोडेड डिटेक्शन पसंद नहीं है, लेकिन यह एक बार बंद हैक के लिए काम करता है।
मैट गैरीसन

इस समाधान के साथ समस्या यह है कि आपके पास कोड में हार्ड-कोडेड "आंकड़े" हैं। यह पृष्ठ का url प्राप्त करने के लिए url टैग का उपयोग करने के उद्देश्य को पराजित करता है।
जस्टिन

7

मैंने ऊपर दिए गए निवाब से कोड लिया और कुछ व्यापकता को हटा दिया और इसे एक साफ टेम्पलेटेट में बना दिया, इसे संशोधित किया ताकि / खाता / संपादन / अभी भी / खाता / टैब सक्रिय कर देगा।

#current_nav.py
from django import template

register = template.Library()

@register.tag
def current_nav(parser, token):
    import re
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1])

class NavSelectedNode(template.Node):
    def __init__(self, url):
        self.url = url

    def render(self, context):
        path = context['request'].path
        pValue = template.Variable(self.url).resolve(context)
        if (pValue == '/' or pValue == '') and not (path  == '/' or path == ''):
            return ""
        if path.startswith(pValue):
            return ' class="current"'
        return ""



#template.html
{% block nav %}
{% load current_nav %}
{% url home as home_url %}
{% url signup as signup_url %}
{% url auth_login as auth_login_url %}
<ul class="container">
    <li><a href="{{ home_url }}"{% current_nav home_url %} title="Home">Home</a></li>
    <li><a href="{{ auth_login_url }}"{% current_nav auth_login_url %} title="Login">Login</a></li>
    <li><a href="{{ signup_url }}"{% current_nav signup_url %} title="Signup">Signup</a></li>
</ul>
{% endblock %}

6

यह ऊपर टोबा द्वारा प्रस्तावित सीएसएस समाधान का एक प्रकार है:

अपने बेस टेम्पलेट में निम्नलिखित शामिल करें:

<body id="section-{% block section %}home{% endblock %}">

फिर अपने टेम्पलेट में जो आधार उपयोग को बढ़ाते हैं:

{% block section %}show{% endblock %}

फिर आप बॉडी टैग के आधार पर वर्तमान क्षेत्र को उजागर करने के लिए सीएसएस का उपयोग कर सकते हैं (उदाहरण के लिए अगर हमारे पास नव-घर की आईडी के साथ लिंक है:

#section-home a#nav-home{
 font-weight:bold;
}


3

अब तक आपके जवाब के लिए धन्यवाद, मर्द। मैं फिर से कुछ अलग करने के लिए गया हूँ ।।

मेरे टेम्पलेट में:

<li{{ link1_active }}>...link...</li>
<li{{ link2_active }}>...link...</li>
<li{{ link3_active }}>...link...</li>
<li{{ link4_active }}>...link...</li>

एक बार जब मैंने काम कर लिया तो मैं किस पेज पर हूं (आमतौर पर urls.py में), मैं पास हो गया class="selected" टेम्पलेट के सही नाम के तहत संदर्भ के भाग के रूप में करता ।

उदाहरण के लिए, अगर मैं लिंक 1 पेज पर हूं, तो मैं अपील करूंगा {'link1_active':' class="selected"'} टेम्पलेट को करने और इंजेक्ट करने के लिए संदर्भ ।

यह काम करने के लिए प्रकट होता है और यह काफी साफ है।

संपादित करें: HTML को मेरे नियंत्रक / दृश्य से बाहर रखने के लिए, मैंने इसे थोड़ा संशोधित किया है:

<li{% if link1_active %} class="selected"{% endif %}>...link...</li>
<li{% if link2_active %} class="selected"{% endif %}>...link...</li>
...

यह टेम्प्लेट को थोड़ा कम पठनीय बनाता है, लेकिन मैं सहमत हूं, यह बेहतर है कि url फ़ाइल से कच्चे HTML के माध्यम से धक्का न दें।


2
आपको अपने दृष्टिकोण में कच्चे HTML को संभालने से वास्तव में बचना चाहिए , जो कि इस तकनीक की आवश्यकता है। क्या आपने कस्टम टेम्पलेट टैग लिखने के बारे में सोचा है?
जस्टिन वॉस

आप सही हे। मैंने HTML से गुजरना बंद करने के लिए संपादन किया है। मैं अभी ट्रू से गुजरता हूं। मैंने अभी तक कोई टेम्प्लेट टैग नहीं लिखे हैं, लेकिन हां, यह शुरू करने के लिए एक अच्छी जगह हो सकती है।
ओली

2

मेरे पास एक ही पृष्ठ पर कई मेनू हैं जो गतिशील रूप से एक लूप के माध्यम से बनाए गए हैं। संदर्भ से संबंधित उपरोक्त पदों ने मुझे एक त्वरित सुधार दिया। आशा है कि यह किसी की मदद करता है। (मैं सक्रिय टेम्पलेट टैग के अलावा इसका उपयोग करता हूं - मेरा फिक्स डायनेमिक समस्या को हल करता है)। यह एक मूर्खतापूर्ण तुलना की तरह लगता है, लेकिन यह काम करता है। मैंने वेरिएबल्स को active_something- यूनिक और कुछ-यूनिक नाम देने के लिए चुना, इस तरह यह नेस्टेड मेनू के साथ काम करता है।

यहाँ दृश्य का एक हिस्सा है (यह समझने के लिए पर्याप्त है कि मैं क्या कर रहा हूँ):

def project_list(request, catslug):
    "render the category detail page"
    category = get_object_or_404(Category, slug=catslug, site__id__exact=settings.SITE_ID)
    context = {
        'active_category': 
            category,
        'category': 
            category,
        'category_list': 
            Category.objects.filter(site__id__exact=settings.SITE_ID),

    }

और यह टेम्पलेट से है:

<ul>
  {% for category in category_list %}
    <li class="tab{% ifequal active_category category %}-active{% endifequal %}">
      <a href="{{ category.get_absolute_url }}">{{ category.cat }}</a>
    </li>
  {% endfor %}
</ul>

2

मेरा समाधान अनुरोध पथ के आधार पर एक चर सेट करने के लिए एक साधारण संदर्भ प्रोसेसर लिखना था:

def navigation(request):
"""
Custom context processor to set the navigation menu pointer.
"""
nav_pointer = ''
if request.path == '/':
    nav_pointer = 'main'
elif request.path.startswith('/services/'):
    nav_pointer = 'services'
elif request.path.startswith('/other_stuff/'):
    nav_pointer = 'other_stuff'
return {'nav_pointer': nav_pointer}

(सेटिंग में अपने कस्टम प्रोसेसर को TEMPLATE_CONTEXT_PROCESSORS में जोड़ना न भूलें।)

फिर आधार टेम्पलेट में मैं "सक्रिय" वर्ग को जोड़ने के लिए निर्धारित करने के लिए प्रति लिंक एक ifequal टैग का उपयोग करता हूं। दी यह दृष्टिकोण सख्ती से आपके पथ संरचना के लचीलेपन तक सीमित है, लेकिन यह मेरी अपेक्षाकृत मामूली तैनाती के लिए काम करता है।


मुझे लगता है कि यह वास्तव में इनको वैश्विक संदर्भ में रखने के लिए समझ में आता है, इसलिए आप साइट अनुभाग को विभिन्न तरीकों से संदर्भित कर सकते हैं (उदाहरण के लिए अलग-अलग साइट अनुभागों के लिए अलग-अलग टेम्पलेट का उपयोग करके। +1।
6:20 पर शेकर

2

मैं निवाब की पोस्ट पर अपनी मामूली वृद्धि को साझा करना चाहता था। मेरे आवेदन में मेरे पास सबनेविगेशन हैं और मैं उन्हें सिर्फ सीएसएस का उपयोग करके छिपाना नहीं चाहता था, इसलिए मुझे किसी आइटम के लिए उप-दायित्व को प्रदर्शित करने के लिए "अगर" टैग की आवश्यकता थी।

from django import template
register = template.Library()

@register.tag
def ifnaviactive(parser, token):
    nodelist = parser.parse(('endifnaviactive',))
    parser.delete_first_token()

    import re
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:], nodelist)

class NavSelectedNode(template.Node):
    def __init__(self, patterns, nodelist):
        self.patterns = patterns
        self.nodelist = nodelist

    def render(self, context):
        path = context['request'].path
        for p in self.patterns:
            pValue = template.Variable(p).resolve(context)
            if path == pValue:
                return self.nodelist.render(context)
        return ""

आप इसे मूल रूप से उसी तरह उपयोग कर सकते हैं जैसे सक्रिय टैग:

{% url product_url as product %}

{% ifnaviactive request product %}
    <ul class="subnavi">
        <li>Subnavi item for product 1</li>
        ...
    </ul>
{% endifnaviactive %}

2

मूल समाधान का सिर्फ एक और ehnancement।

यह कई प्रतिमानों को स्वीकार करता है और जो कि '' '' में लिपटे हुए सापेक्ष URL के रूप में लिखे गए सर्वश्रेष्ठ पैटर्न भी हैं, निम्नानुसार हैं:

{% url admin:clients_client_changelist as clients %}
{% url admin:clients_town_changelist as towns %}
{% url admin:clients_district_changelist as districts %}

<li class="{% active "/" %}"><a href="/">Home</a></li>
<li class="{% active clients %}"><a href="{{ clients }}">Clients</a></li>
{% if request.user.is_superuser %}
<li class="{% active towns districts %}">
    <a href="#">Settings</a>
    <ul>
        <li><a href="{{ towns }}">Towns</a></li>
        <li><a href="{{ districts }}">Districts</a></li>
    </ul>
</li>
{% endif %}

टैग इस प्रकार है:

from django import template

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, urls):
        self.urls = urls

    def render(self, context):
        path = context['request'].path

        for url in self.urls:
            if '"' not in url:
                cpath = template.Variable(url).resolve(context)
            else:
                cpath = url.strip('"')

            if (cpath == '/' or cpath == '') and not (path == '/' or path == ''):
                return ""
            if path.startswith(cpath):
                return 'active'
        return ""

2

मैंने अपने नावबाजों को उजागर करने के लिए jquery का उपयोग किया। यह समाधान बस सीएसएस वर्ग को "सक्रिय" आइटम में जोड़ता है जो सीएसएस चयनकर्ता को फिट बैठता है।

<script type="text/javascript" src="/static/js/jquery.js"></script>
<script>
    $(document).ready(function(){
        var path = location.pathname;
        $('ul.navbar a.nav[href$="' + path + '"]').addClass("active");
    });
</script>

2

@Tback के उत्तर पर थोड़ी वृद्धि , बिना किसी %if%टैग के:

# navigation.py
from django import template
from django.core.urlresolvers import resolve

register = template.Library()

@register.filter(name="activate_if_active", is_safe=True)
def activate_if_active(request, urlname):
  if resolve(request.get_full_path()).url_name == urlname:
    return "active"
  return ''

इसे अपने टेम्पलेट में उपयोग करें जैसे:

{% load navigation %}
<li class="{{ request|activate_if_active:'url_name' }}">
  <a href="{% url 'url_name' %}">My View</a>
</li>

और "django.core.context_processors.request"अपनी TEMPLATE_CONTEXT_PROCESSORSसेटिंग में शामिल करें ।


2

मैंने पाया कि समावेशन टैग का उपयोग करना सबसे अच्छा है:

templates/fnf/nav_item.html

<li class="nav-item">
    <a class="nav-link {% if is_active %}active{% endif %}" href="{% url url_name %}">{{ link_name }}</a>
</li>

यह सिर्फ मेरा मूल बूटस्ट्रैप नेवी आइटम है जिसे मैं रेंडर करना चाहता हूं।

इसे href मान मिलता है, और वैकल्पिक रूप से link_name मान। is_activeवर्तमान अनुरोध के आधार पर गणना की जाती है।

templatetags/nav.py

from django import template

register = template.Library()


@register.inclusion_tag('fnf/nav_item.html', takes_context=True)
def nav_item(context, url_name, link_name=None):
    return {
        'url_name': url_name,
        'link_name': link_name or url_name.title(),
        'is_active': context.request.resolver_match.url_name == url_name,
    }

फिर इसे एक नौसेना में उपयोग करें: templates/fnf/nav.html

{% load nav %}
<nav class="navbar navbar-expand-lg navbar-light bg-light">
        <ul class="navbar-nav mr-auto">
                {% nav_item 'dashboard' %}
            </ul>

बस एक सरसरी रीडिंग, लेकिन क्या यह URL पर सटीक मिलान के लिए चीजों को सीमित नहीं करता है ? मैं आमतौर पर गहरे पृष्ठों के लिए भी इस तरह के नेविगेशन संकेत का उपयोग करता हूं। उदाहरण के बारे में अगर आप /about/company-history/या तो पर थे या के बारे में नौसेना आइटम पर प्रकाश डाला जाएगा/about/what-we-do/
ओली

1
हां, लेकिन is_activeप्रतिस्थापित किया जा सकता है और अन्य कुंजियों को शब्दकोश में जोड़ा गया है। इसके अलावा, चेक context.request.resolver_match.url_name.startswith(x)या कुछ और भी हो सकता है। साथ ही, तानाशाही मूल्यों को स्थापित करने के लिए आपके पास रिटर्न स्टेटमेंट से पहले कोड हो सकता है। इसके अलावा, आप विभिन्न टेम्प्लेट का उपयोग कर सकते हैं, अर्थात एक के लिए एक top_level_nav.htmlअलग तर्क, आदि
Tjorriemorrie

स्वच्छ और सरल समाधान ... अच्छा!
मिमीव

1

एंड्रियास के उत्तर को थोड़ा संशोधित करते हुए, ऐसा लगता है कि आप urls.py से टेम्पलेट टैग के लिए मार्ग के नाम से गुजर सकते हैं। मेरे उदाहरण में my_tasks, और फिर टेम्प्लेट टैग फ़ंक्शन में URL को क्या होना चाहिए, यह जानने के लिए रिवर्स फ़ंक्शन का उपयोग करें, फिर आप अनुरोध ऑब्जेक्ट में URL के विरुद्ध (टेम्पलेट संदर्भ में उपलब्ध) से मिलान कर सकते हैं

from django import template
from django.core.urlresolvers import reverse

register = template.Library()

@register.tag
def active(parser, token):
    args = token.split_contents()
    template_tag = args[0]
    if len(args) < 2:
        raise template.TemplateSyntaxError, "%r tag requires at least one argument" % template_tag
    return NavSelectedNode(args[1:])

class NavSelectedNode(template.Node):
    def __init__(self, name):
        self.name = name

    def render(self, context):

        if context['request'].path == reverse(self.name[1]):
            return 'active'
        else:
            return ''

urls.py

url(r'^tasks/my', my_tasks, name = 'my_tasks' ),

template.html

<li class="{% active request all_tasks %}"><a href="{% url all_tasks %}">Everyone</a></li>

हो सकता है, अधिक सरल दृष्टिकोण: turnkeylinux.org/blog/django-navbar
jgsogo

1

मुझे पता है कि मुझे पार्टी में देर हो रही है। मुझे हालांकि कोई भी लोकप्रिय समाधान पसंद नहीं आया:

ब्लॉक विधि गलत लगता है: मुझे लगता है कि नेविगेशन आत्म निहित होना चाहिए।

template_tag विधि गलत लगता है: मुझे क्या करना पसंद है कि मैं पहली बार यूआरएल टैग से URL प्राप्त करने की जरूरत नहीं। इसके अलावा, मुझे लगता है कि सीएसएस-क्लास को टेम्पलेट में परिभाषित किया जाना चाहिए, टैग नहीं।

इसलिए मैंने एक फ़िल्टर लिखा है जिसमें मेरे द्वारा वर्णित कमियां नहीं हैं। यह रिटर्न Trueअगर एक यूआरएल सक्रिय है और इसलिए साथ इस्तेमाल किया जा सकता {% if %}:

{% load navigation %}
<li{% if request|active:"home" %} class="active"{% endif %}><a href="{% url "home" %}">Home</a></li>

कोड:

@register.filter(name="active")
def active(request, url_name):
    return resolve(request.path_info).url_name == url_name

बस RequestContextनेविगेशन वाले पृष्ठों पर उपयोग करना या अपने संदर्भ में अनुरोध संदर्भ_प्रोसेसर सक्षम करना सुनिश्चित करेंsettings.py

TEMPLATE_CONTEXT_PROCESSORS = (
    ...
    'django.core.context_processors.request',
)

1

मैंने jpwatts ', 110j ' s देखा है, nivhab है और मार्कस Whybrow के उत्तर , लेकिन वे सभी कुछ में कमी लगती हैं: रूट पथ के बारे में क्या? यह हमेशा सक्रिय क्यों है?

तो मैंने एक और रास्ता बनाया है, आसान, जो "नियंत्रक" को खुद से तय करता है और मुझे लगता है कि यह ज्यादातर बड़ी समस्याओं को हल करता है।

यहाँ मेरा कस्टम टैग है:

## myapp_tags.py

@register.simple_tag
def nav_css_class(page_class):
    if not page_class:
        return ""
    else:
        return page_class

फिर, "नियंत्रक" सीएसएस कक्षाओं की आवश्यकता की घोषणा करता है (वास्तव में, सबसे महत्वपूर्ण यह टेम्पलेट की उपस्थिति की घोषणा करता है)

## views.py

def ping(request):
    context={}
    context["nav_ping"] = "active"
    return render(request, 'myapp/ping.html',context)

और अंत में, मैं इसे अपने नेविगेशन बार में प्रस्तुत करता हूं:

<!-- sidebar.html -->

{% load myapp_tags %}
...

<a class="{% nav_css_class nav_home %}" href="{% url 'index' %}">
    Accueil
</a>
<a class="{% nav_css_class nav_candidats %}" href="{% url 'candidats' %}">
    Candidats
</a>
<a class="{% nav_css_class nav_ping %}" href="{% url 'ping' %}">
    Ping
</a>
<a class="{% nav_css_class nav_stat %}" href="{% url 'statistiques' %}">
    Statistiques
</a>
...

इसलिए प्रत्येक पृष्ठ nav_css_classको सेट करने का अपना मूल्य होता है, और यदि यह सेट होता है, तो टेम्पलेट सक्रिय हो जाता है: requestटेम्पलेट संदर्भ की कोई आवश्यकता नहीं, कोई URL पार करने और बहु-URL पेज या रूट पेज के बारे में कोई समस्या नहीं।


1

इस समाधान से प्रेरित होकर , मैंने इस दृष्टिकोण का उपयोग करना शुरू किया:

**Placed in templates as base.html**

{% block tab_menu %}
<ul class="tab-menu">
  <li class="{% if active_tab == 'tab1' %} active{% endif %}"><a href="#">Tab 1</a></li>
  <li class="{% if active_tab == 'tab2' %} active{% endif %}"><a href="#">Tab 2</a></li>
  <li class="{% if active_tab == 'tab3' %} active{% endif %}"><a href="#">Tab 3</a></li>
</ul>
{% endblock tab_menu %}

**Placed in your page template**

{% extends "base.html" %}

{% block tab_menu %}
  {% with active_tab="tab1" %} {{ block.super }} {% endwith %}
{% endblock tab_menu %}

0

यहाँ मेरा उस पर जाना है। मैंने अपने विचारों में एक वर्ग को लागू करना समाप्त कर दिया जिसमें मेरी नेविगेशन संरचना (कुछ मेटाडेटा के साथ फ्लैट) शामिल है। मैं फिर इसे टेम्पलेट पर इंजेक्ट करता हूं और इसे प्रस्तुत करता हूं।

मेरा समाधान i18n से संबंधित है। यह शायद थोड़ा और बाहर अमूर्त किया जाना चाहिए लेकिन मैं वास्तव में वास्तव में परेशान नहीं हुआ हूं।

views.py:

from django.utils.translation import get_language, ugettext as _


class Navi(list):
    items = (_('Events'), _('Users'), )

    def __init__(self, cur_path):
        lang = get_language()
        first_part = '/' + cur_path.lstrip('/').split('/')[0]

        def set_status(n):
            if n['url'] == first_part:
                n['status'] == 'active'

        for i in self.items:
            o = {'name': i, 'url': '/' + slugify(i)}
            set_status(o)
            self.append(o)

# remember to attach Navi() to your template context!
# ie. 'navi': Navi(request.path)

मैंने टेम्पलेट लॉजिक को इस तरह शामिल करते हुए परिभाषित किया। बेस टेम्प्लेट:

{% include "includes/navigation.html" with items=navi %}

वास्तविक में शामिल हैं (शामिल / navigation.html):

 <ul class="nav">
     {% for item in items %}
         <li class="{{ item.status }}">
             <a href="{{ item.url }}">{{ item.name }}</a>
         </li>
     {% endfor %}
 </ul>

उम्मीद है कि किसी को यह उपयोगी मिलेगा! मुझे लगता है कि नेस्टेड पदानुक्रमों आदि का समर्थन करने के लिए उस विचार का विस्तार करना बहुत आसान होगा।


0

"इंट्रानेट / nav_item.html" टेम्पलेट शामिल करें:

{% load url from future %}

{% url view as view_url %}
<li class="nav-item{% ifequal view_url request.path %} current{% endifequal %}">
    <a href="{{ view_url }}">{{ title }}</a>
</li>

और इसे नौसेना तत्व में शामिल करें:

<ul>
    {% include "intranet/nav_item.html" with view='intranet.views.home' title='Home' %}
    {% include "intranet/nav_item.html" with view='crm.views.clients' title='Clients' %}
</ul>

और आपको इसे सेटिंग्स में जोड़ना होगा:

from django.conf import global_settings
TEMPLATE_CONTEXT_PROCESSORS = global_settings.TEMPLATE_CONTEXT_PROCESSORS + (
    'django.core.context_processors.request',
)

0

यहाँ बहुत सरल समाधान है, https://github.com/hellysmile/django-activeurl


1
कृपया ध्यान दें कि आपको इस साइट पर उत्तर के उपयोगी बिंदुओं को पोस्ट करना चाहिए, या आपके पोस्ट के जोखिमों को "नहीं एक उत्तर" के रूप में हटा दिया जाना चाहिए । यदि आप चाहें तो आप अभी भी लिंक को शामिल कर सकते हैं, लेकिन केवल 'संदर्भ' के रूप में। लिंक की आवश्यकता के बिना जवाब अपने दम पर खड़ा होना चाहिए।
एंड्रयू नाई

0

इस एसओ प्रश्न से

{% url 'some_urlpattern_name' as url %}
<a href="{{url}}"{% if request.path == url %} class="active"{% endif %}>Link</a>

प्रत्येक लिंक के लिए आवश्यक दोहराएं।


यह केवल सीधे मैचों के लिए काम करता है। अगर कोई वंशज पृष्ठ भी सक्रिय है, तो अधिकांश नेविगेशन प्रणालियां नौसेना के आइटम को सक्रिय करती हैं। यानी अगर /blog/posts/2021/04/12url / ब्लॉग / नौसेना आइटम सक्रिय होता।
ओली

@ ओली यह कुछ समय के लिए काम नहीं करेगा। stackoverflow नेविगेशन यानी में उदाहरण के लिए Questions, Tags, Users, Badges, Unanswered, Ask Question। यह काम नहीं करेगा Questions, लेकिन अन्य सभी नौसेनाओं के लिए यह ठीक काम करेगा।
suhailvs

0

मैंने इसे हाइलाइट करने के लिए jQuery का भी इस्तेमाल किया और गैर-शब्दार्थ Django टेम्प्लेट टैग के साथ टेम्पलेट को अव्यवस्थित करने की तुलना में अधिक सुरुचिपूर्ण पाया।

नीचे दिए गए कोड बूटस्ट्रैप 3 में नेस्टेड ड्रॉपडाउन के साथ काम करता है (माता-पिता और बच्चे के <li>तत्व दोनों पर प्रकाश डाला गया) ।

// DOM Ready
$(function() {
    // Highlight current page in nav bar
    $('.nav, .navbar-nav li').each(function() {
        // Count the number of links to the current page in the <li>
        var matched_links = $(this).find('a[href]').filter(function() {
            return $(this).attr('href') == window.location.pathname; 
        }).length;
        // If there's at least one, mark the <li> as active
        if (matched_links)
            $(this).addClass('active');
    });
});

टेम्पलेट / html मार्कअप को बदले बिना वर्तमान पृष्ठ के लिए किसी clickईवेंट को जोड़ना return false(या hrefविशेषता को बदलना #) काफी आसान है :

        var matched_links = $(this).find('a[href]').filter(function() {
            var matched = $(this).attr('href') == window.location.pathname;
            if (matched)
                $(this).click(function() { return false; });
            return matched;
        }).length;

0

मैं वर्ग आधारित विचारों के लिए इस मिश्रण के संयोजन का उपयोग करता हूं:

class SetActiveViewMixin(object):
    def get_context_data(self, **kwargs):
        context = super(SetActiveViewMixin, self).get_context_data(**kwargs)
        context['active_nav_menu'] = {
            self.request.resolver_match.view_name: ' class="pure-menu-selected"'
        }
        return context

टेम्पलेट में इसके साथ:

<ul>
    <li{{active_nav_menu.node_explorer }}><a href="{% url 'node_explorer' '' %}">Explore</a></li>
    <li{{active_nav_menu.node_create }}><a href="{% url 'node_create' path %}">Create</a></li>
    <li{{active_nav_menu.node_edit }}><a href="{% url 'node_edit' path %}">Edit</a></li>
    <li{{active_nav_menu.node_delete }}><a href="{% url 'node_delete' path %}">Delete</a></li>
</ul>

0

मेरा एक अन्य जेएस दृष्टिकोण के समान है जो पहले प्रस्तुत किया गया था .. सिर्फ jQuery के बिना ...

हम कहते हैं कि आधार में निम्नलिखित हैं:

<div class="pure-u-1 pure-menu pure-menu-open pure-menu-horizontal header" >
    <ul class="">
        <li id="home"><a href="{% url 'article:index' %}">Home</a></li>
        <li id="news"><a href="{% url 'article:index' %}">News</a></li>
        <li id="analysis"><a href="{% url 'article:index' %}">Analysis</a></li>
        <li id="opinion"><a href="{% url 'article:index' %}">Opinion</a></li>
        <li id="data"><a href="{% url 'article:index' %}">Data</a></li>
        <li id="events"><a href="{% url 'article:index' %}">Events</a></li>
        <li id="forum"><a href="{% url 'article:index' %}">Forum</a></li>
        <li id="subscribe"><a href="{% url 'article:index' %}">Subscribe</a></li>
    </ul>
    <script type="text/javascript">
        (function(){
            loc=/\w+/.exec(window.location.pathname)[0];
            el=document.getElementById(loc).className='pure-menu-selected';         
        })();   
    </script>
</div>

मैंने सिर्फ एक निश्चित URL पैटर्न का पालन करने के लिए अपनी पदानुक्रम बना ली है ... मेजबान पते के बाद ... मेरे पास मेरी मुख्य श्रेणी, जैसे, घर, समाचार, विश्लेषण, आदि है और regex बस पहले शब्द को स्थान से बाहर खींचता है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.