Skip to content

Instantly share code, notes, and snippets.

@hvdklauw
Created December 3, 2024 18:30
Show Gist options
  • Save hvdklauw/5041323a82e9936d544dd7b38a85c5a4 to your computer and use it in GitHub Desktop.
Save hvdklauw/5041323a82e9936d544dd7b38a85c5a4 to your computer and use it in GitHub Desktop.
Template tag to rerender a block
from django import template
from django.template.loader import get_template
from django.template.loader_tags import BlockNode, ExtendsNode
register = template.Library()
@register.simple_tag(takes_context=True)
def reblock(context, block_name):
"""
Renders a specific block from the current template or its parent templates.
:param context: The current template context.
:param block_name: The name of the block to render.
Usage:
{% load reblock %}
...
<h1>{% block title %}Default Title{% endblock %}</h1>
{% reblock "title" %}
...
"""
# Helper function to find block nodes in the template
def find_block(nodelist, block_name):
for node in nodelist:
if isinstance(node, BlockNode) and node.name == block_name:
return node
if hasattr(node, 'nodelist'):
found = find_block(node.nodelist, block_name)
if found:
return found
return None
# Traverse the template tree to find the block
template_instance = context.template
while template_instance:
block = find_block(template_instance.nodelist, block_name)
if block:
return block.render(context)
# Move to the parent template
try:
extends_node = next((node for node in template_instance.nodelist.get_nodes_by_type(ExtendsNode)), None)
if extends_node:
# Use the template loader to fetch the parent template
parent_template_name = extends_node.parent_name.resolve(context)
parent_template = get_template(parent_template_name)
template_instance = parent_template.template
else:
break
except Exception as e:
raise ValueError(f"Error resolving parent template: {e}")
raise ValueError(f"Block '{block_name}' not found in the template hierarchy.")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment