def render_template (
template_name_or_list: t. Union[ str , Template, t. List[ t. Union[ str , Template] ] ] ,
** context: t. Any
) - > str :
ctx = _app_ctx_stack. top
if ctx is None :
raise RuntimeError(
"This function can only be used when an application context is active."
)
ctx. app. update_template_context( context)
return _render(
ctx. app. jinja_env. get_or_select_template( template_name_or_list) ,
context,
ctx. app,
)
@internalcode
def get_or_select_template (
self,
template_name_or_list: t. Union[
str , "Template" , t. List[ t. Union[ str , "Template" ] ]
] ,
parent: t. Optional[ str ] = None ,
globals : t. Optional[ t. MutableMapping[ str , t. Any] ] = None ,
) - > "Template" :
if isinstance ( template_name_or_list, ( str , Undefined) ) :
return self. get_template( template_name_or_list, parent, globals )
elif isinstance ( template_name_or_list, Template) :
return template_name_or_list
return self. select_template( template_name_or_list, parent, globals )
@internalcode
def get_template (
self,
name: t. Union[ str , "Template" ] ,
parent: t. Optional[ str ] = None ,
globals : t. Optional[ t. MutableMapping[ str , t. Any] ] = None ,
) - > "Template" :
if isinstance ( name, Template) :
return name
if parent is not None :
name = self. join_path( name, parent)
return self. _load_template( name, globals )
@internalcode
def _load_template (
self, name: str , globals : t. Optional[ t. MutableMapping[ str , t. Any] ]
) - > "Template" :
if self. loader is None :
raise TypeError( "no loader for this environment specified" )
cache_key = ( weakref. ref( self. loader) , name)
if self. cache is not None :
template = self. cache. get( cache_key)
if template is not None and (
not self. auto_reload or template. is_up_to_date
) :
if globals :
template. globals . update( globals )
return template
template = self. loader. load( self, name, self. make_globals( globals ) )
if self. cache is not None :
self. cache[ cache_key] = template
return template
@internalcode
def load (
self,
environment: "Environment" ,
name: str ,
globals : t. Optional[ t. MutableMapping[ str , t. Any] ] = None ,
) - > "Template" :
code = None
if globals is None :
globals = { }
source, filename, uptodate = self. get_source( environment, name)
bcc = environment. bytecode_cache
if bcc is not None :
bucket = bcc. get_bucket( environment, name, filename, source)
code = bucket. code
if code is None :
code = environment. compile ( source, name, filename)
if bcc is not None and bucket. code is None :
bucket. code = code
bcc. set_bucket( bucket)
return environment. template_class. from_code(
environment, code, globals , uptodate
)
@internalcode
def compile (
self,
source: t. Union[ str , nodes. Template] ,
name: t. Optional[ str ] = None ,
filename: t. Optional[ str ] = None ,
raw: bool = False ,
defer_init: bool = False ,
) - > t. Union[ str , CodeType] :
source_hint = None
try :
if isinstance ( source, str ) :
source_hint = source
source = self. _parse( source, name, filename)
source = self. _generate( source, name, filename, defer_init= defer_init)
if raw:
return source
if filename is None :
filename = "<template>"
return self. _compile( source, filename)
except TemplateSyntaxError:
self. handle_exception( source= source_hint)
def _generate (
self,
source: nodes. Template,
name: t. Optional[ str ] ,
filename: t. Optional[ str ] ,
defer_init: bool = False ,
) - > str :
return generate(
source,
self,
name,
filename,
defer_init= defer_init,
optimized= self. optimized,
)
def generate (
node: nodes. Template,
environment: "Environment" ,
name: t. Optional[ str ] ,
filename: t. Optional[ str ] ,
stream: t. Optional[ t. TextIO] = None ,
defer_init: bool = False ,
optimized: bool = True ,
) - > t. Optional[ str ] :
if not isinstance ( node, nodes. Template) :
raise TypeError( "Can't compile non template nodes" )
generator = environment. code_generator_class(
environment, name, filename, stream, defer_init, optimized
)
generator. visit( node)
if stream is None :
return generator. stream. getvalue( )
return None
def visit ( self, node: Node, * args: t. Any, ** kwargs: t. Any) - > t. Any:
f = self. get_visitor( node)
if f is not None :
return f( node, * args, ** kwargs)
return self. generic_visit( node, * args, ** kwargs)
def get_visitor ( self, node: Node) - > "t.Optional[VisitCallable]" :
return getattr ( self, f"visit_ { type ( node) . __name__} " , None )
def generic_visit ( self, node: Node, * args: t. Any, ** kwargs: t. Any) - > t. Any:
for child_node in node. iter_child_nodes( ) :
self. visit( child_node, * args, ** kwargs)
def _compile ( self, source: str , filename: str ) - > CodeType:
return compile ( source, filename, "exec" )
def _render ( template: Template, context: dict , app: "Flask" ) - > str :
before_render_template. send( app, template= template, context= context)
rv = template. render( context)
template_rendered. send( app, template= template, context= context)
return rv
def render ( self, * args: t. Any, ** kwargs: t. Any) - > str :
if self. environment. is_async:
import asyncio
close = False
try :
loop = asyncio. get_running_loop( )
except RuntimeError:
loop = asyncio. new_event_loop( )
close = True
try :
return loop. run_until_complete( self. render_async( * args, ** kwargs) )
finally :
if close:
loop. close( )
ctx = self. new_context( dict ( * args, ** kwargs) )
try :
return self. environment. concat( self. root_render_func( ctx) )
except Exception:
self. environment. handle_exception( )
async def render_async ( self, * args: t. Any, ** kwargs: t. Any) - > str : 1
if not self. environment. is_async:
raise RuntimeError(
"The environment was not created with async mode enabled."
)
ctx = self. new_context( dict ( * args, ** kwargs) )
try :
return self. environment. concat(
[ n async for n in self. root_render_func( ctx) ]
)
except Exception:
return self. environment. handle_exception( )