I have two methods, set_page_title and get_page_title. set_page_title is called by child.html, which extends base.html which then calls get_page_title.
set_page_title adds an attribute to the global g object, which get_page_title then reads from.
I expected get_page_title to be called last, because it's in a decorating view, but it is actually called first. Is there anyway I can delay the execution of get_page_title until after all child templates have been fully parsed?
It sounds like you are trying to replicate functionality that is already available to you in Jinja's blocks:
{# base.html #}
<!DOCTYPE html>
<head>
<title>{% block title %}Default Title{% endblock %} - Site Name</title>
</head>
<body>
<main>
<h1>{{ self.title() }}</h1>
</main>
</body>
</html>
Then, in the child template you only need to override the block:
{# child.html #}
{% block title %}Child Title{% endblock %}
Related
I'm creating a webapp with Tornado, and I'm having this issue where an .html page I have is extending another .html page like so:
{%extends "sitebase.html" %}
<div id="about">
<p>hello</p>
</div>
When I serve this page, I see the correct content from 'sitebase.html' (a simple nav bar), however I don't see the 'hello' on the web page. I've inspected the page and don't even see an element with this 'hello', and there are no errors in the console. When I remove the extends block and just paste the contents of sitebase.html I see the expected result.
Has anyone else had this experience with tornado where using an extend block causes other pieces of the page to be not rendered?
From docs (emphasis mine):
{% extends *filename* %}
Inherit from another template. Templates that use extends should contain one or more block tags to replace content from the parent template. Anything in the child template not contained in a block tag will be ignored. For an example, see the {% block %} tag.
This means that when you extend a template, the content within a {% block %} tag is rendered, anything outside the tag is ignored.
Example:
base.html:
<title>{% block title %}Default title{% end %}</title>
{% block content %}
{% end %}
mytemplate.html:
{% block title %}Title for this page{% end %}
{% block content %}
Some data to render in the content block
{% end %}
This will not be rendered because it is outside a block tag
I work with templates in my application. I have the main part of the website styled in base.html, being the files that always will be the same (header, menu, footer...) properly coded in 'base.html' and also with the styles linked to it (in a link rel="stylesheet").
When I try to use the base template as it is, a base template, it works well while it lets me add content between de {% block content %} and also shows the 'permanent' parts (menu, header etc), but there have no style (CSS) on it. How could I also extend to these stylesheet to load the CSS styles??
Help would be appreciated, thank you.
EDIT 2: Here's my base.html head content:
<head>
<meta charset="utf-8">
{% load staticfiles %}
<title>{% block title %}Index{% endblock %}</title>
{% block style_base %}
<link href="{% static 'css/styles.css' %}" rel="stylesheet">
{% endblock %}
<meta name="description" content="{% block description %}{% endblock %}">
<link href='https://fonts.googleapis.com/css?family=Roboto+Mono:400,700,300' rel='stylesheet' type='text/css'>
<script src="static/myapp/jquery.min.js" type="text/javascript"></script>
<script src="static/myapp/main.js" type="text/javascript"></script>
</head>
This works on base.html, it gets the correct styles. However, when trying to get the same styles in the common part with another template, it doesn't gets the styles. The template code starts like this:
{% extends "base.html" %}
{% load staticfiles %}
{% load i18n %}
{% include "base.html" %}
{% block title %}{% trans "Main index" %}{% endblock %}
{% block content1 %}
It gets all the correct HTML from base.html but unstyled. I also try delete the 'include' tag or changing its position but there's no result. What can be wrong? Thank you.
Also, the console tells me this:
Not Found: /list/static/myapp/styles.css
[25/Mar/2016 01:03:03] "GET /list/static/myapp/styles.css HTTP/1.1" 404 3414
When I refresh the page (list is the page where there is the template I wanna get the styles from base) it keeps telling me this. List is not a directory in my project, but the /static/myapp/styles.css path is correct. What happens?
You have to call the CSS files within the base.html, so when you extend the base.hml in your other pages, the CSS will be called.
For me, I usually do this:
I have Head.html I call all Javascripts and CSS files I am using in the website inside it like this:
for CSS:
<link rel="stylesheet" type="text/css" href="/static/styles/example.css"/>
for javascript:
<script type="text/javascript" src="/static/js/example.js"></script>
then, in each page in the website, after the title tag I include this Head.html like this:
{% include "Head.html" %}
When you do this in every page, the CSS and javascripts files will be seen in all the pages and callable.
Also, the main urls.py file should be like this: "the answer is from here"
urlpatterns = [ # ... the rest of your URLconf goes here ...
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
On top of your html file add this:
{% extends "base.html" %}
It should work, maybe the css path is wrong, or try to delete your {%block style_base%}
I have a block of code in a Django template for a simple blog engine:
{% block mainLeft %}
<section class="container" id="main">
<section class="offset1 span8" id="mainLeft">
</section>
{% endblock %}
What would the correct way to add content within the #mainleft section for different templates be? For instance, if I wanted to dynamically generate divs within the section tag based on info passed in from a context.
Use {{ block.super }} in the block. See the docs.
I have a string that looks like
string '''
<html>
<head>
{% block head %}{% endblock %}
... other stuff ...
</head>
<body>
{% block body %}{% endblock %}
... other stuff ...
</body>
</html>
'''
I would like the following django template to inherit from the above string:
{% block head %}
... other stuff ...
{% endblock %}
{% block body %}
<h1>Other stuff</h1>
{% endblock %}
Since the string is not in a file a can't just specify it's filename to the template rendering engine. Any ideas?
In order to implement string-only template extender, you would probably have to implement your template loader. Actually, a much cleaner solution is to use threed's suggestion below. Pass a parent Template() in the context rather than the name of disk template:
>>> from django.template import Context, Template
>>> extend_me = Template("Before A. {% block a %}{% endblock %}. After A")
>>> str_template = "{% extends parent %} {% block a %}This is inside A{% endblock %}"
>>> Template(str_template).render(Context({"parent": extend_me}))
u'Before A. This is inside A. After A'
Unfortunately this doesn't seem to work on django 1.3, possibly due to bug #7377 (you can't use the extends and block tags in string templates). Though it does work fine in 1.2. So if you happen to be running 1.3, you can look up the history of this question and use my hack :)
The extends template tag allows you to specify a variable name (since ver 1.0).
There's an example of it's usage in this question: How do I use Django's template extends variable?
It turns out there's an even simpler way to achieve this:
from google.appengine.ext.webapp import template
parent = template.Template("<html><body>{% block content %}{% endblock %}</body></html>")
path = os.path.join(os.path.dirname(__file__), 'index.html')
template.render(path, template.Context({"baseTemplate": parent}))
Where the index.html file looks like this:
{% extends baseTemplate %}
{% block content %}
<h1>Hello World!</h1>
{% endblock %}
In this case, the template object (as opposed to just a string) is passed into the context of the child template and used as the variable in the 'extends' tag.
I'm a front end developer, and I've been trying to get a hang on using Jinja2 effectively. I want to tweak a current site so it has multiple base templates using inheritance, it fully uses block tags to substitute content and override it, and uses macros to support passing of arguments.
My base template contains this code (edited for simplicity):
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
{% from "foo.html" import macro1, macro2, macro3 %}
{% macro base_template(title=none, arg2=none, urls={}, arg3=false) %}
<html>
<title>{{ title }} | Site.com</title>
....
{{ caller() }}
....
</html>
{% endmacro %}
{% block content %}{% endblock %}
And my pages that extend it look like this:
{% extends "base.html" %}
{% block content %}
{% call base_template(title="home", arg2="active", arg3="true") %}
(html code here)
{% endcall %}
{% endblock %}
So basically all the pages extend base, they call a macro and pass arguments to that macro. I don't quite understand it all, but the main point is that this allows default values and a degree of flexibility that doesn't require redefining an entire block: it gives some degree of flexibility and power. Again this is heavily simplified.
The only problem is, this negates my ability to use blocks. Macros are for flexibility, but with blocks, I have the ability to override something entirely, or use it's parents contents and add to it, which I can't do with Macros (at least I don't think). The problem is, I can't wrap things in blocks, else they won't see the values in the macro. For instance, doing this:
{% block title %}<title>{{ title }} | Site.com</title>{% endblock %}
Will fail because it will say title is undefined.
Ultimately I am looking for a way to utilize both the power and organiztional aspects of blocks, but still be able to utilize the logic & terseness of macros. If anyone could give me any help as to how I might go about this problem, I would really appreciate it.
Blocks are only definable at a template's top level. If you extend a template, any values set in the child template using a set tag will be accessible from the template it is extending. For example, if you have a template named layout.html:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<title>{{ title }} | Site.com</title>
....
{% block content %}{% endblock content %}
....
</html>
And you have this child template, index.html:
{% extends "layout.html" %}
{% set title = 'Homepage' %}
{% block content %}
(html code here)
{% endblock content %}
Then the reference to title in the parent would resolve to 'Homepage'. You can do this with any type of variable. For what you're doing, I don't think there is any need for macros - if you take advantage of this feature and place blocks well, you will be able to do pretty much everything you need to do as far as layouts are concerned. I would look at some of the templates used by Plurk Solace, which is written by one of the Jinja2 authors, if you want to get a good idea of when to use various features of Jinja2.