extending parent django template, as well as including a variable - django

I have a base template that I'm trying to extend. With in that template I have a navigation that needs a variable passed.
What I was doing was trying to 'extend' it by using an include like so:
{% include "base.html" with active_nav='atInventory' %}
but this doesn't render the blocks of the base with the extended content in the right order.
The navigation is set up in the base like so:
<nav class="col-xs-12 paddingVertical-sm">
<ul class="removePadding removeMargin txtXxs">
<li class="{% if active_nav == 'atContact' %} activeNav {% else %} inactiveNav{% endif %}">
<a href="{% url 'contact' %}">CONTACT<a>
</li>
<li class="{% if active_nav == 'atAbout' %} activeNav {% else %} inactiveNav{% endif %}">
ABOUT
</li>
<li class="{% if active_nav == 'atProjects' %} activeNav {% else %} inactiveNav{% endif %}">
PROJECTS & CLINICS
</li>
<li class="{% if active_nav == 'atServices' %} activeNav {% else %} inactiveNav{% endif %}">
SERVICS
</li>
<li class="{% if active_nav == 'atInventory' %} activeNav {% else %} inactiveNav{% endif %}">
INVENTORY
</li>
<li class="{% if active_nav == 'atHome' %} activeNav {% else %} inactiveNav{% endif %}">
HOME
</li>
<br class="clear-fix">
</ul>
<img src="{% static 'images/assets/klossviolins_logo.png' %}" />
<br class="clear-fix">
</nav>
Is there a better way to do this? Or does this just require a slight tweak? Thanks in advance for any help on this.

nI wouldn't do this - extend it the way it was intended. Include is for including reusable components. Here you just want every template to extend your 'base.html' with {%extends 'base.html'%}
Just a pointer as well - I'd do the active nav with a tiny script instead of tons of if statements. So add an ID to each li element (#nav-home for index in my example), and on your home page have something like:
<script>
$(document).ready(function() {
$( "#nav-home").addClass("activeNav");
});
</script>

Related

Django add language code to url in html if condition

I have a navbar that shows active when it is in the current section. I have internationalised the web so now the url includes the language code. How can I add the language code in the if condition below?
{% if '/{LANGUAGE_CODE}/accounts/dashboard/' == request.path %} active {% endif %}
webpage url: http://127.0.0.1:8000/en/accounts/dashboard
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<aside class="col-md-3">
<!-- SIDEBAR -->
<ul class="list-group">
<a class="list-group-item {% if '/{LANGUAGE_CODE}/accounts/dashboard/' == request.path %} active {% endif %}" href="{% url 'dashboard' %}"> Dashboard </a>
[continues...]
I tried {{LANGUAGE_CODE}} and some pasting. Any ideas how to get the if condition working?
You can use add filter to concatenate your strings and with tag to cache this complex variable. The result would look like this:
{% load i18n %}
{% get_current_language as LANGUAGE_CODE %}
<aside class="col-md-3">
<!-- SIDEBAR -->
<ul class="list-group">
{% with "/"|add:LANGUAGE_CODE|add:"/accounts/dashboard/" as dashboard_url %}
<a class="list-group-item {% if dashboard_url == request.path %} active {% endif %}" href="{% url 'dashboard' %}"> Dashboard </a>
{% endwith %}
[continues...]

How to fetch and display data from Django Model without invoking the URL

I have a Class-Based ListView as shown below:
class JobByStateView(ListView):
model = State
template_name = 'jobs/jobs_by_state.html'
context_object_name = 'state_list'
ordering = ['name']
paginate_by = 15
I have added the path to urls.py file as shown below:
path('jobs/', JobByStateView.as_view(), name='job-by-state'),
And this how my template looks:
<div class="row">
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% for state in state_list %}
{% if forloop.counter|divisibleby:"5" == False %}
<li>
{{state.name}}
</li>
{% else %}
<li>
{{state.name}}
</li>
</ul>
</div>
<div class="col-md-4">
<ul class="list-unstyled mb-0">
{% endif %}
{% endfor %}
</ul>
</div>
</div>
When I try to access this templates via the url (http://localhost:8000/jobs) it works as expected and displays the data on the screen. But when I try embed this template within another template as shown below, nothing gets displayed on the web page.
{% include 'jobs/jobs_by_state.html' %}
I would like to display this template as a widget within another template.
Really appreciate, if anyone could please help me in fixing this issue.
Thank you so much in advance for your time and help!
=========================================================================
The other page template is:
{% extends 'base.html' %}
{% block page_content %}
{% include 'carousel.html' %}
{% for job in job_list %}
<div class="listing-wrapper">
<div class="listing-container border-top border-bottom">
<a href="{{ job.get_absolute_url }}">
<h2 class="heading mt-3 mb-1 mx-2 d-inline-block">{{ job.title}}</h2>
</a>
</div>
</div>
{% endfor %}
{% if is_paginated %}
<ul class="pagination justify-content-center my-4">
{% if page_obj.has_previous %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.previous_page_number}}">← Previous Page</a>
</li>
{% endif %}
{% if page_obj.has_next %}
<li class="page-item">
<a class="page-link bg-dark text-white" href="?page{{page_obj.next_page_number}}">Next Page →</a>
</li>
{% endif %}
</ul>
{% endif %}
{% include 'jobs/jobs_by_state.html' with state_list=state_list %}
{% endblock page_content %}
{% block page_sidebar %}
{% include 'simple_search_widget.html' %}
<!-- Social Sharing Buttons -->
<div class="sharethis-inline-share-buttons mt-4"></div>
<!-- Newsletter Widget -->
{% include 'newsletter_widget.html' %}
{% endblock page_sidebar %}
The view for the parent template is as shown below:
class JobList(ListView):
model = Job
template_name = "jobs/job_listings.html"
context_object_name = "job_list"
ordering = ['-published_date']
paginate_by = 10
The following solution from #Charnel and #ChidG worked.
#Shahzan, ok, well you are referring to that variable in your template like this: {% include 'jobs/jobs_by_state.html' with state_list=state_list %}. So if the variable isn't in the context, it can't be passed to the included template, and so the included template won't display anything.

Django TemplateError when using if...else block inside for loop

I have the following as part of my django template:
<nav>
<ul class="pagination">
{% if page.has_previous %}
<li>
<a href="{% url 'main:stream_detail' stream_id=stream.id %}?p={{page.next_page_number}}" aria-label="Previous">
<span aria-hidden="true">«</span>
</a>
</li>
{% else %}
<li class="disabled" aria-label="previous"><span aria-hidden="true">«</span></li>
{% endif %}
{% for i in paginator.page_range %}
(% if i == page.number %}
<li class="active">{{i}} <span class="sr-only">(current)</span></li>
{% else %}
<li>{{i}}</li>
{% endif %}
{% endfor %}
{% if page.has_next %}
<li>
<a href="{% url 'main:stream_detail' stream_id=stream.id %}?p={{page.next_page_number}}" aria-label="Next">
<span aria-hidden="true">»</span>
</a>
</li>
{% else %}
<li class="disabled" aria-label="next"><span aria-hidden="true">»</span></li>
{% endif %}
</ul>
</nav>
And I'm getting the following exception:
Invalid block tag on line 26: 'else', expected 'empty' or 'endfor'. Did you forget to register or load this tag?
Line 26 corresponds to the {% else %} clause inside the {% for %} loop. As fas as I can tell, this else clause correctly matches up with the if statement, but the template parser seems to expect a clause to match the for loop there.
You have a syntax error with the if tag in the for loop:
(% if
...should be
{% if
You used '(' instead of '{' on line (% if i == page.number %}

Active Menu using Django passing it along templates

This example at http://djangosnippets.org/snippets/2421/ works as it is.
Placed in templates/includes/tabs.html
<ul class="tab-menu">
<li class="{% if active_tab == 'tab1' %} active{% endif %}">Tab 1</li>
<li class="{% if active_tab == 'tab2' %} active{% endif %}">Tab 2</li>
<li class="{% if active_tab == 'tab3' %} active{% endif %}">Tab 3</li>
</ul>
Placed in your page.html template
{% include "includes/tabs.html" with active_tab='tab1' %}
The variable gets passed along from page template to tabs.html.
How would you pass active tab variable from:
- page.html (pass active tab1)
- extends base.html
- includes tabs.html (how to get it here.)
In your base.html you could have your {% block tabs %}:
{% block tabs %}{% endblock %}
And in your page.html:
{% extends "base.html" %}
{% block tabs %}
{% include "includes/tabs.html" with active_tab='tab1' %}
{% endblock %}
If this isn't enough DRY for you you can maybe crate a custom inclusion tag for your tabs.

Using cycle to Django?

I am developing a Django application, i had some problem,
I hope to do the following effects on Django,
<div id='cssmenu'>
<ul>
<li class='active'><a href='#'><span>Home</span></a></li>
<li><a href='#'><span>Products</span></a></li>
<li><a href='#'><span>Company</span></a></li>
<li class='last'><a href='#'><span>Contact</span></a></li>
</ul>
</div>
Django Code,
<div id='cssmenu'>
{% for child in children %}
{% cycle 'active' 'last' as cssmenu silent %}
<li class="{{ cssmenu }}">
{{ child.get_menu_title }}
{% if child.children %}
<ul>
{% show_menu from_level to_level extra_inactive extra_active template "" "" child %}
</ul>
{% endif %}
</li>
{% endfor %}
</div>
Could you help me?
That's not what cycle is for: it's for alternating between two or more alternatives. You don't want that at all.
Instead, just use the forloop attributes:
{% for child in children %}
<li class="{% if forloop.first %}active{% elif forloop.last %}last{% endif %}">...</li>
{% endfor %}
Although I suppose you don't want the first one to always be active, but you haven't given any information about how you do want to determine where 'active' goes.