]> git.ipfire.org Git - thirdparty/starlette.git/commitdiff
Set `url_for` global for custom jinja envs (#2230)
authorAlex Oleshkevich <alex.oleshkevich@gmail.com>
Fri, 25 Aug 2023 19:11:44 +0000 (21:11 +0200)
committerGitHub <noreply@github.com>
Fri, 25 Aug 2023 19:11:44 +0000 (19:11 +0000)
starlette/templating.py
tests/test_templates.py

index 071e8a4bb05c8b8bef988746bc411a4d66a56424..691cfda93b0b3b44613b63854c830ab34514b1fa 100644 (file)
@@ -109,11 +109,20 @@ class Jinja2Templates:
         elif env is not None:
             self.env = env
 
+        self._setup_env_defaults(self.env)
+
     def _create_env(
         self,
         directory: "typing.Union[str, PathLike[typing.AnyStr], typing.Sequence[typing.Union[str, PathLike[typing.AnyStr]]]]",  # noqa: E501
         **env_options: typing.Any,
     ) -> "jinja2.Environment":
+        loader = jinja2.FileSystemLoader(directory)
+        env_options.setdefault("loader", loader)
+        env_options.setdefault("autoescape", True)
+
+        return jinja2.Environment(**env_options)
+
+    def _setup_env_defaults(self, env: "jinja2.Environment") -> None:
         @pass_context
         def url_for(
             context: typing.Dict[str, typing.Any],
@@ -124,13 +133,7 @@ class Jinja2Templates:
             request: Request = context["request"]
             return request.url_for(name, **path_params)
 
-        loader = jinja2.FileSystemLoader(directory)
-        env_options.setdefault("loader", loader)
-        env_options.setdefault("autoescape", True)
-
-        env = jinja2.Environment(**env_options)
-        env.globals["url_for"] = url_for
-        return env
+        env.globals.setdefault("url_for", url_for)
 
     def get_template(self, name: str) -> "jinja2.Template":
         return self.env.get_template(name)
index 102f0bfcc33349204fa54476f80a9cfc2876858b..14d802e63c907b635ef19bbe63071ff2e173fb3b 100644 (file)
@@ -140,15 +140,25 @@ def test_templates_with_directory(tmpdir):
     assert template.render({}) == "Hello"
 
 
-def test_templates_with_environment(tmpdir):
+def test_templates_with_environment(tmpdir, test_client_factory):
     path = os.path.join(tmpdir, "index.html")
     with open(path, "w") as file:
-        file.write("Hello")
+        file.write("<html>Hello, <a href='{{ url_for('homepage') }}'>world</a></html>")
+
+    async def homepage(request):
+        return templates.TemplateResponse(request, "index.html")
 
     env = jinja2.Environment(loader=jinja2.FileSystemLoader(str(tmpdir)))
+    app = Starlette(
+        debug=True,
+        routes=[Route("/", endpoint=homepage)],
+    )
     templates = Jinja2Templates(env=env)
-    template = templates.get_template("index.html")
-    assert template.render({}) == "Hello"
+    client = test_client_factory(app)
+    response = client.get("/")
+    assert response.text == "<html>Hello, <a href='http://testserver/'>world</a></html>"
+    assert response.template.name == "index.html"
+    assert set(response.context.keys()) == {"request"}
 
 
 def test_templates_with_environment_options_emit_warning(tmpdir):