45š
Have you tried the {% with %} template tag?
{% block content %}
{% with 'myvar' as expectedVarName %}
{{block.super}}
{% endwith %}
{% endblock content %}
9š
Thereās no direct way to pass a variable up the template inheritance tree the way you describe. The way that people implement navigation bars that highlight the current page is often tweaked to the nature of the site itself. That said, Iāve seen two common approaches:
The low-tech approach
Pass a variable in the template context that indicates which tab is active:
# in views.py
def my_view(request):
return render_to_response('app2_template.html', {"active_tab": "bar"},
<!-- Parent template -->
<div id="navigation">
<a href="/foo" {% ifequal active_tab "foo" %}class="active"{% endifequal %}>Foo</a>
<a href="/bar" {% ifequal active_tab "bar" %}class="active"{% endifequal %}>Bar</a>
</div>
The higher-tech approach
Implement a custom template tag to render your navigation bar. Have the tag take a variable that indicates which section is active:
<!-- Parent template -->
<div id="navigation">{% block mainnav %}{% endblock %}</div>
<!-- any child template -->
{% load my_custom_nav_tag %}
{% block mainnav %}{% my_custom_nav_tag "tab_that_is_active" %}{% endblock %}
You can pretty much go crazy from there. You may find that someone has already implemented something that will work for you on djangosnippets.org.
- [Django]-Django sending email
- [Django]-Manually logging in a user without password
- [Django]-How can I turn Django Model objects into a dictionary and still have their foreign keys?
3š
Inability to pass args on template inclusion is one of many failings of the Django template system.
I had to deal with an almost identical problem: Deeply nested templates needed to cause parent templates to format/highlight differently.
Possible solutions:
-
Use a āsuper contextā routine that sets a number of values based on where in the hierarchy you are. I.e. super_context = MySuperContext(request, other, values, etc.), where super_context is a dict you pass to the view (or to RequestContext). This is the most Django-thnonic(?) approach, but it means that presentation logic has been pushed back into the views, which feels wrong to me.
-
Use the expr template tag to set values in the lower level templates. Note: this only works when you {% include %} a template because it must be evaluated before the inclusion occurs. You canāt do that with an {% extends %} because that must be the first thing in the child template.
-
Switch to Jinja2 templating, at least for the views where you need to do this.
Once you have these values set you can do things like this:
<div class="foo{% if foo_active%}_active{%endif%}"> stuff </div>
This makes the div class āfooā when itās not active and āfoo_activeā when it is. Style to taste, but donāt add too much cinnamon. š
- [Django]-Programmatically using Django's loaddata
- [Django]-Django ā two views, one page
- [Django]-How to fix VersionConflict locking failure in pipenv?
2š
I have taken Jarret Hardieās ālow techā approach in a similar, errā¦ context (yes, itās a punā¦ which wonāt make perfect sense to you unless I tell you that I was not doing navs but setting the border color of buttons in order to show which one had been pressed).
But my version is a bit more compact I think. Instead of defining just one simple context variable activebar in the view, I return a dictionary, but always with only one key-value pair: e.g. activebar = {āfooā: āactiveā}.
Then in the template I simply write class=ā{{activebar.foo}}ā in the foo anchor, and correspondingly in the other anchors. If only activebar.foo is defined to have the value āactiveā then activebar.bar in the bar anchor will do nothing. Maybe āfail silentlyā is the proper Django talk. And Bobās your uncle.
EDIT: Oopsā¦ a couple of days have passed, and while what I had written above did work for me a problem appeared when I put into the navbar an anchor with a new window as target. That seemed to be the cause of a strange glitch: after clicking on the new window (tab in Firefox) and then returning to the one from which the new window was launched, portions of the display below the navbar became blank whenever I quickly moved the cursor over the items on the navbarā without clicking on anything. I had to force a screen redraw by moving the scroll bar (not a page reload, though that too worked because it involves a screen redraw).
Iām much too much of a noob to figure out why that might happen. And itās possible that I did something else that caused the problem that somehow went away. Butā¦ I found a simpler approach thatās working perfectly for me. My circumstances are that every child template that is launched from a view should cause an associated navbar item to be shown as āactiveā. Indeed, that navbar item is the one that launched the view that launched the child templateā the usual deal.
My solutionā letās take a āloginā navbar item as an exampleā is to put this in the child template that contains the login form.
{% block login %}active{% endblock %}
I put it in below the title block but I donāt suppose the placement to matter. Then in the parent template that contains the navbar definition, for the li tag that surrounds the anchor for the login navbar item I putā¦ well, hereās the code:
<li class="{% block login %}{% endblock %}"><a href="/mysite/login">Login</a></li>
Thus when the child template is rendered the parent will show the login navbar item as active, and Bobās still your uncle.
The dictionary approach that I described above was to show which of a line of buttons had been pressed, when they were all on the same child template. Thatās still working for me and since only one child template is involved I donāt see how my new method for navbars would work in that circumstance. Note that with the new method for navbars views arenāt even involved. Simpler!
- [Django]-Phpmyadmin logs out after 1440 secs
- [Django]-How does manage.py work?
- [Django]-What's the recommended approach to resetting migration history using Django South?
1š
Variables from the parent template are automatically included in the childās scope. Your title says you want to pass a variable TO the parent, which doesnāt make sense, as you canāt define variables in templates. If you need it a variable in the both the parent and the child, just declare it in the view.
- [Django]-Django ā Site matching query does not exist
- [Django]-Django queries ā id vs pk
- [Django]-How do I remove Label text in Django generated form?
1š
Sadly I canāt find a clean way.
Ended up putting a tag in each appās base.html:
<span class="main_nav_bar_hint" id="2"></span>
(Actually I use two. One set by appās base for the main nav. One set by app pages for appās nav bar)
And a bit of JQuery magic in the project base.html
$(document).ready(function() { $("#nav_menu_" + $(".main_nav_bar_hint").attr("id")).removeClass("normal").addClass("selected"); })
Its a bit of a hack, but this way its easy to understand and I only need to make logical changes once more apps are added.
- [Django]-How do you skip a unit test in Django?
- [Django]-Setting expiration time to django password reset token
- [Django]-Change clickable field in Django admin list_display
-1š
You can use HttpRequest.resolver_match.
In the parent html template:
<li class="nav-item {% if request.resolver_match.view_name == 'my_simple_blog:homepage' %}active{% endif %}"><a href="{% url 'my_simple_blog:homepage' %}" class="nav-link">Home</a></li>
<li class="nav-item {% if request.resolver_match.view_name == 'my_simple_blog:about' %}active{% endif %}"><a href="{% url 'my_simple_blog:about' %}" class="nav-link">About</a></li>
It checks for the current namespace and compare it, if they are the same, add active in the class of the list.
- [Django]-Returning custom message when a permission is denied in DRF
- [Django]-Django ALLOWED_HOSTS: OK to include 'localhost' on a deployed settings file?
- [Django]-New url format in Django 1.9