9👍
I’m assuming each tab is a list item in your template base.html
.
<ul>
<li>Tab 1</li>
<li>Tab 2</li>
...
</ul>
Add an extra block to each li
.
<ul>
<li class="{% block class_tab1 %}inactive{% endblock %}">Tab 1</li>
<li class="{% block class_tab2 %}inactive{% endblock %}">Tab 2</li>
<li class="{% block class_tab3 %}inactive{% endblock %}">Tab 3</li>
...
</ul>
Then in your template if tab 1 is to be selected:
{% extends "base.html" %}
{% block class_tab1 %}active{% endblock %}
...
So the html rendered for Tab 1 is:
<ul>
<li class="active">Tab 1</li>
<li class="inactive">Tab 2</li>
<li class="inactive">Tab 3</li>
...
</ul>
and you can write CSS to target the li .active
as you wish.
1👍
A version of #1 will do the trick — with a separate template file for the tag.
Lets say you have the models “Category” and “Article”.
class Category(models.Model):
title = models.CharField(_("Name"), max_length=200)
introduction = models.TextField(blank=True, null=True)
slug = models.SlugField(help_text=_("Used for URLs"))
sort_order = models.IntegerField(_("Sortierung"))
class Article(models.Model):
title = models.CharField(_("Full Name"), max_length=255)
slug = models.SlugField(_("Slug Name"), unique=True, help_text=_("This is a short, descriptive name of article that will be used in the URL link to this item"))
text = models.TextField(_("Text of Article"), blank=True, null=True)
category = models.ForeignKey(Category)
in your views you would pass the category you are viewing to the template:
@render_to('cat_index.html')
def category_view(request,string):
cat = Category.objects.get(slug=string)
articles = Article.objects.filter(category = cat).order_by('date')
return {
'articles':articles,
'category':cat,
}
(Note: using the annoying render_to
-decorator – same as render_to_response
)
and in your template you call a inclusion_tag like this:
@register.inclusion_tag('snippets/navigation.html')
def navigation(cat=None):
return {'cats':Category.objects.order_by('sort_order'),
'cat':cat
}
by using this in your base-template (often called base.html)
{% navigation category %}
Now in the inclusions_tags’s template (snippets/navigation.html
) you would for-loop over cats
and if one of it equals cat
you can assign other styles
<ul>
{% for c in cats %}
<li{% ifequal c cat %} class="active"{% endifequal %}>
<a href="{{c|url}}">{{ c }}</a>
</li>
{% endfor %}
</ul>
1👍
This is a rather common problems and I’ve come up with some various ways to solve it.
Since you’re asking for options, here’s 3 other alternative ways achieve this effect. The options you mentioned and these listed below all have thier positives and negatives. It’s really up to you to decide which is a best fit.
Alternate 1 – Use Regular Expressions and a Hash Table
This could be performed either client-side (less advantageous) or server-side (a better pick). To do this you could have a tag that had 1 input: a regular expression. In use it would look like this…
// In base.html...
<li class="tab {% is_tab_active r'^/cars/' %}"><a>Cars</a></li>
<li class="tab {% is_tab_active r'^/trucks/' %}"><a>Trucks</a></li>
The custom tag applies the regular expression against the current page being viewed. If successfull, it adds a css class “active” if not “inactive” (or whatever your CSS classes are).
I’ve been pondering this method for a while. I feel as if there should be some good way to come up with a way to tie it into urls.py, but I haven’t seen it yet.
Alternate 2 – Use CSS
If you were to identify each [body] tag, or at least have a common template for the sections of your site, CSS could be used to assign which was active. Consider the following:
body.cars_section .navigation #cars_tab { color: #00000; }
body.truck_section .navigation #trucks_tab { color: #00000; }
For your base template…
<body class="{% block category %}{% endblock %}">
...
<ul class="navigation">
<li id="cars_tab"><a>Cars</a></li>
<li id="trucks_tab"><a>Trucks</a></li>
Then for any page you simply put the category it’s a part of (matching the CSS rule)…
{% extends "base.html" %}
...
{% block category %}cars_section{% endblock %}
Alternate 3 – Have Some Bloated Middleware
Django lets you write Middleware to affect the behavior of just about whatever you want. This seems like a bloated and complex route with potential negative performance impact, but I figured I’d at least mention it as an option.