From 063544167d6691c081007612419c237962dd1c71 Mon Sep 17 00:00:00 2001 From: Tobey Asinugo Date: Tue, 20 May 2025 11:52:15 +0100 Subject: [PATCH] allow iterables template paths --- src/flask/app.py | 13 ++++++++----- src/flask/blueprints.py | 5 ++++- src/flask/sansio/app.py | 13 ++++++++----- src/flask/sansio/blueprints.py | 12 ++++++++---- src/flask/sansio/scaffold.py | 22 +++++++++++++++++----- 5 files changed, 45 insertions(+), 20 deletions(-) diff --git a/src/flask/app.py b/src/flask/app.py index 1232b03d..ef475fda 100644 --- a/src/flask/app.py +++ b/src/flask/app.py @@ -158,10 +158,10 @@ class Flask(App): Defaults to False. :param subdomain_matching: consider the subdomain relative to :data:`SERVER_NAME` when matching routes. Defaults to False. - :param template_folder: the folder that contains the templates that should - be used by the application. Defaults to - ``'templates'`` folder in the root path of the - application. + :param template_folder: the folder or list of folders that contains the + templates that should be used by the application. + Defaults to ``'templates'`` folder in the root + path of the application. :param instance_path: An alternative instance path for the application. By default the folder ``'instance'`` next to the package or module is assumed to be the instance @@ -231,7 +231,10 @@ class Flask(App): static_host: str | None = None, host_matching: bool = False, subdomain_matching: bool = False, - template_folder: str | os.PathLike[str] | None = "templates", + template_folder: ( + str | os.PathLike[str] | + t.Sequence[t.Union[str, "os.PathLike[str]"]] | None + ) = "templates", instance_path: str | None = None, instance_relative_config: bool = False, root_path: str | None = None, diff --git a/src/flask/blueprints.py b/src/flask/blueprints.py index b6d4e433..1fb1b987 100644 --- a/src/flask/blueprints.py +++ b/src/flask/blueprints.py @@ -22,7 +22,10 @@ class Blueprint(SansioBlueprint): import_name: str, static_folder: str | os.PathLike[str] | None = None, static_url_path: str | None = None, - template_folder: str | os.PathLike[str] | None = None, + template_folder: ( + str | os.PathLike[str] | None | + t.Sequence[t.Union[str, "os.PathLike[str]"]] | None + )= None, url_prefix: str | None = None, subdomain: str | None = None, url_defaults: dict[str, t.Any] | None = None, diff --git a/src/flask/sansio/app.py b/src/flask/sansio/app.py index ceab45cb..d378ea15 100644 --- a/src/flask/sansio/app.py +++ b/src/flask/sansio/app.py @@ -136,10 +136,10 @@ class App(Scaffold): Defaults to False. :param subdomain_matching: consider the subdomain relative to :data:`SERVER_NAME` when matching routes. Defaults to False. - :param template_folder: the folder that contains the templates that should - be used by the application. Defaults to - ``'templates'`` folder in the root path of the - application. + :param template_folder: the folder or list of folders that contains the + templates that should be used by the application. + Defaults to ``'templates'`` folder in the root + path of the application. :param instance_path: An alternative instance path for the application. By default the folder ``'instance'`` next to the package or module is assumed to be the instance @@ -287,7 +287,10 @@ class App(Scaffold): static_host: str | None = None, host_matching: bool = False, subdomain_matching: bool = False, - template_folder: str | os.PathLike[str] | None = "templates", + template_folder: ( + str | os.PathLike[str] | + t.Sequence[t.Union[str, "os.PathLike[str]"]] | None + ) = "templates", instance_path: str | None = None, instance_relative_config: bool = False, root_path: str | None = None, diff --git a/src/flask/sansio/blueprints.py b/src/flask/sansio/blueprints.py index 4f912cca..5e7b43c3 100644 --- a/src/flask/sansio/blueprints.py +++ b/src/flask/sansio/blueprints.py @@ -145,9 +145,10 @@ class Blueprint(Scaffold): Defaults to ``static_folder``. If the blueprint does not have a ``url_prefix``, the app's static route will take precedence, and the blueprint's static files won't be accessible. - :param template_folder: A folder with templates that should be added - to the app's template search path. The path is relative to the - blueprint's root path. Blueprint templates are disabled by + :param template_folder: A folder or list of folders with templates + that should be added to the app's template search path. + The path is relative to the blueprint's root path is absolute + paths is not presented. Blueprint templates are disabled by default. Blueprint templates have a lower precedence than those in the app's templates folder. :param url_prefix: A path to prepend to all of the blueprint's URLs, @@ -177,7 +178,10 @@ class Blueprint(Scaffold): import_name: str, static_folder: str | os.PathLike[str] | None = None, static_url_path: str | None = None, - template_folder: str | os.PathLike[str] | None = None, + template_folder: ( + str | os.PathLike[str] | + t.Sequence[t.Union[str, "os.PathLike[str]"]] | None + ) = None, url_prefix: str | None = None, subdomain: str | None = None, url_defaults: dict[str, t.Any] | None = None, diff --git a/src/flask/sansio/scaffold.py b/src/flask/sansio/scaffold.py index 3a839f5a..6c62840a 100644 --- a/src/flask/sansio/scaffold.py +++ b/src/flask/sansio/scaffold.py @@ -6,6 +6,7 @@ import pathlib import sys import typing as t from collections import defaultdict +from collections.abc import Sequence from functools import update_wrapper from jinja2 import BaseLoader @@ -58,7 +59,7 @@ class Scaffold: :param static_folder: Path to a folder of static files to serve. If this is set, a static route will be added. :param static_url_path: URL prefix for the static route. - :param template_folder: Path to a folder containing template files. + :param template_folder: Path or list of paths to a folder containing template files. for rendering. If this is set, a Jinja loader will be added. :param root_path: The path that static, template, and resource files are relative to. Typically not set, it is discovered based on @@ -77,7 +78,10 @@ class Scaffold: import_name: str, static_folder: str | os.PathLike[str] | None = None, static_url_path: str | None = None, - template_folder: str | os.PathLike[str] | None = None, + template_folder: ( + str | os.PathLike[str] | + t.Sequence[t.Union[str, "os.PathLike[str]"]] | None + ) = None, root_path: str | None = None, ): #: The name of the package or module that this object belongs @@ -276,10 +280,18 @@ class Scaffold: .. versionadded:: 0.5 """ - if self.template_folder is not None: - return FileSystemLoader(os.path.join(self.root_path, self.template_folder)) - else: + + if self.template_folder is None: return None + if isinstance(self.template_folder, str): + return FileSystemLoader( + os.path.join(self.root_path, self.template_folder) + ) + return FileSystemLoader([ + folder if isinstance(folder, os.PathLike) + else os.path.join(self.root_path, folder) + for folder in self.template_folder + ]) def _method_route( self,