@@ -67,11 +67,13 @@ def format_name(params, hash, ctx):
6767```
6868"""
6969
70+ from __future__ import annotations
71+
7072import json
7173import sys # noqa
7274from collections .abc import Callable
7375from pathlib import Path
74- from typing import Any
76+ from typing import Any , TypedDict
7577
7678import structlog
7779
@@ -91,6 +93,22 @@ def format_name(params, hash, ctx):
9193
9294HelperFn = Callable [[list [Any ], dict [str , Any ], dict [str , Any ]], str ]
9395NativeHelperFn = Callable [[str , str , str ], str ]
96+ Context = dict [str , Any ]
97+
98+
99+ class RuntimeOptions (TypedDict ):
100+ """Options for the runtime of a Handlebars template.
101+
102+ These options are used to configure the runtime behavior of a Handlebars
103+ template. They can be passed to the compiled template function to customize
104+ the rendering process.
105+ """
106+
107+ data : dict [str , Any ] | None
108+ # TODO: Add other options based on supported features.
109+
110+
111+ CompiledRenderer = Callable [[Context , RuntimeOptions | None ], str ]
94112
95113
96114class EscapeFunction (StrEnum ):
@@ -427,7 +445,7 @@ def unregister_template(self, name: str) -> None:
427445 self ._template .unregister_template (name )
428446 logger .debug ({'event' : 'template_unregistered' , 'name' : name })
429447
430- def render (self , name : str , data : dict [str , Any ]) -> str :
448+ def render (self , name : str , data : dict [str , Any ], options : RuntimeOptions | None = None ) -> str :
431449 """Render a template with the given data.
432450
433451 Renders a previously registered template using the provided data
@@ -437,6 +455,7 @@ def render(self, name: str, data: dict[str, Any]) -> str:
437455 Args:
438456 name: The name of the template to render
439457 data: The data to render the template with
458+ options: Additional options for the template.
440459
441460 Returns:
442461 str: The rendered template string
@@ -445,6 +464,8 @@ def render(self, name: str, data: dict[str, Any]) -> str:
445464 ValueError: If the template does not exist or there is a rendering
446465 error.
447466 """
467+ # TODO: options is currently ignored; need to add support for it.
468+
448469 try :
449470 result = self ._template .render (name , json .dumps (data ))
450471 logger .debug ({'event' : 'template_rendered' , 'name' : name })
@@ -457,7 +478,7 @@ def render(self, name: str, data: dict[str, Any]) -> str:
457478 })
458479 raise
459480
460- def render_template (self , template_string : str , data : dict [str , Any ]) -> str :
481+ def render_template (self , template_string : str , data : dict [str , Any ], options : RuntimeOptions | None = None ) -> str :
461482 """Render a template string directly without registering it.
462483
463484 Parses and renders the template string in one step. This is useful for
@@ -467,6 +488,7 @@ def render_template(self, template_string: str, data: dict[str, Any]) -> str:
467488 Args:
468489 template_string: The template string to render
469490 data: The data to render the template with
491+ options: Additional options for the template.
470492
471493 Returns:
472494 Rendered template string.
@@ -475,8 +497,15 @@ def render_template(self, template_string: str, data: dict[str, Any]) -> str:
475497 ValueError: If there is a syntax error in the template or a
476498 rendering error.
477499 """
500+ # TODO: options is currently ignored; need to add support for it.
478501 try :
479- result = self ._template .render_template (template_string , json .dumps (data ))
502+ # Serialize options if provided, focusing on the '@data' part
503+ options_json = None
504+ if options :
505+ # Pass the whole options dict as JSON
506+ options_json = json .dumps (options )
507+
508+ result = self ._template .render_template (template_string , json .dumps (data ), options_json )
480509 logger .debug ({'event' : 'template_string_rendered' })
481510 return result
482511 except ValueError as e :
@@ -486,7 +515,7 @@ def render_template(self, template_string: str, data: dict[str, Any]) -> str:
486515 })
487516 raise
488517
489- def compile (self , template_string : str ) -> Callable [[ dict [ str , Any ]], str ] :
518+ def compile (self , template_string : str ) -> CompiledRenderer :
490519 """Compile a template string into a reusable function.
491520
492521 This method provides an interface similar to Handlebars.js's `compile`.
@@ -502,8 +531,8 @@ def compile(self, template_string: str) -> Callable[[dict[str, Any]], str]:
502531 template_string: The Handlebars template string to compile.
503532
504533 Returns:
505- A callable function that takes a data dictionary and returns the
506- rendered string.
534+ A callable function that takes a data dictionary and some runtime
535+ options and returns the rendered string.
507536
508537 Raises:
509538 ValueError: If there is a syntax error during the initial parse
@@ -512,8 +541,17 @@ def compile(self, template_string: str) -> Callable[[dict[str, Any]], str]:
512541 called.
513542 """
514543
515- def compiled (data : dict [str , Any ]) -> str :
516- return self .render_template (template_string , data )
544+ def compiled (context : Context , options : RuntimeOptions | None = None ) -> str :
545+ """Compiled template function.
546+
547+ Args:
548+ context: The data to render the template with.
549+ options: Additional options for the template.
550+
551+ Returns:
552+ The rendered template string.
553+ """
554+ return self .render_template (template_string , context , options )
517555
518556 return compiled
519557
0 commit comments