Hi All,

I would like to propose a new template tag to be included in Django, it is 
sort of a cross between 'include' and 'extends'. You can find an 
implementation here: https://gist.github.com/samwillis/af3992f69c2597a16252

The main use case for this tag is being able to create reusable 
'components' for rendering a website. Say for example a page header, a 
panel with headers and footers, or a modal window (as seen in the Bootstrap 
framework). Rather than needing to repeat the html everywhere you need it 
and having to search out all occurrences to make a change to the structure 
you can create a simple template and include it.

To some extent this can currently be done with either an included template 
using the '{% include "template.html" with var="value" %}' syntax or using 
a custom template tag. However, the former isn't suitable for changing 
whole blocks in the include template, and the latter can be overkill and 
may not be suitable for a designer with little knowledge of Python and the 
Django Template API.

The 'use' tag loads a template and renders it with the current context 
similar to the 'include' tag. You can pass additional context using keyword 
arguments as well as override blocks in the included template.

Example (simple) template:

<div class="page-heading {{ extra_class }}">
    <h1>{% block heading %}{% endblock %}</h1>
</div>

Example 'use' tag use with the above template:

{% use "page_header.html" %}
    {% block heading %}Some Title{% endblock %}
{% enduse %}

{% use "page_header.html" with extra_class="large" %}
    {% block heading %}Some Title{% endblock %}
{% enduse %}

As with 'include' use the 'only' argument to exclude the current context 
when rendering the included template:

{% use "page_header.html" only %}
    {% block heading %}Some Title{% endblock %}
{% enduse %}

{% use "page_header.html" with extra_class="large" only %}
    {% block heading %}Some Title{% endblock %}
{% enduse %}

The included template receives an additional context variable called 
'used_blocks' which is a Dict indicating which blocks were overridden in 
the 'use' tag. Using this you can conditionally show content around the 
block. For example, if you had this template for generating a page heading:

<div class="page-heading">
    <h1>{% block heading %}{% endblock %}</h1>
    {% if used_blocks.sub_heading %}
        <h2>{% block sub_heading %}{% endblock %}<h2>
    {% endif %}
</div>

and included it using:

{% use "page_header.html" %}
    {% block heading %}My Page Title{% endblock %}
{% enduse %}

it would exclude the '<h2>' tags from the empty subheading.

Finally, as syntactic sugar if you are just overriding a single block you 
can express it as:

{% use "page_header.html" block heading %}
    My Page Title
{% enduse %}

These example are a little simple, but this could be incredibly useful for 
more complex components such a modal windows.

I have made a first pass at an implementation here: 
https://gist.github.com/samwillis/af3992f69c2597a16252.

Although I have implemented this with the 'use' word, there may be a better 
word. I considered 'embed' but thought 'use' was a little cleaner

Thanks,
Sam

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To post to this group, send email to [email protected].
Visit this group at http://groups.google.com/group/django-developers.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/django-developers/0104008b-bb58-4730-a0dd-43c2875fa1b5%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to