Simple HTML Generation https://minihtml.trendels.name/

layout component must be created each time the template is called

+21 -6
+5 -5
src/minihtml/_template.py
··· 3 3 from functools import wraps 4 4 from typing import Callable, Concatenate, ParamSpec, TextIO, TypeAlias, overload 5 5 6 - from ._component import Component 6 + from ._component import Component, ComponentWrapper 7 7 from ._core import HasNodes, Node, iter_nodes, register_with_context 8 8 from ._template_context import get_template_context, template_context 9 9 ··· 30 30 31 31 @overload 32 32 def template( 33 - layout: Component, *, doctype: bool = ... 33 + layout: ComponentWrapper[...], *, doctype: bool = ... 34 34 ) -> Callable[[TemplateImplLayout[P]], Callable[P, str]]: ... 35 35 36 36 37 37 def template( 38 - layout: Component | None = None, 38 + layout: ComponentWrapper[...] | None = None, 39 39 *, 40 40 doctype: bool = True, 41 41 ) -> ( ··· 61 61 @wraps(fn) 62 62 def wrapper(*args: P.args, **kwargs: P.kwargs) -> str: 63 63 with template_context(): 64 - with layout as result: 65 - fn(layout, *args, **kwargs) 64 + with layout() as result: 65 + fn(result, *args, **kwargs) 66 66 return _render(result, doctype=doctype) 67 67 68 68 return wrapper
+16 -1
tests/test_template.py
··· 46 46 47 47 return elem 48 48 49 - @template(layout=my_layout()) 49 + @template(layout=my_layout) 50 50 def my_template(layout: Component, message: str) -> None: 51 51 with layout.slot("title"): 52 52 text("my title") ··· 61 61 <body> 62 62 <div id="content"> 63 63 <div>hello</div> 64 + </div> 65 + </body> 66 + </html> 67 + """) 68 + 69 + # Test that layout is not cached 70 + assert my_template("goodbye") == dedent("""\ 71 + <!doctype html> 72 + <html> 73 + <head> 74 + <title>my title</title> 75 + </head> 76 + <body> 77 + <div id="content"> 78 + <div>goodbye</div> 64 79 </div> 65 80 </body> 66 81 </html>