@@ -31,28 +31,30 @@ class JinjaRegistry:
3131 rendering environment used by this extension.
3232 """
3333
34- _filters : dict [str , Callable [[ BuildEnvironment ], Callable ]]
34+ _filters : dict [str , tuple [ Callable , bool ]] # (func, pass_build_env)
3535 _extensions : list [str ]
3636
3737 def __init__ (self ) -> None :
3838 self ._filters = {}
3939 self ._extensions = []
4040
4141 def add_filter (
42- self , name : str , factory : Callable [[ BuildEnvironment ], Callable ]
42+ self , name : str , func : Callable , pass_build_env : bool = False
4343 ) -> None :
44- """Register a filter factory .
44+ """Register a filter.
4545
4646 :param name: The filter name, used in Jinja templates as ``{{ value|name }}``
47- :param factory: A callable that takes a :py:class:`~sphinx.environment.BuildEnvironment`
48- and returns a filter callable
47+ :param func: The filter callable
48+ :param pass_build_env: If True, filter receives
49+ :py:class:`sphinx.environment.BuildEnvironment`
50+ as first arg
4951
5052 .. note:: Using the :py:deco:`filter` decorator is recommended for most cases.
5153
5254 """
5355 if name in self ._filters :
5456 raise ValueError (f'Jinja filter "{ name } " already registered' )
55- self ._filters [name ] = factory
57+ self ._filters [name ] = ( func , pass_build_env )
5658
5759 def add_extension (self , extension : str ) -> None :
5860 """Add a Jinja2 extension.
@@ -111,8 +113,14 @@ class _JinjaEnv(SandboxedEnvironment):
111113
112114 def __init__ (self , * args , ** kwargs ):
113115 super ().__init__ (* args , ** kwargs )
114- for name , factory in REGISTRY ._filters .items ():
115- self .filters [name ] = factory (self ._env )
116+ for name , (func , pass_build_env ) in REGISTRY ._filters .items ():
117+ if pass_build_env :
118+ env = self ._env
119+ self .filters [name ] = lambda value , * args , _func = func , ** kwargs : _func (
120+ env , value , * args , ** kwargs
121+ )
122+ else :
123+ self .filters [name ] = func
116124
117125 @classmethod
118126 def on_builder_inited (cls , app : Sphinx ):
@@ -132,20 +140,22 @@ def is_safe_attribute(self, obj, attr, value=None):
132140 return super ().is_safe_attribute (obj , attr , value )
133141
134142
135- def filter (name : str ):
143+ def filter (name : str , pass_build_env : bool = False ):
136144 """Decorator for adding a filter to the Jinja environment.
137145
138146 Usage::
139147
140148 @filter('my_filter')
141- def my_filter(env: BuildEnvironment):
142- def _filter(value):
143- return value.upper()
144- return _filter
149+ def my_filter(value):
150+ return value.upper()
151+
152+ @filter('my_filter_with_env', pass_build_env=True)
153+ def my_filter_with_env(env: BuildEnvironment, value):
154+ return value.upper()
145155 """
146156
147157 def decorator (ff ):
148- REGISTRY .add_filter (name , ff )
158+ REGISTRY .add_filter (name , ff , pass_build_env )
149159 return ff
150160
151161 return decorator
0 commit comments