django import template from file [duplicate] - python

This question already has answers here:
Render Externally Defined Block In Django Template
(3 answers)
Closed 8 years ago.
I have 3 pages, and all of them have the same menu on the top of each html file.
There are many a tags in the menu, and I have problem when I'd like to revised all link in a tag.
I'd like to write the menu in other file called menu.txt, and use template to load the menu.txt and then combine menu with other parts of the page.
Is there any efficiency way to do it?
Except load the page in view.py and pass value to template.
Thank you.

Use include in your template file. See the docs.
Example
{% extends 'base.html' %}
{% block content %}
{% include 'includes/menu.html' %}
<h1>Hello World</h1>
<!-- ... -->
{% endblock content %}

Template inheritance
The most powerful – and thus the most complex – part of Django’s template engine is template inheritance. Template inheritance allows you to build a base “skeleton” template that contains all the common elements of your site and defines blocks that child templates can override.
It’s easiest to understand template inheritance by starting with an example:
<!DOCTYPE html>
<html lang="en">
<head>
<link rel="stylesheet" href="style.css" />
<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>
This template, which we’ll call base.html, defines a simple HTML skeleton document that you might use for a simple two-column page. It’s the job of “child” templates to fill the empty blocks with content.
In this example, the block tag defines three blocks that child templates can fill in. All the block tag does is to tell the template engine that a child template may override those portions of the template.
A child template might look like this:
{% 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 %}
The extends tag is the key here. It tells the template engine that this template “extends” another template. When the template system evaluates this template, first it locates the parent – in this case, “base.html”.
you can refer for extending commom part on each html page
http://www.webforefront.com/django/createreusabledjangotemplates.html

Related

Passing a variable to include in extends in Django templates

I have the following structure of templates:
main.html
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% include 'heading.html' with title=title %} {# but this does not work since it is not a variable #}
</body>
</html>
heading.html
<p>
{{ title }}
</p>
page.html
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
How can I pass the title from page.html to heading.html? Ideally, it should be defined as a block like now, but alternatives are also welcome. I'd like to contain the solution within the templates if possible.
Clarification:
This is a minimal example, but I have multiple pages like main.html that share a larger header that has title and some other variables that I'd like defined in the child template (not necessarily as variable as long as the text is passed).
I could put the title into the view code, but this solution would just decrease the separation of displayed data from the logic.
Use a block around the include with variables, and then wrap {{ block.super }} in the with template tag.
main.html:
<html>
<body>
<p>
This works: {% block title %}{% endblock %}
</p>
{% block with_variables %}
{% include 'heading.html' %}
{% endblock %}
</body>
</html>
page.html:
{% extends 'main.html' %}
{% block title %}test title{% endblock %}
{% block with_variables %}
{% with title="variable title" %}
{{ block.super }}
{% endwith %}
{% endblock %}
You may name it {% block heading %}, or nest the whole main.html in {% block content %}.
instead of {% include %}, you might want to use custom template tags with returning html or extension like slippers
You don't need heading.html. You can use the context variable title directly; as long as you pass it to your render function in your view, e.g.:
views.py
def my_view(request):
context = {'title': 'Hello World!'}
return render(request, 'page.html', context=context)
main.html
<html>
<body>
<p>
This is my title:
{% block title %}{% endblock %}
</p>
</body>
</html>
page.html
{% extends 'main.html' %}
{% block title %}
<strong>{{title}}</strong>
{% endblock %}
If you have administrative rights to your Django installation, an easy and elegant solution would be to switch your Django's template renderer to Jinja2 instead using django-jinja as a backend.
The main advantage of Jinja2 for the needs of this question is that it supports assignment of a block to a variable through block assignments. Since Jinja2 is inspired by the Django template language, your existing templates will need few modifications, if any.
With Jinja2 as a template renderer, you can set the title variable with a block of HTML content in the child template:
page.html
{% extends 'main.html' %}
{% set title %}test title{% endset %}
The title variable will then work in the shared template:
main.html
<html>
<body>
<p>
Main template works: {{ title }}
</p>
{% include 'heading.html' %}
</body>
</html>
And it will also work in the included template:
heading.html
<p>
Included template also works: {{ title }}
</p>
Demo: https://replit.com/#blhsing/AlarmedCleverDebugmonitor
One possible solution is to split heading.html into two and add a {% block %} in-between, but this is an ugly workaround that is prone to bugs with unclosed tags.
I am searching for a better alternative.
main.html
...
{% include 'heading1.html' %} {# containing <p> #}
{% block title %}{% endblock %}
{% include 'heading2.html' %} {# containing </p> #}
...
Additionally, if white spaces are important, there has to be no new line between includes and the block.
add your title to the rendering context and it will be visible in page, main and included heading.

How to interpret/render template tags as HTML from Django database

I'm trying to add posts with images from Django admin site, but the safe/autoescape-off filter cannot interpret Django's template tags.
My input and page look like:
"copy image address" gives http://127.0.0.1:8000/%7B%%20static%20'post/image.jpg'%20%%7D
My view inherits from a generic ListView.
My base.html and post_list.html:
<!DOCTYPE html>
{% load static %}
<html lang="en" dir="ltr">
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<div style="color: red;">
admin
{% block contents %}
{% endblock %}
</div>
</body>
</html>
{% extends 'post/base.html' %}
{% block contents %}
{% for post in object_list %}
{% autoescape off %}{{ post.text }}{% endautoescape %}
{{ post.text|safe }}
{% endfor %}
{% endblock %}
You can't do what you're trying to do directly in the template. Django templates are made up of "nodes" that are later resolved into strings. Nodes using the {{ variable }} syntax always return a string: even if you use the safe filter, Django will not try to convert your post.text string into nodes to be rendered by the templating engine.
You could potentially work around this in the view by manually rendering your text as a Django template:
from django.template import Template
class MyListView(ListView):
#...your existing code
def get_context_data(self, **kwargs):
context = super(MyListView, self).get_context_data(**kwargs)
for post in context["object_list"]:
post.rendered_text = Template(post.text).render(context)
return context
Then in your template:
{% for post in object_list %}
{{ post.rendered_text|safe }}
{% endfor %}
But beware! This is a pretty bad idea from a security standpoint! The safe tag is already quite dangerous because it allows cross-site scripting attacks: anyone who has access to create a post can inject malicious Javascript that is displayed to the user. This extra rendering step is even more dangerous because it also gives access to the Django templating language and all the context of your view, which could have access to server-side secrets.

Flask template inheritance clarification

I'm trying to set up a site in Flask (formerly familiar with django) and I'm having difficulties getting templates to render properly.
I have a base.html, home.html and a navigation.html. My route renders home.html template, which extends the base.html template, and that works fine. But within my base.html, there is another block called navigation. Nothing I enter into my navigation file seems to render at all.
base.html
<DOCTYPE html>
<html>
<head>
<title>{% block title %} {% endblock %} </title>
</head>
<body>
{% block navigation %}
{% endblock %}
{% block content %}
{% endblock %}
</body>
</html>
home.html
{% extends 'base.html %}
{% block title %} lorem ipsum {% endblock %}
{% block content %}
<h1> Here is text </h1>
<p> Lorem ipsum paragraph </p>
{% endblock %}
navigation.html
{% extends 'base.html %}
{% block navigation %}
<nav>
insert any html here, I used a p tag
</nav>
{% endblock %}
I can't get anything within navigation.html to display, no matter what it is.
In django, I don't remember having this issue.
To my best of critical thinking, I would assume that I'm rendering home.html and not base.html so therefore home.html can use base, but it can't extend it's reach to actually use navigation.html.
I'm not sure, and I'm tired of racking my head into my desk.
Making a assumption here, so please clarify if I get this wrong.
I suspect what you mean to do is {% include 'navigation.html' %} from within index.html (and in all other pages that want that common navigation).
If that's the case, you can remove the {% extends ... %} from navigation.html.

is dividing a template into parts and including each part bad?

I have a base template that I'd like to split up into three parts: header, body, footer. Then I use the base template to include the three sub-templates. However, from what I've seen, this means I cannot override {{ block }} content. Is using includes a bad idea then? Or is there a way to override block content in an included template?
I know that you can send static context variables to the included segment, but it needs to be more dynamic.
My code:
In header.html
<html>
<head>
<script url="..."></script>
<link rel="..." />
{% block head_extension %}
{% endblock %}
</head>
<body>
<header>
<div class="headerstuff">
</div>
</header>
Then in the body.html file:
<div class="container">
{% block content %}
Foo fum my content
{% endblock %}
</div>
footer.html:
<footer>
{% block footer %}
Copyright 2015
{% endblock %}
</footer>
</body>
</html>
base.html:
{% include "header.html" %}
{% include "body.html" %}
{% include "footer.html" %}
<!-- and the part that doesn't work -->
{% block head_extension %}
<script src="unique_script"></script>
{% endblock %}
{% block content %}
My unique content
{% endblock %}
{% block footer %}
Copyright 2011
{% endblock %}
<!-- end broken django templating try -->
Am I doing something wrong? The templating documentation seemed to indicate that what I am trying to do doesn't work. It seems like this would be the best way to create easy-to-read templates. Is it better just to have all parts in one large file? As you can imagine, the header, body, and footer elements are much larger than this demonstration. But the point remains.
I am hoping there is a way to do what I'm thinking of that I'm not aware of.
Thanks in advance
Your approach is fine but you are doing this in wrong order. First of all the html starting <html> and ending tag </html> should not be split into different files, it is good to have it in base.html.
Below is an example of how to follow the breakup structure:
base.html
<html>
<head>
<!-- Some stuff here which should be included in all templates for example js or css -->
{% block extra_css %}
<!-- to included app-template dependent css -->
{% endblock extra_css %}
{% block extra_js %}
<!-- to included app-template dependent js -->
{% endblock extra_js %}
{% block extra_head %}
<!-- for anything else inside head -->
{% endblock extra_head %}
</head>
<body>
{% block menu %}
<!-- Default menu here -->
{% block extra_menu %}
<!-- extend menu based on template -->
{% endblock extra_menu %}
{% endblock menu %}
{% block content %}
<div>This is good</div>
{% endblock content %}
{% include "footer.html" %}
{% block bottom_js %}
<!-- if you want to have manual js scripts at bottom -->
{% endblock bottom_js %}
</body>
</html>
Now base.html is all setup now lets suppose from another child template you want to override the base.html block content you will do:
child.html
{% extends "base.html" %}
{% block content %}
<div>This is really good</div>
{% endblock content %}
So when the page will be loaded you will see this is really good instead of this is good (which was defined in base.html inside content block) because you just override it.
If you want that whatever inside the content block in base.html should also be preserved then you need to extend the block rather than overriding it completely by using method {{ block.super }}
child.html
{% extends "base.html" %}
{% block content %}
{{ block.super }}
<div>This is really good</div>
{% endblock content %}
Now you will see both this is good and this is really good. Hope this will clarify your concept and will lead you good.

Whats the best way to duplicate data in a django template? [duplicate]

This question already has answers here:
How to repeat a "block" in a django template
(15 answers)
Closed 6 years ago.
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block title %}{% endblock %}</h1>
</body>
</html>
This is my template, more or less. The h1 heading is always the same as the title tag. The above snippet of code is not valid because there can't be two blocks with the same name. How do I handle this without repeating myself?
edit to clarify: I have a ton of child templates which are inherited from this one template, and so making a new {{title}} variable for each template is not a very good solution. Previously I had it set up like this:
base.html:
<title>{% block title %}{% endblock %}</title>
then in base_view.html (extending base.html):
<h1>{% block title %}{% endblock %}</h1>
then in base_object.html (extending base_view.html):
{% block title %}my title goes here{% endblock %}
and it just worked somehow. I refactored my templates so theres just base.html, and base_object.html How can I get this functionality back?
In base.html:
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
Then, make another "base" layer on top of that called content_base.html (or something):
{% extends "base.html" %}
{% block h1 %}{% block title %}{% endblock %}{% endblock %}
Now have all your other templates extend content_base.html. Whatever you put in block "title" in all your templates will go into both "title" and "h1" blocks in base.html.
{% extends "base.html" %}
{% with "Entry Title" as title %}
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
{% endwith %}
That could work if you're really worried about keeping title out of the views and not repeating yourself.
It looks like your layout is solid. You have a base.html template that defines the basic structure and outer layout for each page in your app. You also have base_object.html that extends this template.
You'd like each page to have a unique title and a matching h1 (I think). This best way to do this is to define two separate blocks in your base.html template.
<html>
<head>
<title>{% block title %}Default Title{% endblock %}</title>
</head>
<body>
<h1>{% block h1 %}{% endblock %}</h1>
</body>
</html>
In your child templates, you need to override both of these if you'd like them to be identical. I know you feel this is counter-intuitive, but it is necessary due to the way template inheritance is handled in Django.
Source: The Django template language
Finally, note that 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.
The children look like this:
{% extends "base.html" %}
{% block title %}Title{% endblock %}
{% block h1 %}Title{% endblock %}
If this bothers you, you should set the title from the view for each object as a template variable.
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
Django strives to keep as much logic out of the template layer as possible. Often a title is determined dynamically from the database, so the view layer is the perfect place to retrieve and set this information. You can still leave the title blank if you'd like to defer to the default title (perhaps set in base.html, or you can grab the name of the site from the django.contrib.sites package)
Also {{ block.super }} may come in handy. This will allow you to combine the contents of the parent block with additional contents from the child. So you could define a title like "Stackoverflow.com" in the base, and set
{% block title %}{{ block.super }} - Ask a Question{% endblock %}
in the child to get a title like "Stackoverflow.com - Ask a Question"
Pass a variable to your template, maybe called title. Then replace your title block with {{ title }}. To pass this into your template in your view make sure you have:
def myview(request):
t = loader.get_template("mypage.html")
title = "My Title"
c = Context({"title" : title })
HttpResponse(t.render(c))
Then in your template you will have:
<html>
<head>
<title>{{ title }}</title>
</head>
<body>
<h1>{{ title }}}</h1>
</body>
See also: How to repeat a "block" in a django template

Categories

Resources