Using content blocks in Django Template - django

I am having an issue when trying to make a generic template that is then extended into a child template.
Post.html
{% extends "blog\blog_base.html" %}
{% block title %} The Blog {% endblock %}
{% block menu %}
{% endblock %}
<h1>The Blogs Index Page</h1>
{% block content %}
<h2> Posts </h2>
{% for post in latest_post_list %}
<h3> {{ post.title }} </h3>
<p> {{ post.body|linebreaks }} </p>
{% endfor %}
{% endblock %}
blog_base.html
<body>
{% block menu %}
{% for menu in menu %}
{{ menu.page_name }}
{% endfor %}
{% endblock %}
<div class = "content">
{% block content %} <p> Place Holder </p> {% endblock %}
</div>
</body>
The block for the content works.
The block for the menu does not, it displays no page_name property of the menu object.
But if i insert ->
{% for menu in menu %}
{{ menu.page_name }}
{% endfor %}
straight into the Post.html template, it works. Oh it also automatically makes the menu a list as well which confuses me. Why does it make a list with bullet-points and not just print out each menu object on its own line?

By including the block tags in Post.html, you're overriding the menu in the base template. Remove the following from the post template:
{% block menu %}
{% endblock %}

Related

Is it okay to have two base.html templates in django?

Is it okay to have multiple base.html templates in django? For instance, I would have one template that would extend from base_one.html and another template extending from base_two.html. For example, this is one of the templates:
{% extends "base_one.html" %}
{% block content %}
{% endblock content %}
and this is another template:
{% extends "base_two.html" %}
{% block content %}
{% endblock content %}
Well not only two you can keep how much you want just with different names and you have to extend on different templates but yeah you can easily keep parts of the base template and extend in one according to your needs.
I'm adding three files here 1-base.html 2-base-comments.html 3-post-template.html
Here is a little expansion of my answer
Suppose this file name is base.html
# base.html
<html>
<head>
<title>Foo</title>
</head>
<body>
<header>
{% block header %}
<h1>Lorem ipsum</h1>
{% endblock %}
</header>
{% block content %}{% comment %}A wrapper around content is needed{% endcomment %}
<div class="page-content">
{% block page_content %}{% comment %} Filled in by your page templates {% endcomment %}
{% endblock %}
</div>
{% endblock %}
<footer>
{% block footer %}
<em>♥ joar</em>
{% endblock footer %}
</footer>
</body>
</html>
here is another file base-comments.html which extends the previous file.
# base-comments.html
{% extends 'base.html' %}
{% block content %}
<div class="page-content">
{% block page_content %}{% comment %} Filled in by your page templates {% endcomment %}
{% endblock %}
{% block comments %}
<footer>
<h2>Comments</h2>
<script>loadCommentsEtc()</script>
</footer>
{% endblock %}
</div>
{% endblock %}
And here is the last file which extends the 2nd base file which already extends the 1st base file 3-post-template.html
# post-template.html
{% extends 'base-comments.html' %}
{% block page_content %}
<article>
<h1>{{ post.title }}</h1>
<div class="post-body">
{{ post.body }}
</div>
</article>
{% endblock %}
I hope this works and clears your doubts.
Thanks for the question.

{% block something %} always being displayed despite being False in an if-statement

I have two types of blog articles. Regular blog articles, and translation articles. They both have different html markup. I have a boolean variable translation_bool in my models to check if it is a translation article or not. If it is I want it to display my {% block translation %} and if not {% block translation %}. It worked with plain html code and not using html tags. But I had so much reusable code that it got troublesome to manage.
So my question is: why is this happening despite it being inside of an if statement.
Article template:
{% extends "base_generic.html" %}
{% load static %}
{% block js %}...{% endblock %}
{% if blogpost.translation_bool == True %}
{% block translation %}....{% endblock %}
{% else %}
{% block content %}...{% endblock %}
{% endif %}
{% block sidebar %}....{% endblock %}
In Base Generic Template:
<div class="row">
<div class="col-md-1"></div>
<div class="col-md-8">
{% block content %}{% endblock %}
{% block translation %}{% endblock %}
</div>
<div class="col-md-3">
{% block social_media %}...{% endblock %}
{% block sidebar %}...{% endblock %}
</div>
</div>
</body>
This is because blocks not defined in child template will render value from parent template. So in your case you should perform validation inside parent template. Or if it's impossible override blocks in child with empty content:
{% block translation %}
{% if blogpost.translation_bool == True %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
{% block content %}
{% if blogpost.translation_bool == False %}
{{ block.super }}
{% else %}
{% endif %}
{% endblock %}
Note {{ block.super }} will render content from parent template.

Django: generate div class tag value with max value

I am trying to dynamically create div class tag value for my blocks in Django. I have comments tree and decided to create limit on max value for comment block (only in template not in db). So I created next template. It works fine, but has too big line and I can't insert any spaces and new line symbol, because they break template or keep in page html-source. This is line right after comment.
{% extends 'myblog/base.html' %}
{% load bleach_tags %}
{% block title %}{{ article.name|bleach }}{% endblock %}
{% block content %}
<h2>{{ article.name|bleach }}</h2>
<div class = "post_body_detail">
{{ article.text|bleach }}
</div>
<div class = "comments">
{% for comment in comment_list %}
<li>
{# (next line is too big) div class comment level can not be bigger max value for marking purposes #}
<div class = "comment{% if comment.level <= comment.MAX_COMMENT_DIV_BLOCK_DEEP %}{{comment.level}}{% else %}comment.MAX_COMMENT_DIV_BLOCK_DEEP{% endif %}">
{{ comment.text|bleach}}
</div>
</li>
{% empty %}
<li>No comments yet.</li>
{% endfor %}
</div>
{% endblock %}
How I can split this line for easier reading (format it)?
try this:
{% with max_deep=comment.MAX_COMMENT_DIV_BLOCK_DEEP %}
<div
{% if comment.level <= max_deep %}
class="comment{{ comment.level }}"
{% else %}
class="comment{{ max_deep }}"
{% endif %}
>
{{ comment.text|bleach}}
</div>
{% endwith %}

Djangocms template not showing up

I have a basic DjangoCMS up and running.
base.html contains:
{% block content %}{% endblock content %}
I also have feature.html:
{% extends "base.html" %}
{% load cms_tags %}
{% block title %}{% page_attribute "page_title" %}{% endblock title %}
{% block content %}
<div>
{% placeholder "feature2" %}
</div>
<div class="jumbotron"">
{% placeholder "feature" %}
</div>
<div>
{% placeholder "content" %}
</div>
{% endblock content %}
I added the "feature2" placeholder in the above, and it correctly displays for editing on the site.
I then added a new line to base.html:
{% block base_logo %}{% endblock base_logo %}
and created a new file, base_logo.html:
{% extends "base.html" %}
{% load cms_tags %}
{% block base_logo %}
<div>
{% placeholder logo %}
</div>
{% endblock base_logo %}
I expected this to also appear on the site for editing, but it doesnt. I have added the base_logo.html to the CMS_TEMPLATES in settings.py and TEMPLATE_DIR is also pointing correctly.
What else do I need to do for Djangocms to pick up my new template?
Take a look at template inheritance.
You're trying to use two {% extends %} tags, which won't work. You should use the {% include %} tag for base_logo, because it seems you'd want to include this in many templates. This question provides more info.

Django template rendering extend tag incorrectly

I have three Django templates:
base.html:
user_links.html
user_detail.html
I want user_links.html to extend base.html. Next, I want user_detail.html to extend user_links.html and base.html.
Here's base.html:
<head>
<title>Cool App</title>
<link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/main.css" />
</head>
<body>
<h1>Cool App</h1>
<div class="navbar">
<p>
HOME |
{% if user.is_authenticated %}
LOGOUT
{% else %}
LOGIN
{% endif %}</p>
{% block content %}
{% endblock %}
{% block pagination %}
{% endblock %}</div>
Here's user_links.html:
{% extends "base.html" %}
Yellow
Pink
Green
{% block content %}
{% endblock %}
And here's user_detail.html
{% extends "user_links.html" %}
{% block content %}
<h2>{{ object.username }}'s Profile</h2>
{% if object.userprofile.bio %}
{{ object.userprofile.bio }}
{% endif %}
{% endblock %}
So when the browser renders user_detail.html, I want it to (i) show the stylesheet and navigation links from base.html, (ii) show the word Yellow, Pink, Green from user_links.html, (iii) and show the user's username and bio. But (ii) is not being rendered at all, though (i) and (iii) are correctly rendering.
How should the templates be set up so that I see (i), (ii) and (iii) in user_detail.html? Please advise.
Note: all three templates reside in the same directory. I'm on Django 1.5
If you extends a base.html template, no content not surrounded by {% block %} will be rendered at all.
You could create additional {% block precontnet %}{% endblock %} in base.html, and wraps Pink/Yellow/Red in user_links.html
Or you can put Pink/Yellow/Red in {% block content %} if user_links.html and use {{ block.super }} in user_detail.html
links.html
{% extends "base.html" %}
{% block content %}
Yellow
Pink
Green
{% endblock %}
user_detail.html
{% extends "user_links.html" %}
{% block content %}
{{ block.super }}
<h2>{{ object.username }}'s Profile</h2>
{% if object.userprofile.bio %}
{{ object.userprofile.bio }}
{% endif %}
{% endblock %}
Place div after </p> in base.html
<h1>Cool App</h1>
<div class="navbar">
<p>
HOME |
{% if user.is_authenticated %}
LOGOUT
{% else %}
LOGIN
{% endif %}</p>
</div>
Try this in user_links.html
{% extends "base.html" %}
{% block content %}
Yellow
Pink
Green
{% endblock %}