base.html contains {% extends 'base.html' %}? - django

I'm trying the django-cms tutorial,
There is something I don't understand at the end of this part :
I have to add a template at /mysite/templates/polls/base.html. But this file has to begin with {% extends 'base.html' %}.
Is that normal? Is the file this line refers to an other base.html file? The one in the parent directory perhaps? I'm not sure at all.
Thank you for your help.

Extending from a base.html like that would suggest, like I do, that you have a base.html file at the root template directory of your project to handle the core markup;
{% load cms_tags menu_tags sekizai_tags cache i18n %}
{% load static from staticfiles %}
<head>
<meta charset="utf-8">
{% block head %}{% endblock head %}
<title>
<script type="text/javascript"
src="{% static 'project/external/jquery-1.11.2.min.js' %}"></script>
{% render_block "css" %}
{% render_block "js" %}
{% block styles %}{% endblock styles %}
{% block scripts %}{% endblock scripts %}
</head>
<body>
{% cms_toolbar %}
{% block content %}
{% endblock content %}
{% block footer-scripts %}{% endblock footer-scripts %}
</body>
</html>
That way, when you setup templates in your apps you can start with a base.html for that app which may extend the base blocks for the head tag or elsewhere.
Usually I have a setup similar to myproj/templates and then app templates like myproj/project/templates and myproj/app1/templates. That first templates dir sits next to manage.py and I use the project dir to hold settings & any templates specific to that project like types of CMS page; article.html etc.
You don't have to extend base.html but if you don't, then you need to recreate all that markup again so by using this template model you'll be able to limit repeated markup.

Related

Django; How to debug {% include '' %} tag within templates

Sometimes I get an empty string returned for my include tags which is impossible, because I have some static elements in it.
This is happening sometimes in my productive environment. How can I debug such an issue?
For example my footer or header disappears in some cases (Which I include within my "base.html") which I can't reproduce.
Thx
Example:
base.html
<html>
...
{% include "subdir/_header.html" %}
...
{% block content %}
<h1>Default Content</h1>
{% endblock %}
...
{% include "subdir/_footer.html" %}
</html>
home.html
{% extends "base.html" %}
{% block content %}
<h1>Home related Content</h1>
{% endblock %}
So if I load home.html my footer sometimes disappears. No idea why, no errors.
FOUND THE PROBLEM
A missing static file caused that kind of problem. Unfortunately I did not get an error.
I don't know the exact reason of this issue, but can you try with {% extends 'base.html' %}.
The difference between include and extends right here:
{% include %} vs {% extends %} in django templates
Your base html should be Extended and not Included... include is for small blocks of codes, like components... blog post, news, contact and that stuffs
base html
{% load static %}
<!DOCTYPE html>
<html lang="en-US">
{% include 'path/head.html' %}
{% block content %}{% endblock %}
{% include 'path/footer.html' %}
</html>
other pages
{% extends 'base.html' %}
{% load static %}
{% block content %}
<!-- Content from each page -->
{% endblock %}
Obs.: Include inside of includes dont work propely, you can get the data from first page in includes inside includes... for that i usualy use templatetags or context_processors, depending of your need.
Use django-debug-toolbar to debug your entire application in dev environment, you can see the entire request and the includes that you want
https://django-debug-toolbar.readthedocs.io/en/stable/

External JS in Django apps best practice

I have two pages that extends a base template. Each page has their own external js which i need to load. For the time being, i have put both of them before closing body tag in the base which means that both JS are loaded on both pages. How is it possible to load specific JS for specific page?
Yes you can do it:
1. base.html
<html>
<head>
<title>Foobar</title>
</head>
<body>
{% block content %}{% endblock %}
{% block js %}{% endblock %}
</body>
</html>
2. yourpage.html
{% extends "base.html" %}
{% load staticfiles %}
{% block content %}
<p>your content!</p>
{% endblock %}
{% block js %}
<script src="{% static 'js/foobar.js' %}"></script>
{% endblock %}

Jinja2 use variable from parent template

Image a base template like this:
{% set styles = [] %}
<!DOCTYPE html>
<html>
<head>
{% for style in styles %}
<link href="{{style}}" ref="stylesheet" type="text/css; charset=utf8">
{% endfor %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
I want to append to the styles variable from a child-template, but it will yield "styles is undefined".
{% extends "base.html" %}
{% do styles.append("index.css") %}
One solution to this would be to define the styles as an empty list when rendering the template from the Python code. But I do not want to add styles=[] to every template I render.
Unfortunately, importing doesn't work either. It won't tell you anymore that "styles is undefined", but it simply won't render in the head section of the parent template.
{% extends "base.html" %}
{% from "base.html" import styles %}
{% do styles.append("index.css") %}
How can this be solved?
PS: You need to add jinja2.ext.do to the extensions if you want to test it.
You can achieve this using blocks
base.html would look like this
<!DOCTYPE html>
<html>
<head>
<link href="{{style}}" ref="stylesheet" type="text/css; charset=utf8"> {# all global css includes you need #}
{% block styles %}
{% endblock styles %}
</head>
<body>
{% block body %}
{% endblock %}
</body>
</html>
and then child.html would look like this:
{% extends "base.html" %}
{% block styles %}
<link href="{{style}}" ref="stylesheet" type="text/css; charset=utf8"> {# all css files you need #}
{% endblock styles %}

Correct way to use Sekizai addtoblock in a DjangoCMS plugin

I am working on a DjangoCMS plugin, which includes a javascript file for itself. The plugin's Javascript relies on the same libraries that the rest of the site does. So, here's the conceptual part of what I have right now:
Basetemplate.html
{% load cms_tags sekizai_tags and_a_bunch_of_other_stuff %}
<html>
...
<head>
{% render_block "css" %}
</head>
<body>
...
{% addtoblock "js" %}[jquery]{% endaddtoblock %}
{% addtoblock "js" %}[google api, data, more cool stuff like jqplot.]{%endaddtoblock%}
{% addtoblock "js" %}[my site's library js.] {% endaddtoblock %}
{% render_block "js" %}
</body>
</html>
Now in the template loaded for my DjangoCMS custom plugin,
great_calendar_plugin_template.html
{% load sekizai_tags and_a_couple_other_things %}
{% addtoblock "js" %}[plugin javascript file dependency]{%endaddtoblock %}
{% addtoblock "js" %}[plugin javascript file]{% endaddtoblock %}
....
So no matter what I do the plugin javascript files are placed into the final HTML above JQuery and all the other dependencies, rather than underneath where they belong. What am I missing here?
Thanks.
You can fix this issue by putting the "base" addtoblock calls (jquery, etc) as far at the top of your base template as possible. The important bit is that it's before you call and {% placeholder %} tags, which on most sites means before your opening <body> tag.
An example dummy template:
{% load cms_tags sekizai_tags and_a_bunch_of_other_stuff %}
{% addtoblock "js" %}[jquery]{% endaddtoblock %}
{% addtoblock "js" %}[google api, data, more cool stuff like jqplot.]{%endaddtoblock%}
{% addtoblock "js" %}[my site's library js.] {% endaddtoblock %}
<html>
<head>
{% render_block "css" %}
</head>
<body>
{% placeholder "mycontent" %}
{% render_block "js" %}
</body>
</html>

Django-compressor and template inheritance

I'm using the django-compressor app in Django 1.2.3 to minify and merge a number of included CSS and JS files. In a base template, I have
{% load compress %}
{% compress js %}
{% block js %}
<script type="text/javascript" src="/site_media/js/jquery.query-2.1.7.js">
{% endblock %}
and in a child,
{% block js %}
{{block.super}}
<script type="text/javascript" src="/site_media/js/jquery.validate.min.js">
{% endblock %}
When the templates render, the first script tag is correctly minified, but the second isn't. In similar scenarios, I've confirmed that the issue is inheritance.
I don't want to keep using compress tags in child templates, because half the point of using this app is to merge the files and and cut back on the HTTP requests. Am I missing something? Is there another solution I should look into?
I use django-compressor with Django 1.2, and I set it up like this:
{% compress js %}
<script type="text/javascript" src="{{ MEDIA_URL }}js/jquery-1.4.2.min.js"></script>
{% block extra_compressed_js %}{% endblock %}
{% endcompress %}
{% block external_js %}{% endblock %}
And with my extra_compressed_js block I will often use the method you described, with {{ block.super }} to add more js through inheritance. It works for me without any trouble. One thing that you have to be careful about is that all the JS to compress needs to be available on the local filesystem. That's why I have a separate external_js block, for JS that comes from an outside source.
It sounds to me like something else is going on. Make sure your copy of compressor is up to date, and then check on your inheritance to make sure it's actually working correctly. One way to do this is by setting COMPRESS=False in your settings and making sure that all of the javascript that you want included actually shows up in the rendered template.
I don't know if this will work, but it seems worth a try:
First have these blocks in your base template:
{% compress js %}
{% block js %}
{% endblock %}
{% endcompress %}
{% compress css %}
{% block css %}
{% endblock %}
{% endcompress %}
and then in a given child template:
{% block js %}
{{ block.super }}
<script type="text/javascript" src="/site_media/js/jquery.query-2.1.7.js">
{% endblock %}
Always use block.super. Like I said, I don't know if it will work, but it might.