Skip to content

Commit

Permalink
add custom Template class with tojavascript filter (#1912)
Browse files Browse the repository at this point in the history
  • Loading branch information
Conengmo authored Apr 3, 2024
1 parent 3ec6ad6 commit a3034f9
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 0 deletions.
51 changes: 51 additions & 0 deletions folium/template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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():
out.append(f' "{camelize(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")
)


class Environment(jinja2.Environment):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.filters["tojavascript"] = tojavascript


class Template(jinja2.Template):
environment_class = Environment
68 changes: 68 additions & 0 deletions tests/test_template.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
from branca.element import Element

from folium import JsCode
from folium.template import Environment, Template, _to_escaped_json, tojavascript


def test_tojavascript_with_jscode():
js_code = JsCode("console.log('Hello, World!')")
assert tojavascript(js_code) == "console.log('Hello, World!')"


def test_tojavascript_with_element():
element = Element()
assert tojavascript(element) == element.get_name()


def test_tojavascript_with_dict():
dict_obj = {"key": "value"}
assert tojavascript(dict_obj) == '{\n "key": "value",\n}'


def test_tojavascript_with_list():
list_obj = ["value1", "value2"]
assert tojavascript(list_obj) == '[\n"value1",\n"value2",\n]'


def test_tojavascript_with_string():
assert tojavascript("Hello, World!") == _to_escaped_json("Hello, World!")


def test_tojavascript_with_combined_elements():
js_code = JsCode("console.log('Hello, World!')")
element = Element()
combined_dict = {
"key": "value",
"list": ["value1", "value2", element, js_code],
"nested_dict": {"nested_key": "nested_value"},
}
result = tojavascript(combined_dict)
expected_lines = [
"{",
' "key": "value",',
' "list": [',
'"value1",',
'"value2",',
element.get_name() + ",",
"console.log('Hello, World!'),",
"],",
' "nestedDict": {',
' "nestedKey": "nested_value",',
"},",
"}",
]
for result_line, expected_line in zip(result.splitlines(), expected_lines):
assert result_line == expected_line


def test_to_escaped_json():
assert _to_escaped_json("hi<>&'") == '"hi\\u003c\\u003e\\u0026\\u0027"'


def test_environment_filter():
env = Environment()
assert "tojavascript" in env.filters


def test_template_environment_class():
assert Template.environment_class == Environment

0 comments on commit a3034f9

Please sign in to comment.