django template extends not working - django

This is my base.html
<!DOCTYPE html>
<head>
<title> My Site </title>
</head>
<body>
<div id="wrapper">
<!-- HEADER START -->
{% block nav %} {% endblock %}
{% block index %} {% endblock %}
</div>
</body>
</html>
this is my nav.html
{% extends "base.html" %}
{% block nav %}
<div id="header">
<div class="inner">
<div class="nav">
<ul>
<li class="current">Home</li>
<li>About</li>
<li>Blog</li>
<li>Contact</li>
</ul>
</div>
<div class="clear"></div>
</div><!-- .inner end -->
</div><!-- #header end -->
<!-- HEADER END -->
{% endblock %}
this is my index.html
{% extends "base.html" %}
{% block index %}
<p> hello </p>
{% endblock %}
I have done it several times before before but i am clueless as to why this is NOT working?
the urls and views are here.

Well everything is fine, the trouble that you are having is that
you are confused, just naming a block in base does not calls it.
Mark the difference between extends and include.
You have counfused extends to include.
Once in your views if you call say index.html it will be rendered properly.
The effect you want can be achieved by changing the base.html in your views to index.html.
Hope this helps. more can be read here: https://docs.djangoproject.com/en/dev/topics/templates/#template-inheritance

For more people who end up here (as myself), main thing to note is that when you use {% extends 'something.html' %}, you cannot use anything other than these template tags at the top-level.
You can obviously have html tags inside these tags (like block tags), but don't put ANYTHING outside the template tags.

Also helps if you change the path in extends, for example {% extends 'mysite/index.html' %}. And view function must render the file with extends, not the basic one.

In views.py, you have to call the template that extends the other template, not the other way around. In your example you should call nav.html.

try do this
{% extends 'appname/index.html' %}

Related

django {% inlcude %} throws Template Error

The problem: I have a file base.html, where I have a {% block content %}, for the page's content and a {% inlcude %}, for the navigation bar (bootstrap) of the base template. But the include does not find the Template (TemplateDoesNotExist) and I am sure I didn't spell it wrong. Do I have to provide anything for the template to be found or what?
base.html important content:
<body>
{% include "navbar.html" %}
<div>
{% block content %}
{% endblock %}
</div>
</body>
Some important information:
I downloaded bootstrap in the base.html file; base.html and navbar.html are in the same folder.
Since in your directory structure, you have home directory inside templates. Please change code as per below :
<body>
{% include "home/navbar.html" %}
<div>
{% block content %}
{% endblock %}
</div>
</body>

Is it possible to use a block tag ({% block %}) from base html template two or more times in derived html file in Django

I want to be able to reuse the same block tag multiple times in derived html.
something like:
base.html
<body>
{% block panel %}
# some basic panel structure inside this block
{% endblock %}
</body>
derived.html
{% extends base.html %}
--first panel
<div class="col">
{% block panel %}
# override things like panel header
{% endblock %}
</div>
--second panel
<div class="col">
{% block panel %}
# again override some panel stuff from base template
{% endblock %}
</div>
Is there anyway i can achieve this in Django?
No, it will result in template syntax error. The best you can do is to include as many block tags as you require in base and reuse them. Or you can even loop the blocks in base.
I haven't tested it out, but theoretically it should work. In your base, create a loop block, in below example it creates 6 blocks, block content1..... content6
{% for i in '123456' %}
{% block content{{i}} %}
Foo
{% endblock content{{i}} %}
{% endfor %}
No, you can not. The best way to do it is, assign each block for each panel or if you have multipanel then run the loop for the block.
In your current case (i assuming two panel in single derived file) it would be like this-
base.html
<body>
{% block content %}
<!-- all your panels -->
{% endblock %}
</body>
derived.html
{% extends "base.html" %}
{% block content %}
 <div class="col">
<!-- First panel -->
<!-- Second panel -->
</div>
{% endblock %}
The block is just for reducing the redundant work which unique to each extended file. so you can only referred it to single time in any extended file.

Django template include overwrite <h1> tag

I have the following html files.
banner.html
<header class="intro2">
<div class="intro-body">
<div class="container">
<div class="row">
<div class="col-md-8 col-md-offset-2">
<h1>{% block banner %}Bannertest{% endblock banner %}</h1>
</div>
</div>
</div>
</div>
</header>
test.html
{% extends 'banner.html' %}
{% block banner %}
Test
{% endblock banner %}
I'm new to Django but I would expect the H1 title to be updated to say Test instead of Bannertest?
What am I doing wrong?
You need to extend your main html not to include
replace
{% include 'banner.html' %}
to
{% extends "banner.html" %}
more details here: include-vs-extends
your full new html:
{% extends 'banner.html' %}
{% block banner %}Test{% endblock banner %}
For block overriding you must use {% extends 'banner.html' %} instead of {% include %}
So instead of making small fragments for include, like in php, standard approach is to make a full template, say base.html, when extend it in child templates.
{% include %} tag is better suits for widgets with parameters, e.g. {% include '_form.html' style='light' some_param=some_value %}

Why django generates empty string after extend?

My base template is
<!DOCTYPE html>
<html lang="en">
<head>
<title>{% block title %}My amazing site{% endblock %}</title>
</head>
<body>
<div id="sidebar">
{% block sidebar %}
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
Index page:
{% extends "base.html" %}
{% block title %}My amazing blog{% endblock %}
{% block content %}
{% for entry in blog_entries %}
<h2>{{ entry.title }}</h2>
<p>{{ entry.body }}</p>
{% endfor %}
{% endblock %}
What is wrong with that and why it is generating strange empty text inside those quotes?
It is affecting my layout. Do you have any ideas? Thanks.
At last!!! I found what caused this.I use Notepad++ and encode to
UTF-8
but I should have encoded to
UTF-8 without BOM
Thanks everyone anyway.
Does the source opened using Ctrl+U also look weird? Maybe it is Chrome that is messing up the Elements preview, because I have made a view rendering those exact two templates (and adding 2 dummy blog entries) on Django 1.2.3 and it rendered correctly as:
<!DOCTYPE html>
<html lang="en">
<head>
<title>My amazing blog</title>
</head>
<body>
<div id="sidebar">
<ul>
<li>Home</li>
<li>Blog</li>
</ul>
</div>
<div id="content">
<h2>Test 1</h2>
<p>blah blah</p>
<h2>Test 2</h2>
<p>blah blah</p>
</div>
</body>
</html>
Pay attantion that your title tag inserted into body tag. Maybe start to search from here?
It can't be the result of this to templates combined, because in your "base.html" template, {% block title %} is in between section, but in your resulting html, it is in section. And also there's a CSS link, outside either and sections. I have lots of this empty strings, and this doesn't affect my layout, I think the problem is that your is outside section.

Django: nested content blocks with the same name

Is there a way to have content blocks with the same name?
base.html:
This is the template with the main layout.
<html>
...
{% block content %}
{% endblock %}
...
</html>
base_side_left.html:
This is the template with the main layout + sidebar on the left.
{% extends 'base.html' %}
{% block content %}
<div class='sidebar'>
</div>
{% block content %}
//This doesn't work because you can't have blocks with the same name//
{% endblock %}
{% endblock
I have a few reason why I am asking this:
It's easy to change the parent of a page without having to change the name of the content blocks.
I don't have to come up with names for my blocks. Like content-content, sidebar-content, etc
I got two solutions for this which I don't like because they ain't DRY:
Make the sidebar a partial and include it in the templates you need.
Add everything to the base template and overwrite those blocks you don't need.
If this isn't possible with Django Template can I do something like this with an other templating engine?
Small update:
So what I want to do is to be able to move the templates around in the template tree without to much hassle. It's not possible though without coming up with smart names for my content blocks but I thought I add this pretty diagram anyways.
No, you can't. From the Django docs on template inheritance:
you can't define multiple {% block %} tags with the same name in the same template. This limitation exists because a block tag works in "both" directions. That is, a block tag doesn't just provide a hole to fill -- it also defines the content that fills the hole in the parent. If there were two similarly-named {% block %} tags in a template, that template's parent wouldn't know which one of the blocks' content to use.
I'm not clear on why you want to do this.
It's easy to change the parent of a page without having to change the name of the content blocks.
There's only one {% block %} tag with a given name, and there's only one {% extends %} tag as well. I don't see any difference in difficulty.
I don't have to come up with names for my blocks. Like content-content, sidebar-content, etc
Anyone maintaining your code will quickly lose track of which content block is effective and get confused. Besides, the names should have something to do with what the {% block %} is supposed to do. So I'm wondering why you'd have two templates, one including another, with blocks that are exactly the same.
Another point from the docs:
If you find yourself duplicating content in a number of templates, it probably means you should move that content to a {% block %} in a parent template.
This lets you make the duplicated markup the default, and you can override it in those places where needed.
This may be helpful, too:
If you need to get the content of the block from the parent template, the {{ block.super }} variable will do the trick. This is useful if you want to add to the contents of a parent block instead of completely overriding it. Data inserted using {{ block.super }} will not be automatically escaped (see the next section), since it was already escaped, if necessary, in the parent template.
From what I can tell, this is probably your best choice:
Make the sidebar a partial and include it in the templates you need.
How is this not DRY? You have to repeat the {% include %} tag?
I think there's a better design solution that would work for you, but you haven't given enough info on what you're trying to accomplish for me to help further.
EDIT: Looking at your example, you can do all that with a single template. CSS will take care of you here.
page_template.html:
<!DOCTYPE html PUBLIC -- ... -->
<html>
<head>
<!-- ... other header fields ... -->
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<base href="{{ host }}{{ root }}{{ path }}" />
<title>{% block title %}Untitled{% endblock %}</title>
<link rel="icon" type="image/png"
href="{{ root }}static/images/favicon.png" />
<link rel="stylesheet" type="text/css"
href="{{ root }}static/css/general.css" />
<!-- other header fields here -->
{% block head %}{% endblock %}
</head>
<body class="{% block page_class %}no_sidebar{% endblock %}">
<div id="page_header">
<!-- page heading here -->
</div>
<div id="sidebar">
{% block sidebar %}<!-- default sidebar here -->{% endblock %}
</div>
<div id="banner">
{% block banner %}{% endblock %}
</div>
<div id="content">
{% block content %}{% endblock %}
</div>
</body>
</html>
general.css:
body.no_sidebar div#sidebar,
div#banner
{
display: none;
}
div#sidebar
{
width: 20%;
}
body.with_sidebar div#sidebar
{
float: left;
}
body.with_banner div#banner
{
display: block;
}
body.right_sidebar div#sidebar
{
float: right;
}
Then your pages just look like, in the order of your examples:
plain_old_page.html:
{% extends base.html %}
{% block content %}
<!-- content goes here -->
{% endblock %}
page_with_left_sidebar.html:
{% extends base.html %}
{% block page_class %}with_sidebar{% endblock %}
{% block sidebar %}
<!-- sidebar goes here, if different from default -->
<!-- otherwise omit this section -->
{% endblock %}
{% block content %}
<!-- content goes here -->
{% endblock %}
page_with_left_sidebar_and_banner.html:
{% extends base.html %}
{% block page_class %}with_sidebar with_banner{% endblock %}
{% block sidebar %}
<!-- sidebar goes here, if different from default -->
<!-- otherwise omit this section -->
{% endblock %}
{% block banner %}
<!-- banner goes here -->
{% endblock %}
{% block content %}
<!-- content goes here -->
{% endblock %}
page_with_right_sidebar.html:
{% extends base.html %}
{% block page_class %}right_sidebar{% endblock %}
{% block sidebar %}
<!-- sidebar goes here, if different from default -->
<!-- otherwise omit this section -->
{% endblock %}
{% block content %}
<!-- content goes here -->
{% endblock %}