Django - Change active navbar template based on webpage - django

I have a template that looks like this in my html. It uses the bootstrap classes.
<-- navbar-template.html>
<div class="collapse navbar-collapse" id="myNavbar">
<ul class="nav navbar-nav">
<li>Home</li>
<li class='active'>Members</li>
<li>Research</li>
<li>Publications</li>
<li>Links</li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li><span class="glyphicon glyphicon-log-in"></span> Login</li>
</ul>
</div>
I like the active class but I need the to change which list object it is based on which page from the navbar django has loaded.
I think you'd like to do something like this in the home.html file
<-- HOME -->
{% include "navbar_template.html" with page="home"} %}
###Do something with {{page}} variable in order to set the home list tag to active.
Do I have to write a crazy amount of if else statements or is there an easier way. Perhaps something with the views.py in django

You can do it like this (example solution I use on my page):
<ul class="sidebar-nav--primary">
{% url 'main:home' as home %}
{% url 'main:work' as work %}
{% url 'main:personal' as personal %}
<li><a href="{{ home }}" {% if request.path == home %}class="active"{% endif %}>Home</a></li>
<li><a href="{{ work }}" {% if request.path == work %}class="active"{% endif %}>Work</a></li>
<li><a href="{{ personal }}" {% if request.path == personal %}class="active"{% endif %}>Personal</a></li>
</ul>

A cleaner method would be creating a custom template tag. Something like is_active:
# Inside custom tag - is_active.py
from django.template import Library
from django.core.urlresolvers import reverse
register = Library()
#register.simple_tag
def is_active(request, url):
# Main idea is to check if the url and the current path is a match
if request.path in reverse(url):
return "active"
return ""
And use it in your templates like this:
# template.html
{% load is_active %}
<li>Home</li>

Related

Active nav-item highlighting based on pk passed in url

I have 4 nav-items being generating dynamically based on the Django Model entries.
My template code is as below:
{% for stockbroker in stockbrokers %}
<li class="nav-item">
<a class="nav-link" href="{% url 'broker:display_stocks' stockbroker.id %}" id="nav">{{ stockbroker.broker_name }}
</a>
</li>
{% endfor %}
I want to highlight the currently active nav based on the id I am passing in the url section of the a tag href. Is it possible to achieve this?
I am generating these nav links in the base.html using context_processors.py
from .models import StockBroker
def stockbrokers(request):
return {'stockbrokers': StockBroker.objects.all()}
An if condition should work for this:
{% for stockbroker in stockbrokers %}
<li class="nav-item">
<a class="nav-link {% if stockbroker.id == current_id %}active{% endif %}" href="{% url 'broker:display_stocks' stockbroker.id %}" id="nav">{{ stockbroker.broker_name }}
</a>
</li>
{% endfor %}
Note: current_id (or variable name of your preference) should be passed in the context.
The context is the dictionary that is passed while rendering the template, example:
def my_view(request):
# View Code
return render(request, 'template_name.html', {'current_id': current_id})

How to loop through urls in a template

I have a load of URLs I want to declare as constants so I can use them in for and if statements in a template. At the moment I do this manually e.g.:
{% url 'inbox' as inbox %}
{% url 'sent' as sent %}
{% url 'drafts_tasks' as drafts_tasks %}
However this feels kinda clunky and when the urls increase in numbers it is a load of extra code repeated on every template.
Is there a better way I can loop through urls and declare them?
Here's an example of how I want to use them:
{% url 'XXX' as XXX %}
{% for ....
<li class="nav-item {% if request.path == XXX %}active{% endif %}">
<a class="nav-link" href="{{ XXX.url }}">{{ XXX.name }}
</a>
</li>
endfor %}
The easiest option would be to pass the urls as a list.
class URLView(TemplateView):
template_name = 'urls.html'
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
context['urls'] = get_my_list_of_urls()
return context
As for the repeated code you could make use of the include template tag.
Create a file with the repeating template fragment templates/includes/url_link_list.html:
<li class="nav-item {% if request.path == xxx %}active{% endif %}">
<a class="nav-link" href="{{ xxx.url }}">{{ xxx.name }}</a>
</li>
Then in your urls.html file that was defined in your view you will include that fragment:
<ul>
{% for url in urls %}
{% with url as xxx %}
{% include 'includes/url_link_list.html' %}
{% endwith %}
{% endfor %}
</ul>

Django - passing flatpage.title variable as part of an include

I'm using Django flatpages and trying to pass the title of a flatpage as part of an html include.
{% block navbar %}
{% include 'navbar.html' with active='{{flatpage.title}}' %}
{% endblock %}
This is so I can highlight the whereabouts in the navigation bar.
<ul class="nav navbar-nav">
<li class="{% if active == 'home' %}active{% endif %}">Home</li>
etc.
</ul>
It doesn't appear to render correctly. Whereas if I replace {{flatpage.title}} with a hard-coded value ie. 'home' it works just fine.
{% block navbar %}
{% include 'navbar.html' with active='home' %}
{% endblock %}
Am I not able to do this?
I'm not clear on a way to debug Django templates to check for these values... The way I'm currently checking that the variable is passing the right value is simply to reference {{flatpages.title}} elsewhere, separately in the html - which appears to render the correct 'home' value I'd expect.
<div id="navbar" class="navbar-collapse collapse">
<ul class="nav navbar-nav">
<li class="{% if active == 'home' %}active{% endif %}">Home</li>
{{flatpage.title}}
etc.
</ul>
</div>
You do not need to surround arguments in {{ }} brackets in template tags.
If it's a variable, not a string, then do not use "" quotes.
The following should work:
{% block navbar %}
{% include 'navbar.html' with active=flatpage.title %}
{% endblock %}
see include section to more informations

Share same pagination code for different views in Django

I'm building a simple blog app using Django.
This app has a main template blog.html which is shared between the following views:
blog (url: /blog/[page number])
Main page of the blog, displays the last articles
search (url: /search/<query>/[page number])
Will display the articles who match the query
category (url: /category/<category name>/[page number])
Will display the articles from the given category
Each a this views provides the template blog.html with an object page obtained using the function Paginator each time with a different objects list (depending on the view).
Here is my problem:
The template blog.html contains a pager
<ul class="pager">
{% if page.has_previous %}
<li class="previous">
<a href="{{ url_previous_page }}" class="btn btn-primary" >← Older</a>
</li>
{% endif %}
{% if page.has_next %}
<li class="next">
<a href="{{ url_next_page }}" class="btn btn-primary" >Newer →</a>
</li>
{% endif %}
</ul>
How can I define in an elegant way the values of url_next_page and url_previous_page in all the views?
You shouldn't really need to supply the links for the next and previous buttons like that. I would suggest changing your pagination code to be something like this:
<div class="pagination-wrap">
<span class="pagination-links">
{% if page_obj.has_previous %}
{% endif %}
<span class="current">
{{ page_obj.number }} of {{ page_obj.paginator.num_pages }}
</span>
{% if page_obj.has_next %}
{% endif %}
</span>
<div>{{ page_obj.start_index }} to {{ page_obj.end_index }} of {{ page_obj.paginator.count }}</div>
</div>
In your views, all you need to specify is the number of objects to paginate by with paginate_by = 15.
If you really want to, you could create a mixin for your list views to use which has a method that could return the url you want.

How to use the Django Usurena "mugshot" template variable

I'm trying to use Userena in our Django website, but I can't seem to figure out how to use the template tag to display the mugshot. I have tried the following to spit out the URL within an image tag:
<img src="{{ owner_profile.get_mugshot_url }}">
and
<img src="{{ profile.get_mugshot_url }}">
Anyone have some insight??
Thanks!
based on alican answer, just put following code in your template:
<img src="{{ user.get_profile.get_mugshot_url }}" />
Use the following code to display Userena profile image(mugshot) in your template. Use appropriate username to filter the required user.
views.py
from django.shortcuts import get_object_or_404
from django.contrib.auth.models import User
def my_view(request):
profile = get_object_or_404(User, username__iexact=username).get_profile()
return render_to_response('template.html', locals(), context_instance=RequestContext(request))
Here I have rendered this variable "profile" to the template "template.html". Include following code in your template to display mugshot image.
template.html
<img src="{{ profile.get_mugshot_url }}" />
It worked for me. Hope it will work for you too. Thanks.
Try this:
{{ user.get_profile.get_mugshot_url }}
Here's the way it worked for me:
{{ user.get_profile.get_mugshot_url }}
But make sure you use render as opposed to render_to_response for each of the pages that you'll be pulling it in (ex: views.py):
from django.shortcuts import render
return render(request, 'sometemplate.html', {"name": "some_var"}, )
Here's how I did it, pulling in the mugshot for the navbar dropdown (ex: sometemplate.html):
<ul class="nav pull-right">
{% if user.is_authenticated %}
<li class="dropdown">
<a href="#" class="dropdown-toggle user-dropdown" data-toggle="dropdown">
<img class="user-thumbnail img-circle" src="{{ user.get_profile.get_mugshot_url }}" alt="" />
Hi, {{ user.username }}
<b class="caret"></b></a>
<ul class="dropdown-menu">
<li><i class="icon-wrench"></i> Profile</li>
<li class="divider"></li>
<li><i class="icon-off"></i> Log Out</li>
</ul>
</li>
{% else %}
<li>Log in</li>
{% endif %}
</ul>