11"""
22This module provides a Jinja2 environment.
33"""
4+
45import os
56from enum import Enum
6-
7- from jinja2 import Environment , PackageLoader , Template , select_autoescape
7+ from pathlib import Path
8+ from typing import Optional
9+
10+ from jinja2 import (
11+ ChoiceLoader ,
12+ Environment ,
13+ FileSystemLoader ,
14+ PackageLoader ,
15+ Template ,
16+ select_autoescape ,
17+ )
818
919from . import get_http_status_phrase , highlight_params , read_dict , sort_dict
1020from .common import DocumentsWriter , is_reference
@@ -62,29 +72,50 @@ def __init__(
6272
6373
6474def get_environment (
65- package_name : str , views_style : OutputStyle = OutputStyle .MKDOCS
75+ package_name : str ,
76+ views_style : OutputStyle = OutputStyle .MKDOCS ,
77+ custom_templates_path : Optional [str ] = None ,
6678) -> Environment :
6779 templates_folder = f"views_{ views_style .name } " .lower ()
6880
81+ loaders = []
82+
83+ # If custom templates path is provided, validate and add FileSystemLoader first
84+ if custom_templates_path :
85+ custom_path = Path (custom_templates_path )
86+ if not custom_path .exists ():
87+ raise ValueError (
88+ f"Custom templates path does not exist: { custom_templates_path } "
89+ )
90+ if not custom_path .is_dir ():
91+ raise ValueError (
92+ f"Custom templates path is not a directory: { custom_templates_path } "
93+ )
94+ loaders .append (FileSystemLoader (str (custom_path )))
95+
96+ # Always add the package loader as fallback
6997 try :
70- loader = PackageLoader (package_name , templates_folder )
98+ loaders . append ( PackageLoader (package_name , templates_folder ) )
7199 except ValueError as package_loading_error : # pragma: no cover
72- raise PackageLoadingError (
73- views_style , templates_folder
74- ) from package_loading_error
75- else :
76- env = Environment (
77- loader = loader ,
78- autoescape = select_autoescape (["html" , "xml" ])
79- if os .environ .get ("SELECT_AUTOESCAPE" ) in {"YES" , "Y" , "1" }
80- else False ,
81- auto_reload = True ,
82- enable_async = False ,
83- )
84- configure_filters (env )
85- configure_functions (env )
100+ if not custom_templates_path :
101+ raise PackageLoadingError (
102+ views_style , templates_folder
103+ ) from package_loading_error
104+
105+ loader = ChoiceLoader (loaders )
106+
107+ env = Environment (
108+ loader = loader ,
109+ autoescape = select_autoescape (["html" , "xml" ])
110+ if os .environ .get ("SELECT_AUTOESCAPE" ) in {"YES" , "Y" , "1" }
111+ else False ,
112+ auto_reload = True ,
113+ enable_async = False ,
114+ )
115+ configure_filters (env )
116+ configure_functions (env )
86117
87- return env
118+ return env
88119
89120
90121class Jinja2DocumentsWriter (DocumentsWriter ):
@@ -97,8 +128,9 @@ def __init__(
97128 self ,
98129 package_name : str ,
99130 views_style : OutputStyle = OutputStyle .MKDOCS ,
131+ custom_templates_path : Optional [str ] = None ,
100132 ) -> None :
101- self ._env = get_environment (package_name , views_style )
133+ self ._env = get_environment (package_name , views_style , custom_templates_path )
102134
103135 @property
104136 def env (self ) -> Environment :
0 commit comments