How to use inheritance in Django Templates - django

Respected All:
I want to use the feature of reusability of the Django templates
As i wrote in base.html
<title>{% block title %}{% trans 'Main Page title' %}{% endblock %}</title>
And my otherfile.html is this
{% block title %}Other file Title{% endblock %}
I want to Set the title without useing tags in otherfile.html is it possible?

Your otherfile.html will have this template tag at the top {% extends "base.html" %}
After that you can use % block title %}Other file Title{% endblock %} in otherfile.html
https://docs.djangoproject.com/en/2.0/ref/templates/language/#templates

Related

Django How can I repeat a block within a template

My Django base template looks like this:
#base.html
<title>{% block title %} My Default Title {% endblock title %}</title>
<meta property="og:title" content="{% block og_title %} My Default Title {% endblock og_title %}">
Then if I'd like to override the default title for specific page:
#page.html
{% extends "base.html" %}
{% block title %} My page Title {% endblock title %}
{% block og_title %} My page Title {% endblock _ogtitle %}
How can I set the base.html block title once (like a variable) and use across my document? Then, if I need, I override the title once in the page.html and it gets populated across?
You can work with a variable in the base template:
<title>{{ my_title|default:"my page title" }}</title>
<meta property="og:title" content="{{ my_title|default:"my page title" }}">
In your view, you then pass a value for my_title:
from django.shortcuts import render
def some_view(request):
# …
return render(request, 'some_template.html', {'my_title': 'some_title'})
Answering my own question:
There is no good way to do that. There are a few workarounds mentioned here:
How to repeat a "block" in a django template
(I saw this question in advance. But wasn't sure if anything changed)
This is the workaround I chose:
#base.html
<title>{% block title %} My Default Title {% endblock title %}</title>
<meta property="og:title" content="{% block og_title %} My Default Title {% endblock og_title %}">
#page.html
{% extends "base.html" %}
{% block title %} {% block og_title %} My page Title {% endblock og_title %}{% endblock title %}

Hide Django logo/name in header Django admin tool

I want to hide/change the name displayed in the header bar, the label that I want to change is "DJANGO" word as the next image shows"
Another solution for customizing the admin header.
Just copy /django/contrib/admin/templates/admin/base_site.html from django source (Link Here) and paste it under your templates directory.
For example,
your_project/templates/admin/base_site.html
Now you can change whatever you like in this template.
Hope this helps.
The easiest way is to simply add the following lines to your main urls.py:
admin.site.site_title = 'My Heading'
admin.site.site_header = 'My Heading'
admin.site.index_title = 'My Heading'
See the Django documentation for more attributes.
make a custom template file like:
templates/admin/base_site.html
{% extends "admin/base.html" %}
{% load i18n %}
{% block title %}YOUR WEB TITLE{% endblock %}
{% block branding %}
<h1 id="site-name">Your Site Name</h1>
{% endblock %}
{% block extrahead %}
<style type="text/css">
#header #branding h1{
background: None; // here you remove the django image
}
</style>
{% endblock %}
Just Share improve with favicon icon :
{% extends "admin/base.html" %}
**{% load staticfiles %}**
{% block title %}BROKR System{% endblock %}
{% block extrahead %}
**<link rel="shortcut icon" href="{% static 'img/logo1.png' %}"/>**
{% endblock %}
{% block branding %}
<h1 id="site-name">BROKR System</h1>
{% endblock %}
{% block nav-global %}{% endblock %}
You will need to locate your
django/contrib/admin/templates/admin/base.html
This might be located in your
env/lib/site-packages
Thus, you find it in
env/lib/site-packages/django/contrib/admin/templates/admin/base.html
This is if you have virtual environment setup.
Else it will be in your base project folder containing your settings.py, wsgi.py etc
In:
your_base_folder/lib/site-packages/django/contrib/admin/templates/admin/base.html
Then go to line 32-34
<div id="branding">{% block branding %}{% endblock %}</div>
Replace the below with your img or text or h1
{% block branding %}{% endblock %}
For example:
<div id="branding"><img href='example.png'></div>
Or You could use the preferred django's
{{% url (bla.bla bla) %}}

Strip HTML from Django template block?

In my Django base.html template I have a title block:
<html>
<head>
<title>{% block title %}{% endblock %}</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
In a page template I use the text from its <h1> page title in that block, so it also appears in the <title> tag, e.g.:
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %}Hello world!{% endblock %}</h1>
{% endblock %}
That all works fine. But if I want to use HTML tags within the page's <h1> like this...
{% extends 'base.html' %}
{% block content %}
{% block title %}<b>Hello</b> world!{% endblock %}
{% endblock %}
...those tags will also appear in the <title>, which isn't allowed.
Is there a way around this other than having two versions of the title: one within <h1>, and one HTML-free version within a {% block title %}? I don't think there's a way to strip HTML from a block?
You could use cycle like so:
{% extends 'base.html' %}
{% block content %}
<h1>
{% block title %}
{% cycle '' '<b>' %}Hello world!{% cycle '' '</b>' %}
{% endblock %}
</h1>
{% endblock %}
Hope this helps

django template language not working

#base.html
<html>
<head><title>Hello world</title>
</head>
<body>
{% block content %}
{% endblock %}
</body>
</html>
#child.html
{% extends base.html %}
{% block content}
This is the content that
comes here
{% endblock %}
but the html output of base.html not displaying content.? Why this template language not working ?
Template inheritance includes the parent template in the child, not the other way around.
Render child.html and you'll see your content surrounded by the base.html (parent) markup.
Also, you need to quote the parent template name:
{% extends "base.html" %}
{% block content %}
Content!
{% endblock %}

How to repeat a "block" in a django template

I want to use the same {% block %} twice in the same django template. I want this block to appear more than once in my base template:
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
And then extend it:
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
I will get an exception, as Django wants the block to appear only once:
TemplateSyntaxError at /
'block' tag with name 'title' appears
more than once
A quick and dirty solution would be duplicating the block title into title1 and title2:
# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}
But this is a violation of the DRY principle. It would be very difficult as I have a lot of inheriting templates, and also because I don't wanna go to hell ;-)
Is there any trick or work-around to this problem? How can I repeat the same block in my template, without duplicating all the code?
Use the Django template macros plugin:
https://gist.github.com/1715202 (django >= 1.4)
or
http://www.djangosnippets.org/snippets/363/ (django < 1.4)
django >= 1.4
# base.html
{% kwacro title %}
{% block title %}My Cool Website{% endblock %}
{% endkwacro %}
<html>
<head>
<title>{% usekwacro title %}</title>
</head>
<body>
<h1>{% usekwacro title %}</h1>
</body>
</html>
and
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
django < 1.4
# base.html
{% macro title %}
{% block title %}My Cool Website{% endblock %}
{% endmacro %}
<html>
<head>
<title>{% usemacro title %}</title>
</head>
<body>
<h1>{% usemacro title %}</h1>
</body>
</html>
and
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
I think that use of the context processor is in this case an overkill. You can easily do this:
#base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
{% block content %}{% endblock %}
</body>
</html>
and then:
# blog.html
{% extends 'base.html' %}
{% block content %}
<h1>{% block title %}My Blog{% endblock %}</h1>
Lorem ipsum here...
{% endblock %}
and so on... Looks like DRY-compatible.
You probably don't actually want to use a block but rather to just use a variable:
# base.html
<html>
<head>
<title>{{ title|default:"My Cool Website" }}</title>
</head>
<body>
<h1>{{ title|default:"My Cool Website" }}</h1>
</body>
</html>
You then set the title through the context.
Here's a way I discovered when trying to do the same thing myself:
# base_helper.html
<html>
<head>
<title>{% block _title1 %}{% endblock %}</title>
</head>
<body>
<h1>{% block _title2 %}{% endblock %}</h1>
</body>
</html>
# base.html
{% extends "base_helper.html" %}
# Copy title into _title1 & _title2, using "My Cool Website" as a default.
{% block _title1 %}{% block _title2 %}{% block title %}My Cool Website{% endblock %}{% endblock %}{% endblock %}
Requires an extra file unfortunately, but doesn't require you to pass the title from the view.
you can use {% include subtemplate.html %} more than once. it's not the same as blocks, but does the trick.
There are some discussion here:
http://code.djangoproject.com/ticket/4529
Obviously django core team reject this ticket because they think this is not a common used scenario, however I disagree.
repeat block is simple and clean implementation for this:
https://github.com/SmileyChris/django-repeatblock
template macros is another one, however the author mentioned it's not carefully tested:
http://www.djangosnippets.org/snippets/363/
I used repeatblock.
As an update for anyone coming across this, I've taken the snippet mentioned above and turned it into a template tag library, django-macros, makes the macros more powerful and also implements a repeated block pattern explicitly: django-macros.
Here is a lightweight solution similar to the above do_set and do_get template tag answer. Django allows you to pass the entire template context into a tag which can allow you to define a global variable.
base.html:
<!DOCTYPE html>
<html lang="en">
<head>
{% block head %}
<title>{{ title }}</title>
{% endblock %}
</head>
<body>
<h1>{{ title }}</h1>
</body>
</html>
page.html:
{% extends "base.html" %}
{% block head %}
{% define 'title' 'Homepage | title' %}
{{ block.super }}
{% endblock %}
custom tag (got the idea here: https://stackoverflow.com/a/33564990/2747924):
#register.simple_tag(takes_context=True)
def define(context, key, value):
context.dicts[0][key] = value
return ''
Also don't forget to {% load %} your custom tags or add them to the template options builtins list so you don't have to load them in every template. The only limitation to this approach is the {% define %} has to be called from within a block tag because child templates only render block tags that match the parent tags. Not sure if there is a way around that. Also make sure the define call comes before you try to use it obviously.
Building on Van Gale's suggestion, you could create get and set tags by adding the following to your templatetags.py file:
register = template.Library()
Stateful = {}
def do_set(parser, token):
_, key = token.split_contents()
nodelist = parser.parse(('endset',))
parser.delete_first_token() # from the example -- why?
return SetStatefulNode(key,nodelist)
class SetStatefulNode(template.Node):
def __init__(self, key, nodes):
Stateful[key] = nodes
def render(self, context):
return ''
register.tag('set', do_set)
def do_get(parser, token):
tag_name, key = token.split_contents()
return GetStatefulNode(key)
class GetStatefulNode(template.Node):
def __init__(self, key):
self.key = key
def render(self, context):
return ''.join( [x.render(context) for x in Stateful[self.key]] )
register.tag('get', do_get)
Then set values in one template via {% set foo %}put data here{% endset %} and get them via {% get foo %} in another.
I too have come across the same need for a repeated {% block %} in my template files. The issue is that I want a Django {% block %} to be used in either case of a Django conditional, and I want the {% block %} to be over-writable by subsequent files that may extend the current file. (So in this case, what I want is definitely more of a block than a variable because I'm not technically re-using it, it just appears on either end of a conditional.
The Problem:
The following Django template code will result in a Template Syntax Error, but I think it's a valid "want" to have a defined {% block %} re-used in a conditional (IE, why is the Django parser validating syntax on BOTH ends of a conditional, shouldn't it only validate the TRUTHY condition?)
# This example shows a {{ DEBUG }} conditional that loads
# Uncompressed JavaScript files if TRUE
# and loads Asynchronous minified JavaScript files if FALSE.
# BASE.html
{% if DEBUG %}
<script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
<script type="text/javascript">
{% block page_js %}
var page = new $site.Page();
{% endblock page_js %}
</script>
{% else %}
<script type="text/javascript">
// load in the PRODUCTION VERSION of the site
// minified and asynchronosly loaded
yepnope([
{
load : '{MEDIA_URL}}js/flatfiles.min.js',
wait : true,
complete : function() {
{% block page_js %} // NOTE THE PAGE_JS BLOCK
var page = new $site.Page();
{% endblock page_js %}
}
}
)];
</script>
{% endif %}
# ABOUT.html
{% extends 'pages/base.html' %}
{% block page_js %}
var page = new $site.Page.About();
{% endblock page_js %}
The Solution:
You can use an {% include %} to conditionally insert a {% block %} more than once. This worked for me because the Django syntax checker includes only the TRUTHY {% include %}. See the result below:
# partials/page.js
{% block page_js %}
var page = new $site.Page();
{% endblock %}
# base.html
{% if DEBUG %}
<script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
<script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
<script type="text/javascript">
{% include 'partials/page_js.html' %}
</script>
{% else %}
<script type="text/javascript">
yepnope([
{
load : '{MEDIA_URL}}js/flatfiles.min.js',
wait : true,
complete : function() {
{% include 'partials/page_js.html' %}
}
}
)];
</script>
{% endif %}
I use this answer to keep things dry.
{% extends "base.html" %}
{% with "Entry Title" as title %}
{% block title %}{{ title }}{% endblock %}
{% block h1 %}{{ title }}{% endblock %}
{% endwith %}
There are two easy solutions for this.
The easiest is to put your title into a context variable. You would set the context variable in your view.
If you are using something like generic views and don't have a views.py for pictures, cats, etc. then you can go the way of a custom template tag that sets a variable in the context.
Going this route would enable you to do something like:
{% extends "base.html" %}
{% load set_page_title %}
{% page_title "My Pictures" %}
...
Then in your base.html:
...
{% block title %}{{ page_title }}{% endblock %}
...
<h1>{{ page_title }}</h1>
The selected answer alludes to an easy workaround to wrap one tag inside another in the child template to give them both the same value. I use this for social images like so.
Child template:
{% extends 'base.html' %}
...
{% block meta_image %}
{% block meta_image_secure %}
{% if object.cover_pic %}
{{ object.cover_pic.url }}
{% else %}
https://live-static.welovemicro.com/static/img/device-dark.png
{% endif %}
{% endblock %}
{% endblock %}
...
Then in the parent base.html:
...
<meta property="og:image" itemprop="image" content="{% block meta_image %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
<meta property="og:image:secure_url" itemprop="image" content="{% block meta_image_secure %}https://live-static.welovemicro.com/static/img/device-dark.png{% endblock %}">
...
I would suggest using the django-macros library.
To install:
pip install django-macros
And then add the 'macros' app in your INSTALLED_APPS list in settings.py.
After that, load the macros custom tags in your base template and use them like that:
{# base.html #}
{% load macros %}
{% macro title %}
{% block title %} My Cool Website {% endblock %}
{% endmacro %}
<html>
<head>
<title> {% use_macro title %} </title>
</head>
<body>
<h1> {% use_macro title %} </h1>
</body>
</html>
In twig you can make this like:
# base.html
<html>
<head>
<title>{{ block('title') }}</title>
</head>
<body>
<h1>{{ block('title') }}</h1>
</body>
</html>
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}