Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django multi-level template extends and nested blocks

Let's say I have the three html template files shown below. HTML is minimal just to illustrate the point.

Is it possible to somehow nest a block named extra_head_content inside of a block already named extra_head_content. The idea is to allow the third-level template to provide a block named extra_head_content. The template above it takes that content, adds it to its block named extra_head_content and provides this combined block to its parent template.

Essentially, I am looking for block nesting across inherited template files.

The exact scenario I am trying to solve is that any template should be able to add extra javascript or css files to the head element. However, the lowest template should not care how many levels down it is nested. Similarly, the extra head content provided by an intermediate template should not get overwritten by the block element of the terminal template.

base.html

<html> <head>     <link rel="stylesheet" type="text/css" href="/static/css/reset.css" />     {% block extra_head_content %}{% endblock %} </head> <body>{% block content %}{% endblock %} </html> 

account.html

{% extends "base.html" %}  {% block extra_head_content  %}     <link rel="stylesheet" type="text/css" href="/static/css/account.css" />     {% block extra_head_content  %}{% endblock %} {% endblock %}  {% block content %}     <div id="menu">...</div>     {% block account_content %}{% endblock %} {% endblock %} 

account_profile.html

{% extends "account.html" %}  {% block extra_head_content  %}     <link rel="stylesheet" type="text/css" href="/static/css/edit_profile.css" /> {% endblock %}  {% block account_content %}     Welcome to your profile {% endblock %} 
like image 252
Krystian Cybulski Avatar asked Jan 03 '12 19:01

Krystian Cybulski


People also ask

Can you extend more than one template Django?

Use Django extends in multiple templates Note that you can extend the header. html to multiple HTML documents using the same document structure and DTL block content tags. This means the header can render in multiple templates. The example above extends the header template to a new HTML template called contact.

What is difference between extend and include in Django?

Extends sort of 'includes' the parent template and then can overwrite parts of it for different functionality. Include does a simple include rendering a template in a current context.

What does {% %} mean in Django?

{% %} and {{ }} are part of Django templating language. They are used to pass the variables from views to template. {% %} is basically used when you have an expression and are called tags while {{ }} is used to simply access the variable.

When {% extends %} is used for inheriting a template?

extends tag is used for inheritance of templates in django. One needs to repeat the same code again and again. Using extends we can inherit templates as well as variables.


2 Answers

No, but you can use {{ block.super }}:

{% block extra_head_content  %}     {{ block.super }}     <link rel="stylesheet" type="text/css" href="/static/css/account.css" /> {% endblock %} 
like image 178
Chris Pratt Avatar answered Sep 21 '22 12:09

Chris Pratt


The django-sekizai module takes care of addition to css and javascript with ease:

#base.html {% load sekizai_tags %} # define your template, declaring blocks for inheriting templates: {% block content %} {% endblock content %} # at the bottom of the body: {% render_block "js" %} </body> </html>  #my_template.html {% extends "base.html" %} {% load sekizai_tags %} {% block content %} # content goes here... # so does the addtoblock tag     {% addtoblock "js" %}         <script src="my/awesome/script.js"></script>     {% endaddtoblock %} {% endblock content %} # Note no addtoblock tags outside the block-endblock tags 

The sekazai docs make clear the caveats for using this system, namely that:

  1. render_block should only be used outside block tags
  2. render_block cannot be used in included templates
  3. addtoblock should be used inside block tags when used in an included template
like image 23
James Fletcher Avatar answered Sep 20 '22 12:09

James Fletcher