From a10241a45c8aa69786ddbe6586ac58ec2b668f5f Mon Sep 17 00:00:00 2001
From: Hans Then <hans.then@gmail.com>
Date: Sun, 6 Apr 2025 22:16:02 +0200
Subject: [PATCH] Add parameters to JsCode

---
 folium/template.py     | 43 +----------------------------------------
 folium/utilities.py    | 44 +++++++++++++++++++++++++++++++++++++++---
 tests/test_template.py |  9 ++++++++-
 3 files changed, 50 insertions(+), 46 deletions(-)

diff --git a/folium/template.py b/folium/template.py
index 1d3cb6aa0d..29507ecc03 100644
--- a/folium/template.py
+++ b/folium/template.py
@@ -1,47 +1,6 @@
-import json
-from typing import Union
-
 import jinja2
-from branca.element import Element
-
-from folium.utilities import JsCode, TypeJsonValue, camelize
-
-
-def tojavascript(obj: Union[str, JsCode, dict, list, Element]) -> str:
-    if isinstance(obj, JsCode):
-        return obj.js_code
-    elif isinstance(obj, Element):
-        return obj.get_name()
-    elif isinstance(obj, dict):
-        out = ["{\n"]
-        for key, value in obj.items():
-            if isinstance(key, str):
-                out.append(f'  "{camelize(key)}": ')
-            else:
-                out.append(f"  {key}: ")
-            out.append(tojavascript(value))
-            out.append(",\n")
-        out.append("}")
-        return "".join(out)
-    elif isinstance(obj, list):
-        out = ["[\n"]
-        for value in obj:
-            out.append(tojavascript(value))
-            out.append(",\n")
-        out.append("]")
-        return "".join(out)
-    else:
-        return _to_escaped_json(obj)
-
 
-def _to_escaped_json(obj: TypeJsonValue) -> str:
-    return (
-        json.dumps(obj)
-        .replace("<", "\\u003c")
-        .replace(">", "\\u003e")
-        .replace("&", "\\u0026")
-        .replace("'", "\\u0027")
-    )
+from folium.utilities import tojavascript
 
 
 class Environment(jinja2.Environment):
diff --git a/folium/utilities.py b/folium/utilities.py
index 131492e453..9505c72c34 100644
--- a/folium/utilities.py
+++ b/folium/utilities.py
@@ -441,16 +441,54 @@ def get_and_assert_figure_root(obj: Element) -> Figure:
 class JsCode:
     """Wrapper around Javascript code."""
 
-    def __init__(self, js_code: Union[str, "JsCode"]):
+    def __init__(self, js_code: Union[str, "JsCode"], **kwargs):
+        args = {k: tojavascript(v) for k, v in kwargs.items()}
         if isinstance(js_code, JsCode):
-            self.js_code: str = js_code.js_code
+            self.js_code: str = js_code.js_code % args
         else:
-            self.js_code = js_code
+            self.js_code = js_code % args
 
     def __str__(self):
         return self.js_code
 
 
+def tojavascript(obj: Union[str, JsCode, dict, list, Element]) -> str:
+    if isinstance(obj, JsCode):
+        return obj.js_code
+    elif isinstance(obj, Element):
+        return obj.get_name()
+    elif isinstance(obj, dict):
+        out = ["{\n"]
+        for key, value in obj.items():
+            if isinstance(key, str):
+                out.append(f'  "{camelize(key)}": ')
+            else:
+                out.append(f"  {key}: ")
+            out.append(tojavascript(value))
+            out.append(",\n")
+        out.append("}")
+        return "".join(out)
+    elif isinstance(obj, list):
+        out = ["[\n"]
+        for value in obj:
+            out.append(tojavascript(value))
+            out.append(",\n")
+        out.append("]")
+        return "".join(out)
+    else:
+        return _to_escaped_json(obj)
+
+
+def _to_escaped_json(obj: TypeJsonValue) -> str:
+    return (
+        json.dumps(obj)
+        .replace("<", "\\u003c")
+        .replace(">", "\\u003e")
+        .replace("&", "\\u0026")
+        .replace("'", "\\u0027")
+    )
+
+
 def parse_font_size(value: Union[str, int, float]) -> str:
     """Parse a font size value, if number set as px"""
     if isinstance(value, (int, float)):
diff --git a/tests/test_template.py b/tests/test_template.py
index 09c57ce492..8a7ad3ff0d 100644
--- a/tests/test_template.py
+++ b/tests/test_template.py
@@ -1,7 +1,8 @@
 from branca.element import Element
 
 from folium import JsCode
-from folium.template import Environment, Template, _to_escaped_json, tojavascript
+from folium.template import Environment, Template
+from folium.utilities import _to_escaped_json, tojavascript
 
 
 def test_tojavascript_with_jscode():
@@ -72,3 +73,9 @@ def test_environment_filter():
 
 def test_template_environment_class():
     assert Template.environment_class == Environment
+
+
+def test_jscode_with_parameters():
+    element = Element()
+    js_code = JsCode("var element = %(element)s", element=element)
+    assert js_code.js_code == f"var element = {element.get_name()}"