|
from django.template import Library, TemplateSyntaxError |
|
from django.template.loader_tags import BlockNode, BLOCK_CONTEXT_KEY |
|
|
|
register = Library() |
|
|
|
|
|
class IfBlockNode(BlockNode): |
|
|
|
def __repr__(self): |
|
return "<IfBlock Node: %s. Contents: %r>" % (self.name, self.nodelist) |
|
|
|
def render(self, context): |
|
block_context = context.render_context.get(BLOCK_CONTEXT_KEY) |
|
context.push() |
|
if block_context is None: |
|
result = '' |
|
else: |
|
push = block = block_context.pop(self.name) |
|
if block is None or block is self: |
|
result = '' |
|
else: |
|
context.push() |
|
# Create new block so we can store context without |
|
# thread-safety issues. |
|
block = IfBlockNode(block.name, block.nodelist) |
|
block.context = context |
|
context['block'] = block |
|
result = block.nodelist.render(context) |
|
context.pop() |
|
context['blockoutput'] = result |
|
result = self.nodelist.render(context) |
|
if push is not None: |
|
block_context.push(self.name, push) |
|
context.pop() |
|
return result |
|
|
|
def super(self): |
|
render_context = self.context.render_context |
|
if BLOCK_CONTEXT_KEY in render_context: |
|
block = render_context[BLOCK_CONTEXT_KEY].get_block(self.name) |
|
if block is not None and not isinstance(block, IfBlockNode): |
|
return super(IfBlockNode, self).render(self.context) |
|
return '' |
|
|
|
|
|
@register.tag(name="ifblock") |
|
def do_ifblock(parser, token): |
|
bits = token.contents.split() |
|
if len(bits) != 2: |
|
raise TemplateSyntaxError("'%s' tag takes only one argument" % bits[0]) |
|
block_name = bits[1] |
|
# Keep track of the names of BlockNodes found in this template, so we can |
|
# check for duplication. |
|
try: |
|
if block_name in parser.__loaded_blocks: |
|
msg = "'%s' tag with name '%s' appears more than once" |
|
raise TemplateSyntaxError(msg % (bits[0], block_name)) |
|
parser.__loaded_blocks.append(block_name) |
|
except AttributeError: # parser.__loaded_blocks isn't a list yet |
|
parser.__loaded_blocks = [block_name] |
|
|
|
nodelist = parser.parse(('endifblock', 'endifblock %s' % block_name)) |
|
parser.delete_first_token() |
|
return IfBlockNode(block_name, nodelist) |