Jinja2 can't extend simple layout - jinja2

I have a layout html file called layout.html that goes as follows:
<!DOCTYPE html>
<html>
<head>
<title>{% block title %} {% endblock %}</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta.3/css/bootstrap.min.css" integrity="sha384-Zug+QiDoJOrZ5t4lssLdxGhVrurbmBWopoEl+M6BdEfwnCJZtKxi1KgxUyJq13dy" crossorigin="anonymous">
</head>
<body>
{% block head %}
<div class = "container-fluid">
<h1>Books </h1>
<h1 class = "text-muted">Rate and discover books</h1>
</div>
{% endblock %}
{% block body %} {% endblock %}
</body>
</html>
and an index layout called index.html that goes as follows:
{% extends "layout.html" %}
{% block title %}{% endblock %}
{% block head %}{% endblock %}
{% block body %}
<h1>some text</h1>
{% endblock %}
but when I render the index.html into the browser with my flask application, all I see is the following text:
Why??
thanks!

OK, I feel pretty stupid now. I realised that whenever you enter the name of a block in the child template that is also present in the parent template, you are overriding that part of the parent template. So in this case, by entering the block head in the child template and leaving it blank, that's exactly what I did, so the text was overridden by no text basically.

Related

html after {% block content %} and {% endblock content %} is showing before the content in Django?

I have base and child templates.
In my base HTML file I have this:
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<ul id="barra">
<li>Inicio</li>
<li>Enlace1</li>
<li>Enlace2</li>
<li>Enlace3</li>
<li>Enlace4</li>
<li>Ayuda</li>
</ul>
{% block content %}
{% endblock %}
</br>
<a>asdasdasdasdasdasd</a>
</body>
</html>
But when I see the web in a browser, the "asdasdasdasdasdasd" is shown below URL and over {% block content}.
Does anyone knows the origin of this behavior, I think its a really simple structure and I cant get why it's failing?
Thank you very much!

django set global variable in template

I am using a banner image that needs to change on each page, I would like to set the banner in the html template, so that it is easy for the person I am building it for to easily add new pages.
I am developing it in django, but I can't figure out how to get it to work, please help!
example:
index.html
set image url here
{% extends 'base.html' %}
base.html
<html>
<body>
{% include 'top.html %}
</body>
</html>
top.html
<div>
<img src="{{ image url }}">
</div>
The Django template language does not let you set variables. You can acheive something similar by using blocks. Change your base template to:
base.html
<html>
<body>
<div>
<img src="{% block image_url %}/default_image.jpg{% endblock %}">
</div>
</body>
</html>
Then override the image_url block in your templates, e.g.
index.html
{% extends 'base.html' %}
{% block image_url %}/images/index.jpg{% endblock %}
Note that with this approach it is not possible to use {% include top.html %}, because you cannot override blocks that have been included by the {% include %} tag.
well I didn't understand very well, but should be better if you delete top.html and include that content in the base like:
<html>
<body>
<div>
<img src="{% block url_img %}{% enblock %}">
</div>
</body>
</html>
and in your index
{% extends 'base.html' %}
{% block url_img %}here images url{% endblock %}
also if you are using top.html for another purpose, do the same:
{% extends 'base.html' %}
{% block url_img %}{{ image url }}{% endblock %}

Django Footer and header on each page with {% extends }

So I'm trying to add the footer and header on every page of my website. I made a base.html file which contains the general layout of the site.
In my about.html page, i did:
{% extends "public/base.html" %}
<h1>Content goes here</h1>
I can see my header and footer, but how do I display the content. I want to type stuff in that about.html page. The content goes here isn't being displayed in the middle.
You need to define a block in base.html and populate it in about.html.
base.html:
<header>...</header>
{% block content %}{% endblock %}
<footer>...</footer>
about.html
{% extends "public/base.html" %}
{% block content %}
<h1>Content goes here</h1>
{% endblock %}
This is all fully explained in the tutorial.
{% extends "public/base.html" %}
{% block content %}
<h1>Content goes here</h1>
{% endblock %}
Or simply create about.html and include it where you want in your main html.
Example:
{% extends "public/base.html" %}
{% block content %}
"Your code"
{% include "core/about.html" %}
{% endblock %}
Let's say your base.html looks like this:
<html>
<body>
<!-- header code -->
{% block content %}
{% endblock %}
<!-- footer code -->
</body>
<html>
Then in your other file you would do this:
{% extends "base.html" %}
{% block content %}
<!-- Content here -->
{% endblock %}
Anything placed inside the template's (extended file's) body tag would be overwritten by the stuff in the child file's content, but anything outside of that tag would be extended, or copied, into it.
Here are the docs on the block tag

Include and Extends the same file?

I'm using twig and having a problem with include and extends.
I have a file header.html.twig that I'm including on index.html.twig. That works fine.
However, I'm also trying to overwrite a portion of the header.html.twig file with extends on index.html.twig. The code I came up with is:
<!-- index.html.twig -->
{% include '::header.html.twig' %}
{% extends '::header.html.twig' %}
{% block head %}
<li class="active">Login</li>
{% endblock %}
However, this code throws the exception "A template that extends another one cannot have a body...."
How can I fix this?
You can only have {% block... %} {% endblock %} tags in the template that extends another one.
In your case, if I got correctly what you are trying to achieve, you can define an empty block in header.html.twig (at the beginning), and override that block in index.html.twig with
{% block foo %}
{% include "header.html.twig" %}
{% endblock %}
If you are doing things outside any block, those things are considered to be the body of your twig file. And as the exception clearly tells, if you are extending a twig template, you need to overwrite some blocks contained in the extended file without any body.
You should use the {% extends %} tag without any include before, as the extends already include contents. The packaged "base.html.twig" file is a good example: you put the code that will be used everywhere in your application in a base.html.twig file:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{% block title %}Welcome!{% endblock %}</title>
{% block stylesheets %}{% endblock %}
<link rel="shortcut icon" href="{{ asset('favicon.ico') }}" />
</head>
<body>
{% block body %}{% endblock %}
{% block javascripts %}{% endblock %}
</body>
</html>
For your case, you can add a {% block head %}{% endblock %} above the body block, and then, in your index.html.twig file, you'll overwrite this block to fulfill it.
{% extends '::base.html.twig' %}
{% block head %}
<li class="active">Login</li>
{% endblock %}
This will finally output:
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Welcome!</title>
<link rel="shortcut icon" href="/favicon.ico" />
</head>
<body>
<li class="active">Login</li>
</body>
</html>
Conclusion
The difference between extends and include is that you are able to override blocks from the extended file, where you can't while including it using include.

Twitter bootstrap style inheritance with jinja2

I'm developing an web app with Google app engine that uses jinja2 as a template engine.
I'm my base.html file i have a <link> tag for CSS.
Now i have a another file front.html that extends the first file . It has the {% extends 'base.html' %} block and the code is in a block {% block content %} ....... {% endblock %}.
In the second file, the CSS style won't apply. Any ideas how to fix it ?
To be more precise:
base.html :
<head>
<link ... >
< /head>
<body>
{% block content %}
{% endblock %}
</body>
front.html:
{% extends 'base.html' %}
{% block content %}
....
{% endblock %}
The style from the tag won't apply to the block.
Ok. I figured it out . The path to the front.html was something like /path1/path2 while for the base.html the path was /path1. So it did not link corectly.
As a solution you can make a block on the link tag and the override it something like:
{% block stylesheet %}
<link href="path1/something.css">
{% endblock %}
and in the child you have
{% block stylesheet %}
<link href="/path1/path2/something.css">
{% endblock %}
Or, you could put a path in the app.yaml file.