Update simple tag implementation from Django PR
This commit is contained in:
parent
5044f6d822
commit
15fd589c6b
1 changed files with 54 additions and 19 deletions
|
@ -1,5 +1,6 @@
|
||||||
from inspect import getfullargspec, unwrap
|
from inspect import getfullargspec, unwrap
|
||||||
from django.template.library import parse_bits, SimpleNode
|
from django.template.library import parse_bits, SimpleNode
|
||||||
|
from django.template.exceptions import TemplateSyntaxError
|
||||||
from functools import wraps
|
from functools import wraps
|
||||||
|
|
||||||
class SimpleBlockNode(SimpleNode):
|
class SimpleBlockNode(SimpleNode):
|
||||||
|
@ -9,43 +10,77 @@ class SimpleBlockNode(SimpleNode):
|
||||||
|
|
||||||
def get_resolved_arguments(self, context):
|
def get_resolved_arguments(self, context):
|
||||||
resolved_args, resolved_kwargs = super().get_resolved_arguments(context)
|
resolved_args, resolved_kwargs = super().get_resolved_arguments(context)
|
||||||
resolved_args.insert(1 if self.takes_context else 0, self.nodelist.render(context))
|
|
||||||
|
# Restore the "content" argument.
|
||||||
|
# It will move depending on whether takes_context was passed.
|
||||||
|
resolved_args.insert(
|
||||||
|
1 if self.takes_context else 0, self.nodelist.render(context)
|
||||||
|
)
|
||||||
|
|
||||||
return resolved_args, resolved_kwargs
|
return resolved_args, resolved_kwargs
|
||||||
|
|
||||||
|
|
||||||
def simple_block_tag(register, takes_context=None, name=None):
|
def simple_block_tag(register, takes_context=None, name=None):
|
||||||
def dec(func):
|
def dec(func):
|
||||||
argspec = getfullargspec(unwrap(func))
|
(
|
||||||
|
params,
|
||||||
|
varargs,
|
||||||
|
varkw,
|
||||||
|
defaults,
|
||||||
|
kwonly,
|
||||||
|
kwonly_defaults,
|
||||||
|
_,
|
||||||
|
) = getfullargspec(unwrap(func))
|
||||||
function_name = name or func.__name__
|
function_name = name or func.__name__
|
||||||
|
|
||||||
@wraps(func)
|
@wraps(func)
|
||||||
def tag_compiler(parser, token):
|
def compile_func(parser, token):
|
||||||
|
tag_params = params.copy()
|
||||||
|
|
||||||
|
if takes_context:
|
||||||
|
if len(tag_params) >= 2 and tag_params[1] == "content":
|
||||||
|
del tag_params[1]
|
||||||
|
else:
|
||||||
|
raise TemplateSyntaxError(
|
||||||
|
f"'{function_name}' is decorated with takes_context=True so"
|
||||||
|
" it must have a first argument of 'context' and a second "
|
||||||
|
"argument of 'content'"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
if tag_params and tag_params[0] == "content":
|
||||||
|
del tag_params[0]
|
||||||
|
else:
|
||||||
|
raise TemplateSyntaxError(
|
||||||
|
f"'{function_name}' must have a first argument of 'content'"
|
||||||
|
)
|
||||||
|
|
||||||
bits = token.split_contents()[1:]
|
bits = token.split_contents()[1:]
|
||||||
target_var = None
|
target_var = None
|
||||||
if len(bits) >= 2 and bits[-2] == "as":
|
if len(bits) >= 2 and bits[-2] == "as":
|
||||||
target_var = bits[-1]
|
target_var = bits[-1]
|
||||||
bits = bits[:-2]
|
bits = bits[:-2]
|
||||||
|
|
||||||
params = argspec.args
|
nodelist = parser.parse((f"end{function_name}",))
|
||||||
del params[1 if takes_context else 0]
|
parser.delete_first_token()
|
||||||
|
|
||||||
args, kwargs = parse_bits(
|
args, kwargs = parse_bits(
|
||||||
parser=parser,
|
parser,
|
||||||
bits=bits,
|
bits,
|
||||||
params=params,
|
tag_params,
|
||||||
varargs=argspec.varargs,
|
varargs,
|
||||||
varkw=argspec.varkw,
|
varkw,
|
||||||
defaults=argspec.defaults,
|
defaults,
|
||||||
kwonly=argspec.kwonlyargs,
|
kwonly,
|
||||||
kwonly_defaults=argspec.kwonlydefaults,
|
kwonly_defaults,
|
||||||
takes_context=takes_context,
|
takes_context,
|
||||||
name=function_name
|
function_name,
|
||||||
)
|
)
|
||||||
|
|
||||||
nodelist = parser.parse((f'end{function_name}',))
|
return SimpleBlockNode(
|
||||||
parser.delete_first_token()
|
nodelist, func, takes_context, args, kwargs, target_var
|
||||||
return SimpleBlockNode(nodelist, func, takes_context, args, kwargs, target_var)
|
)
|
||||||
|
|
||||||
register.tag(function_name, tag_compiler)
|
register.tag(function_name, compile_func)
|
||||||
return func
|
return func
|
||||||
|
|
||||||
return dec
|
return dec
|
||||||
|
|
Loading…
Reference in a new issue