"""Provides some wild filters"""
try:
from jinja2 import pass_environment
except ImportError:
from jinja2 import environmentfilter as pass_environment
from typing import TYPE_CHECKING, Any, Callable
from .manager import FilterManager
if TYPE_CHECKING:
from jinja2.environment import Environment
wild_filter_manager = FilterManager()
@wild_filter_manager.register("ifelse, if_else")DOCS
@pass_environment
def ifelse(
env: "Environment",
value: Any,
test: Any,
test_args: Any = (),
true: Any = None,
true_args: Any = (),
false: Any = None,
false_args: Any = (),
) -> Any:
"""An if-else filter, implementing a tenary-like filter.
Use `ifelse` or `if_else`.
Examples:
>>> {{ a | ifelse: isinstance, (int, ),
>>> "plus", (1, ),
>>> "append", (".html", ) }}
>>> # 2 when a = 1
>>> # "a.html" when a = "a"
Args:
value: The base value
test: The test callable or filter name
test_args: Other args (value as the first arg) for the test
true: The callable or filter name when test is True
true_args: Other args (value as the first arg) for the true
When this is None, return the true callable itself or the name
of the filter it self
false: The callable or filter name when test is False
false_args: Other args (value as the first arg) for the false
When this is None, return the false callable itself or the name
of the filter it self
Returns:
The result of true of test result is True otherwise result of false.
"""
def compile_out(func: Any, args: Any) -> Any:
if args is None:
return func
if not isinstance(args, tuple):
args = (args,)
if callable(func):
return func(value, *args)
expr = env.compile_expression(f"value | {func}(*args)")
return expr(value=value, args=args)
test_out = compile_out(test, test_args)
if test_out:
return compile_out(true, true_args)
return compile_out(false, false_args)
@wild_filter_manager.registerDOCS
def call(fn: Callable, *args, **kwargs) -> Any:
"""Call a function with passed arguments
Examples:
>>> {{ int | call: "1" | plus: 1 }}
>>> # 2
Args:
fn: The callable
*args: and
**kwargs: The arguments for the callable
Returns:
The result of calling the function
"""
return fn(*args, **kwargs)
@wild_filter_manager.registerDOCS
def each(array: Any, fn: Callable, *args: Any, **kwargs: Any) -> Any:
"""Call a function for each item in an array.
With wild mode, you can use the 'map' filter to apply a function to each
item in an array. However, this filter is different from the 'map' filter
in that it takes the array as the first argument and additional arguments
passed to the function are allowed.
Examples:
>>> {{ floor | map: [1.1, 2.1, 3.1] | list }}
>>> # [1, 2, 3]
>>> {{ [1.1, 2.1, 3.1] | each: floor }}
>>> # [1, 2, 3]
>>> {{ [1.1, 2.1, 3.1] | each: plus, 1 }}
>>> # [2.2, 3.2, 4.2]
Args:
array: The array
fn: The callable
Returns:
The result of calling the function for each item in the array
"""
return [fn(item, *args, **kwargs) for item in array]