Coverage for formkit_ninja / parser / template_loader.py: 68.75%
16 statements
« prev ^ index » next coverage.py v7.13.1, created at 2026-02-20 04:40 +0000
« prev ^ index » next coverage.py v7.13.1, created at 2026-02-20 04:40 +0000
1"""
2Template loader abstraction for code generation.
4This module provides:
5- TemplateLoader: Abstract base class for template loading
6- DefaultTemplateLoader: Loads templates from formkit_ninja.parser.templates
7- ExtendedTemplateLoader: Supports multiple package sources with template inheritance
8"""
10from abc import ABC, abstractmethod
11from typing import List
13from jinja2 import ChoiceLoader, Environment, PackageLoader, select_autoescape
16class TemplateLoader(ABC):
17 """
18 Abstract base class for template loaders.
20 Subclasses must implement get_environment() to return a configured Jinja2 Environment.
21 """
23 @abstractmethod
24 def get_environment(self) -> Environment:
25 """
26 Get a configured Jinja2 Environment.
28 Returns:
29 Environment: A Jinja2 Environment instance configured with appropriate
30 template loaders and settings.
31 """
32 pass
35class DefaultTemplateLoader(TemplateLoader):
36 """
37 Default template loader that loads templates from formkit_ninja.parser.templates.
39 This loader provides access to the base templates included with formkit-ninja.
40 """
42 def get_environment(self) -> Environment:
43 """
44 Get a Jinja2 Environment configured to load from formkit_ninja.parser.templates.
46 Returns:
47 Environment: A Jinja2 Environment with PackageLoader for base templates.
48 """
49 return Environment(
50 loader=PackageLoader("formkit_ninja.parser", "templates"),
51 autoescape=select_autoescape(),
52 trim_blocks=True,
53 lstrip_blocks=True,
54 )
57class ExtendedTemplateLoader(TemplateLoader):
58 """
59 Extended template loader that supports multiple package sources.
61 Templates are loaded from packages in order, with earlier packages taking precedence.
62 This allows projects to override base templates with custom versions.
64 The loader looks for a "templates" subdirectory within each package.
66 Args:
67 template_packages: List of package names (e.g., ["myapp", "formkit_ninja.parser"]).
68 Templates are expected to be in a "templates" subdirectory of each package.
69 """
71 def __init__(self, template_packages: List[str]) -> None:
72 """
73 Initialize ExtendedTemplateLoader.
75 Args:
76 template_packages: List of package names where templates can be found.
77 Templates are expected in a "templates" subdirectory.
78 Packages are checked in order, first match wins.
79 """
80 self.template_packages = template_packages
82 def get_environment(self) -> Environment:
83 """
84 Get a Jinja2 Environment configured to load from multiple package sources.
86 Returns:
87 Environment: A Jinja2 Environment with ChoiceLoader for multiple sources.
88 """
89 loaders = [PackageLoader(package, "templates") for package in self.template_packages]
91 return Environment(
92 loader=ChoiceLoader(loaders),
93 autoescape=select_autoescape(),
94 trim_blocks=True,
95 lstrip_blocks=True,
96 )