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

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

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...]

Wagtail Index page not displaying objects of children

I am at my wits-end and feel I am missing something simple but I've looked at it over and over and can't figure it out.
I have a simple person_index_page that I want to show the child person_page objects, but no matter what I try...nothing. I have several sites with a similar setup and they work. Can you please look at my code below and see if you notice something I am missing? Thank you.
home_tags.py
# Person feed for home page and staff page
#register.inclusion_tag(
'home/tags/person_listing_homepage.html',
takes_context=True
)
def person_listing_homepage(context, count=3):
people = PersonPage.objects.live().order_by('?')
return {
'people': people[:count].select_related('feed_image'),
'request': context['request'],
}
person_index_page.html
{% extends 'base.html' %}
{% load wagtailcore_tags wagtailimages_tags home_tags %}
{% block content %}
...
{% include "home/tags/person_listing_homepage.html" %}
...
{% endblock %}
person_listing_homepage.html probably should name this at some point
{% for person in people %}
{% include "home/includes/person_list_item.html" %}
{% endfor %}
person_list_item.html
{% load wagtailcore_tags wagtailimages_tags %}
{# Individual person item in a list - used on people index and home page #}
<a class="list-group-item" href="{% pageurl person %}">
<div class="media">
{% if person.feed_image %}
<div class="media-left">
{% image person.feed_image width-200 as img %} <img class="media-object" src="{{ img.url }}"/>
</div>
{% endif %}
<div class="media-body">
<h4 class="media-heading">{{ person.first_name }} {{ person.last_name }}</h4>
{% if person.search_description %}
<p>{{ person.search_description }}</p>
{% endif %}
</div>
</div>
</a>
This is more of a "how to debug" question than a Wagtail one. Rather than just giving you the answer directly, here's the process I would take:
You say that adding print(people) inside the person_listing_homepage function doesn't display anything. So, your next question should be: "is this function being run at all?" Change the print statement to print("GOT HERE"). You'll find that this doesn't display anything either - which tells you that the function is not being run.
The next step would be to add some debugging output around the place where the function should be called from - if that doesn't get displayed either, you know that code isn't being run either, and you'd have to keep going up a level until you find something that is being run. So let's look for that place...
And this is where you find the problem. You never call the person_listing_homepage function anywhere in your code. You include the person_listing_homepage.html template, but that's not the same thing. person_index_page.html should become:
{% extends 'base.html' %}
{% load wagtailcore_tags wagtailimages_tags home_tags %}
{% block content %}
...
{% person_listing_homepage %}
...
{% endblock %}

extend other app to my template working

I want to extend an other template to my blog.html, no matter have i try to extend this, it doesn`t work .
blog/index.html
{% block nav %}
<ul id="nav">
<li>{% block nav-blog %}Blog{% endblock %}</li>
<li>{% block nav-photo %}Photo{% endblock %}</li>
</ul>
{% endblock %}
<div class="news">
{% block polls %}
{% extends 'polls/index.html' %}
{% endblock %}
<div>
polls/index.html
{% if latest_poll_list %}
<ul>
{% for poll in latest_poll_list %}
<li>{{ poll.question }}</li>
{% endfor %}
</ul>
{% else %}
<p>No polls are available.</p>
{% endif %}
Usually extends has to be stuck at the top of the template and not somewhere in the template.
In the template you use the tags that you have set up in the base templates.
You need to make sure you're doing two things here:
Declare a "nav" block in your index.html. This will let django know the part of your index html you wish to have overwritten when a template extends it. Anything you put inside the "nav" block in index html will be considered default content.
You need to use the "extends" template tag at the beginning of your blog.html so django knows the template you'd like to extend.
Like this:
index.html
{% block nav %}
<div>
Some default html here..
</div>
{% endblock %}
And then blog.html
{% extends index.html %}
{% block nav %}
<div>
This is what will render
</div>
{% endblock %}
Also, you're going to want to test index.html before trying to extend it to verify that django is finding that template. If it isn't then you need to add the directory that it is found in to the TEMPLATE_DIRS array in your settings.py file.

Django Templates: no output in template if statment

I have a base template with a header include in it. The header include contains the code below.
However for some reason I get no output in between the if block, any reason why? ps no errors. The rest of the template outputs just fine.
base.html
<body>
{% include 'includes/header.html' %}
{% block sliderWrapper %}{% endblock %}
{% block titleWrapper %}{% endblock %}
<div id="wrapper">
<div class="container">
{% block mainWrapper %}{% endblock %}
</div>
</div>
{% include 'includes/footer.html' %}
{% include 'includes/copyright.html' %}
{% include 'includes/js.html' %}
</body>
content of {% include 'includes/header.html' %} below.... everything shows just not the two login/logout links. take them out the block and they show. neither statement shows in the if
<div class="span9">
<div class="navbar navbar-inverse">
<div class="navbar-inner">
<a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
<div class="nav-collapse collapse">
<ul class="nav">
<li>Home</li>
<li><a href='{% url django.contrib.flatpages.views.flatpage url="how-it-works/" %}'>How does it work?</a></li>
<li><a href='{% url django.contrib.flatpages.views.flatpage url="how-it-works/" %}'>Download</a></li>
<li>Register</li>
{% if user.is_authenticated %}
<li>Logout</li>
{% else % }
<li>Login</li>
{% endif %}
</ul>
</div>
</div>
</div>
"django.contrib.auth.context_processors.auth" is installed and sessions in enabled.
If I output {{ user }} i get AnonymousUser which is what I except, so, one would assume the 'else' condition would fire, however neither conditions seem to be met.
The request context is being passed also...
return render_to_response('pageRegistration.html', context,context_instance=RequestContext(request))
I believe there's a syntax error in your code that passed by unnoticed:
{% else % }
should be:
{% else %}
Django template system probably looks for a regex {%...%}, and as that didn't match, it was regarded simply as text inside the {% if %}{% endif %} node.

How to make a reusable template in Django?

What is the Django way of creating a reusable template?
Example: Suppose a lot of my pages contain a "Latest News" box and following the DRY principle, I would like to define it once and reuse it in the other pages. How would I do this with Django (or Jinja2) templates?
Reading through Django's Template Documentation I get the impression that Django templates offer "top-down" inheritance where the sub-template itself determines in which super-template it is going to be embedded:
<!-- Super-template (not valid, for illustration): -->
<html>
<head><title>Title</title></head>
<body>{% block content %}{% endblock %}</body>
</html>
<!-- Sub-template: -->
{% extends "base.html" %}
{% block content %}
<div class="latest-news">News</div>
{% endblock %}
So what is the technique to reuse a block (a sub-template) in several places?
The most flexible way to reuse template fragments is to define an inclusion_tag. You can pass arguments to your custom tag, process them a bit in Python, then bounce back to a template. Direct inclusion only works for fragments that don't depend on the surrounding context.
Quick example from the docs:
In app/templatetags/poll_extras.py register the tag with a decoration:
from django import template
register = template.Library()
#register.inclusion_tag('results.html')
def show_results(poll):
choices = poll.choice_set.all()
return {'choices': choices}
In app/templates/results.html:
<ul>
{% for choice in choices %}
<li> {{ choice }} </li>
{% endfor %}
</ul>
Calling the tag:
{% load poll_extras %}
{% show_results poll %}
What you're looking for, is {% include "template.html"%} from Django docs.
If you need to use {% block %} you can only do that via the {% extend %} approach. Otherwise, you can use {% include 'some.html' %} to include a bit of HTML in multiple places.
The unofficial Django Reusable App Conventions recommends using these block names:
{% block title %}
{% block extra_head %}
{% block body %}
{% block menu %}
{% block content %}
{% block content_title %}
{% block header %} {% block footer %}
{% block body_id %} {% block body_class %}
{% block [section]_menu %} {% block page_menu %}
If everyone stuck to these conventions, it should make this problem easier. Follow the link to see the description of each block.
Example of using {% include %} tag
All data comes from Django back-end
Many values are passed to card_template.html using include tag in page1.html
card_template.html
<style>
.choices_div {
border-radius: 5rem;
}
.card-footer {
background-color: transparent;
border: transparent;
}
</style>
<div class="col mb-5 px-4">
<div class="card h-100 w-100 jumbotron choices_div {{ bg_color|default:'' }}">
<div class="card-body p-0">
<h3 class="card-title text-center">{{ card_title|capfirst }}</h3>
<ul class="card-text mt-3">
{% for c in card_body_list %}
<li>{{ c }}</li>
{% endfor %}
</ul>
</div>
<div class="card-footer text-center pt-4">
{% if get_post_request == 1 %}
<a class="btn btn-light" href="{{ href }}">{{ button_text }}</a>
{% else %}
<form method="post">
{% csrf_token %}
<button type="submit" class="btn btn-light w-75" name="category"
value="{{ button_value }}">{{ button_text }}</button>
</form>
{% endif %}
</div>
</div>
</div>
page1.html
{% extends 'core/core.html' %}
{% block body %}
<div class="jumbotron bg-white">
<div class="container">
<div class="mb-5 text-center">
<h1>Choose user category</h1>
<h5>Once choosen, the user category cannot be changed</h5>
</div>
<div class="row row-cols-lg-2 justify-content-around">
{% for object in object_list %}
{% cycle 'bg_peacock' 'bg_sunset' 'bg_skin' 'bg_brown' as bg_color silent %}
{% include 'core/card_template.html' with card_title=object.category card_body_list=object.description get_post_request=2 button_text='Select' bg_color=bg_color button_value=object.id %}
{% endfor %}
</div>
</div>
</div>
{% endblock %}
As other answers have mentioned, the simplest approach is direct inclusion:
{% include 'mytemplate.html' %}
It is possible to modify the context of the rendered template (Or in simpler terms, to pass variables to the template) using
{% include 'mytemplate.html' with poll=poll %}
To use the traditional polls example, the template I would write would be:
<div class="stylish-poll">
{% for choice in poll.choices %} <!-- poll is a template variable -->
{% include 'choice_template.html' with choice=choice %}
{% endfor %}
</div>
Another potentially useful thing to know is that the only keyword prevents the template variable poll being passed into 'choice_template.html' which it would be by default. If you do not want the choice template to have access to {{ poll }} then the include statement looks like:
{% include 'choice_template.html' with choice=choice only %}
Documentation: https://docs.djangoproject.com/en/dev/ref/templates/builtins/#include
Aïe, my fault – the answer is given in the Django Reference (and not discussed in the aforementioned Django Template Documentation)…
So: Just use {% include sub_template_name %}.
even though the question is asked years ago, any way I will show you the method that worked for me.
base.html
In your base template you need to define all of your blocks that you need to reuse in your other templates,
<html>
<head>
<meta name="description" content="{%block description%}{%endblock%}">
<meta name="keywords" content="{%block keywords%}{%endblock%}">
<title>{%block title%}{%endblock%}</title>
</head>
<body>
<!---other body stuff--->
{%block content%}
{%endblock%}
</body>
</html>
home.html
{%extends 'base.html'%}
<!--you can reuse all blocks here-->
{%block description%}Django reusable blocks, for every bage{%endblock%}
{%block keywords%}django,block, resuable,meta,title,{%endblock%}
{%block title%}django reuseable blocks for title, meta description and meta keywords{%endblock%}
{%block content%}
<div>
<h1> reuse blocks</h1>
</div>
{%endblock%}