class Komponent
from yak.component import Komponent
Block-type `TemplateTag` similar in every other aspect to Django's `{% include %}` tag.
Ancestors (MRO)
- builtins.object
- yak.tags.TemplateTag
- yak.component.Komponent
Attribute | Type | Defined in |
---|---|---|
__dict__ |
getset_descriptor
|
yak.tags.TemplateTag |
__weakref__ |
getset_descriptor
|
yak.tags.TemplateTag |
Attribute | Value | Defined in |
---|---|---|
accepts_with_context |
True |
yak.component.Komponent |
accepts_with_context |
False |
yak.tags.TemplateTag |
allow_as |
True |
yak.tags.TemplateTag |
is_block_node |
True |
yak.component.Komponent |
is_block_node |
False |
yak.tags.TemplateTag |
node_class |
<class 'yak.tags.InclusionNode'> |
yak.component.Komponent |
nodelist |
None |
yak.tags.TemplateTag |
template_name |
None |
yak.tags.TemplateTag |
with_context |
None |
yak.tags.TemplateTag |
def __call__(self, parser, token)
yak.tags.TemplateTag
- gets (unevaluated) `args` and `kwargs` from the token string - collects internal nodes into `nodelist` if this is a block tag - passes `args`, `kwargs` and eventual `nodelist` and `end_token` to the `parse` method - creates and returns the render `Node`
def __call__(self, parser, token):
'''
- gets (unevaluated) `args` and `kwargs` from the token string
- collects internal nodes into `nodelist` if this is a block tag
- passes `args`, `kwargs` and eventual `nodelist` and `end_token` to the `parse` method
- creates and returns the render `Node`
'''
self.parser = parser
# args and kwargs will respectively be a list and a dict of `FilterExpression`s
args, kwargs = self._get_args_kwargs(parser, token)
if self.is_block_node:
nodelist = NodeList()
nodelist.must_be_first = False
end_tag = self.deduce_end_tag(token)
# Read and tokenize the template until we encounter the corresponding endtag.
parser.extend_nodelist(
nodelist,
NodeListRenderer(parser.parse([end_tag]), self.uuid),
token
)
end_token = parser.next_token()
else:
nodelist = None
end_token = None
self.parse(args, kwargs, nodelist, end_token)
node_args, node_kwargs = self.get_node_args_kwargs(args, kwargs)
# TODO: check this isn't an issue for GC
self.node = self.node_class(*node_args, **node_kwargs)
self.node.template_tag = self
return self.node
def __init__(self, **kwargs)
yak.tags.TemplateTag
Do not call directly. Use `as_tag` instead. Any `kwarg` passed to this method will be mapped and assigned to an attribute or method on the object. This is useful if you'd like to avoid subclassing.
def __init__(self, **kwargs):
'''
Do not call directly. Use `as_tag` instead.
Any `kwarg` passed to this method will be mapped and assigned
to an attribute or method on the object.
This is useful if you'd like to avoid subclassing.
'''
for attr, val in kwargs.items():
if not hasattr(self, attr):
raise AttributeError(f'{self.__class__.__name__} received unknown parameter "{attr}"')
setattr(self, attr, val)
# stores initial kwargs, this will be needed for handling nested similar tags
self._init_kwargs = kwargs
def as_tag(cls, *args, **kwargs)
yak.tags.TemplateTag
Class method used to create a templatetag function. Similar to `as_view` on class-based views
@classmethod
def as_tag(cls, *args, **kwargs):
'''
Class method used to create a templatetag function.
Similar to `as_view` on class-based views
'''
def func(parser, token):
return cls(*args, **kwargs)(parser, token)
func.__name__ = cls.__name__.lower()
return func
def clean_as(self, bits)
yak.tags.TemplateTag
Removes `as` keyword if present and store the `target_var` on the `TemplateTag`
def clean_as(self, bits):
'''
Removes `as` keyword if present and store the `target_var` on the `TemplateTag`
'''
if len(bits) >= 2 and bits[-2] == "as":
if not self.allow_as:
raise AssignmentNotSupported(f'{self.__class__.__name__} does not support "as"')
self.target_var = bits[-1]
del bits[-2:]
def clean_bits(self, bits)
yak.component.Komponent
yak.component.Komponent
Stores the `FilterExpression` representing the template name during parsing. This expression will have be evaluated by the `Node` at render time.
def clean_bits(self, bits):
'''
Stores the `FilterExpression` representing the template name during parsing.
This expression will have be evaluated by the `Node` at render time.
'''
super().clean_bits(bits)
self.template_name = self.parser.compile_filter(bits.pop(0))
yak.tags.TemplateTag
Called during tag parsing to extract the "bits" (raw pieces of the template string inside `{%` `%}`) This method **modifies** `bits`
def clean_bits(self, bits):
'''
Called during tag parsing to extract the "bits"
(raw pieces of the template string inside `{%` `%}`)
This method **modifies** `bits`
'''
self.clean_as(bits)
self.clean_with(bits)
def clean_with(self, bits)
yak.tags.TemplateTag
Removes `with` keyword if present and store the `with_context`, a list of keyword arguments, on the `TemplateTag` for later evaluation.
def clean_with(self, bits):
'''
Removes `with` keyword if present and store the `with_context`, a list of keyword arguments,
on the `TemplateTag` for later evaluation.
'''
if self.accepts_with_context:
if 'with' not in bits:
return
pos = bits.index('with')
if pos == len(bits) + 1:
raise WithNotSupported(f'missing assignements after "with" in {self.__class__.__name__}')
_, self.with_context = parse_bits(self.parser, bits[pos + 1:],
[], None, 'with_context', None, [], {}, # fake argspec
False, f'{self.__class__.__name__}.render - with_context')
del bits[pos:]
elif 'with' in bits:
raise WithNotSupported(self.__class__.__name__)
def deduce_end_tag(self, token)
yak.tags.TemplateTag
def deduce_end_tag(self, token):
return f'end{self.tag_extract(token)}'
def get_arg_spec(cls, func, discard_self=True)
yak.tags.TemplateTag
@classmethod
def get_arg_spec(cls, func, discard_self=True):
((_discarded_self, *params), varargs, varkw, defaults, kwonly, kwonly_defaults, _,) \
= getfullargspec(unwrap(func))
if not discard_self:
params = (_discarded_self, *params)
return params, varargs, varkw, defaults, kwonly, kwonly_defaults
def get_node_args_kwargs(self, args, kwargs)
yak.tags.TemplateTag
def get_node_args_kwargs(self, args, kwargs):
return (
self.render,
self.takes_context,
args,
kwargs,
self.get_node_last_arg()
), dict()
def get_node_last_arg(self)
yak.tags.TemplateTag
Called upon when creating the `Node` (as specified by `node_class`). Django's `SimpleNode` and `InclusionNode` have different signature. This method returns the `template_name` (therefore `None` if no `template_name` was defined) `SimpleNode` accepts `target_var` as last arg (we are setting this using `AssignmentNodeMixin` instead) while `InclusionNode` a template name.
def get_node_last_arg(self):
'''
Called upon when creating the `Node` (as specified by `node_class`).
Django's `SimpleNode` and `InclusionNode` have different signature.
This method returns the `template_name` (therefore `None` if no `template_name` was defined)
`SimpleNode` accepts `target_var` as last arg
(we are setting this using `AssignmentNodeMixin` instead)
while `InclusionNode` a template name.
'''
return self.template_name
def get_with_context(self, context)
yak.tags.TemplateTag
Evaluates the content of `with_context` before returning it
def get_with_context(self, context):
'''
Evaluates the content of `with_context` before returning it
'''
if self.with_context is None:
return dict()
return {k: v.resolve(context) for k, v in self.with_context.items()}
def handle_end_token(self, token)
yak.tags.TemplateTag
Doesn't do anything by default with the end or closing token. You might want to override if eg your non-inclusion `TemplateTag` wraps its contents in a `<div>`
def handle_end_token(self, token):
'''
Doesn't do anything by default with the end or closing token.
You might want to override if eg your non-inclusion `TemplateTag`
wraps its contents in a `<div>`
'''
pass
def node_class(self)
yak.tags.TemplateTag
Automatically deduces whether to use a SimpleNode or InclusionNode. You might want to override this with a simple attribute in your subclasses. If using a custom node class, it should accept the following: - a render method (`self.render`) - a takes_context boolean - a list (`args`) - a dict (`kwargs`) - a template name or `None`
def parse(self, args, kwargs, nodelist=None, end_token=None)
yak.tags.TemplateTag
Called at parsing time after collecting the internal nodelist if applicable. You might want to override this for eg storing the nodelist in the context or a template partial.
def parse(self, args, kwargs, nodelist=None, end_token=None):
'''
Called at parsing time after collecting the internal nodelist if applicable.
You might want to override this for eg storing the nodelist in the context
or a template partial.
'''
self.nodelist = nodelist
def render(self, context)
yak.component.Komponent
yak.component.Komponent
Stores the rendered contents of the internal node list in the context as `yield` alongside with any evaluted `with_context`. A convenience `has_block` variable is also set to represent whether or not there is something in `yield`.
def render(self, context):
'''
Stores the rendered contents of the internal node list in the context as `yield`
alongside with any evaluted `with_context`.
A convenience `has_block` variable is also set to represent whether or not
there is something in `yield`.
'''
slot_content = self.nodelist.render(context)
return {
**context.flatten(),
**self.get_with_context(context),
'_parent_uuid': self.uuid,
'yield': slot_content,
'has_block': len(slot_content.strip()) > 0,
}
yak.tags.TemplateTag
This is the only method you probably need to override. If you require the template contex, accept `context` as first argument (eg `def render(self, context):`). The arguments of this method will be automatica
def render(self):
'''
This is the only method you probably need to override.
If you require the template contex, accept `context` as first argument
(eg `def render(self, context):`).
The arguments of this method will be automatica
'''
pass
def tag_extract(self, token)
yak.tags.TemplateTag
def tag_extract(self, token):
return token.contents.split(' ', 1)[0]
def takes_context(self)
yak.tags.TemplateTag
Whether or not this TemplateTag takes the template context. This is deduced by inspecting the `render` method and looking at the name of its first arg.
def uuid(self)
yak.tags.TemplateTag