Labmdas¶
Lambdas are collections.abc.Callable values found in the template
rendering scope that are called when referenced, allowing complext
context-aware rendering logic to be implemented.
Lambda variables¶
As part of standard Mustache lambda extension, any collections.abc.Callable
variable will be invoked when used as a variable, and its return value will
be rendered as a template.
This is the simplest type of lambda.
import mstache
print(mstache.render(
'{{lambda}} world!',
{
'lambda': lambda: '{{hello}}',
'hello': 'Hello',
},
))
# Hello world!
Lambda blocks¶
If a lambda is invoked as a block, the content of said block will be passed
to the collections.abc.Callable as parameter.
There are currently two different ways of implement lambda blocks.
Explicit render mode¶
Also known as chevron-style, current default behavior, the lambda
collections.abc.Callable will expect two parameters, template
and render, and its return value will be included in the template
as a value.
This means that any template rendering must happen by explicitly calling
the received render function, which works in the current scope and inherits
the configuration of the current rendering context, and then returned.
import mstache
print(mstache.render(
'{{#lambda}}content{{/lambda}} world!',
{
'lambda': lambda content, render: (
# explicit render: return render result
render('{{' + content + '}}')
),
'content': 'Hello',
},
))
# Hello world!
Implicit render mode¶
Also known as Mustache-style, enabled by passing lambda_render=None,
the lambda collections.abc.Callable will expect a single template
parameter, and its return value will be as template, and rendered, before
being incuded in the output.
import mstache
print(mstache.render(
'{{#lambda}}content{{/lambda}} world!',
{
'lambda': lambda content: (
# implicit render: return template
'{{' + content + '}}'
),
'content': 'Hello',
},
lambda_render=None,
))
# Hello world!
Virtual properties¶
Virtual properties are, essentially, generic object property lambdas.
They are useful for when typical template lambdas, which receive template data, can’t effectively cover operations made with objects in the rendering scope.
This was traditionally done by patching JavaScript prototypes, but that kind of object manipulation is considered unsafe in Python.
To mitigate this, mstache.default_getter() can receive a mapping
of virtual properties to be made available under any scope, effectively
functioning as injected property getters.
While you can provide your own getter function to mstache.render(),
it’s simpler to just wrap mstache.default_getter() via
functools.partial() to include extra virtual properties, extending
those from mstache.default_virtuals.
import functools
import mstache
print(mstache.render(
'{{text.word_count}} words',
{'text': 'virtual properties are cool'},
getter=functools.partial(
mstache.default_getter,
virtuals={
**mstache.default_virtuals,
'word_count': lambda text: len(text.split()),
},
),
))
# 4 words
Please note both AttributeError and TypeError
exceptions raised from virtual property functions are appropriately ignored by
by mstache.default_getter().