[Answer]-Is it possible to preprocess a template to remove its `{% extends %}` tag?

1👍

This is what i actually needed…

Any way to make {% extends '…' %} conditional? – Django

… and below is the solution i spent several hours coming up with, until i finally realised the question i actually wanted to ask. I’m going to post it here anyway, just incase someone else finds it useful.

__init__.py

{% extends %} always has to be first in a template, so it’s not possible to use {% load %} to load this tag. Instead it must be loaded in the same way as the django tags.

So this needs to go somewhere that will force it to run immediately.

# The `add_to_builtins` function changed module in 1.7
try:
    from django.template.loader import add_to_builtins
except ImportError:
    from django.template.base import add_to_builtins


add_to_builtins('my_app.templatetags.overriden_tags')

my_app/templatetags/overriden_tags.py

from django import template
from django.template.loader_tags import do_extends, ExtendsNode

register = template.Library()

@register.tag('extends')
def preventable_extends(parser, token):
    node = do_extends(parser, token)
    return PreventableExtendsNode(node.nodelist, node.parent_name)


class PreventableExtendsNode(ExtendsNode):

    def render(self, context):
        prevent = context.get('prevent_extends')
        if prevent == self.parent_name.var:
            return self.nodelist.render(context)
        return super(PreventableExtendsNode, self).render(context)

mixins.py

class PreventableExtendsMixin(object):

    def __init__(self, **kwargs):
        self.prevent_extends = kwargs.pop('prevent_extends')
        super(PreventableExtendsMixin, self).__init__(**kwargs)

    def get_context_data(self, **kwargs):
        context = super(PreventableExtendsMixin, self).get_context_data(**kwargs)
        context['prevent_extends'] = self.prevent_extends
        return context

Usage

from third_party_app import LoginView

class MyLoginView(PreventableExtendsMixin, LoginView):

    def __init__(self, **kwargs):
        kwargs['prevent_extends'] = 'base.html'
        super(MyLoginView, self).__init__(**kwargs)
👤james

Leave a comment