diff --git a/folium/elements.py b/folium/elements.py
index 3d4498517..89a6332a9 100644
--- a/folium/elements.py
+++ b/folium/elements.py
@@ -1,8 +1,8 @@
from typing import List, Tuple
from branca.element import CssLink, Element, Figure, JavascriptLink, MacroElement
-from jinja2 import Template
+from folium.template import Template
from folium.utilities import JsCode
diff --git a/folium/features.py b/folium/features.py
index bca5c6d70..0a3ac1af7 100644
--- a/folium/features.py
+++ b/folium/features.py
@@ -14,17 +14,16 @@
from branca.colormap import ColorMap, LinearColormap, StepColormap
from branca.element import Element, Figure, Html, IFrame, JavascriptLink, MacroElement
from branca.utilities import color_brewer
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.folium import Map
from folium.map import FeatureGroup, Icon, Layer, Marker, Popup, Tooltip
+from folium.template import Template
from folium.utilities import (
TypeJsonValue,
TypeLine,
TypePathOptions,
_parse_size,
- camelize,
escape_backticks,
get_bounds,
get_obj_in_upper_tree,
@@ -32,7 +31,6 @@
javascript_identifier_path_to_array_notation,
none_max,
none_min,
- parse_options,
validate_locations,
)
from folium.vector_layers import Circle, CircleMarker, PolyLine, path_options
@@ -68,7 +66,7 @@ class RegularPolygonMarker(JSCSSMixin, Marker):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = new L.RegularPolygonMarker(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{% endmacro %}
"""
@@ -95,7 +93,7 @@ def __init__(
self._name = "RegularPolygonMarker"
self.options = path_options(line=False, radius=radius, **kwargs)
self.options.update(
- parse_options(
+ dict(
number_of_sides=number_of_sides,
rotation=rotation,
)
@@ -627,9 +625,7 @@ class GeoJson(Layer):
{%- if this.marker %}
pointToLayer: {{ this.get_name() }}_pointToLayer,
{%- endif %}
- {%- for key, value in this.options.items() %}
- {{ key }}: {{ value|tojson }},
- {%- endfor %}
+ ...{{this.options | tojavascript }}
});
function {{ this.get_name() }}_add (data) {
@@ -667,7 +663,7 @@ def __init__(
popup: Optional["GeoJsonPopup"] = None,
zoom_on_click: bool = False,
marker: Union[Circle, CircleMarker, Marker, None] = None,
- **kwargs: TypeJsonValue,
+ **kwargs: Any,
):
super().__init__(name=name, overlay=overlay, control=control, show=show)
self._name = "GeoJson"
@@ -692,7 +688,7 @@ def __init__(
self.popup_keep_highlighted = popup_keep_highlighted
self.marker = marker
- self.options = parse_options(**kwargs)
+ self.options = kwargs
self.data = self.process_data(data)
@@ -1267,7 +1263,7 @@ class GeoJsonTooltip(GeoJsonDetail):
{% macro script(this, kwargs) %}
{{ this._parent.get_name() }}.bindTooltip("""
+ GeoJsonDetail.base_template
- + """,{{ this.tooltip_options | tojson | safe }});
+ + """,{{ this.tooltip_options | tojavascript }});
{% endmacro %}
"""
)
@@ -1293,7 +1289,7 @@ def __init__(
)
self._name = "GeoJsonTooltip"
kwargs.update({"sticky": sticky, "class_name": class_name})
- self.tooltip_options = {camelize(key): kwargs[key] for key in kwargs.keys()}
+ self.tooltip_options = kwargs
class GeoJsonPopup(GeoJsonDetail):
@@ -1335,7 +1331,7 @@ class GeoJsonPopup(GeoJsonDetail):
{% macro script(this, kwargs) %}
{{ this._parent.get_name() }}.bindPopup("""
+ GeoJsonDetail.base_template
- + """,{{ this.popup_options | tojson | safe }});
+ + """,{{ this.popup_options | tojavascript }});
{% endmacro %}
"""
)
@@ -1360,7 +1356,7 @@ def __init__(
)
self._name = "GeoJsonPopup"
kwargs.update({"class_name": self.class_name})
- self.popup_options = {camelize(key): value for key, value in kwargs.items()}
+ self.popup_options = kwargs
class Choropleth(FeatureGroup):
@@ -1703,7 +1699,7 @@ class DivIcon(MacroElement):
_template = Template(
"""
{% macro script(this, kwargs) %}
- var {{ this.get_name() }} = L.divIcon({{ this.options|tojson }});
+ var {{ this.get_name() }} = L.divIcon({{ this.options|tojavascript }});
{{this._parent.get_name()}}.setIcon({{this.get_name()}});
{% endmacro %}
"""
@@ -1719,7 +1715,7 @@ def __init__(
):
super().__init__()
self._name = "DivIcon"
- self.options = parse_options(
+ self.options = dict(
html=html,
icon_size=icon_size,
icon_anchor=icon_anchor,
@@ -1880,7 +1876,7 @@ class CustomIcon(Icon):
_template = Template(
"""
{% macro script(this, kwargs) %}
- var {{ this.get_name() }} = L.icon({{ this.options|tojson }});
+ var {{ this.get_name() }} = L.icon({{ this.options|tojavascript }});
{{ this._parent.get_name() }}.setIcon({{ this.get_name() }});
{% endmacro %}
"""
@@ -1898,7 +1894,7 @@ def __init__(
):
super(Icon, self).__init__()
self._name = "CustomIcon"
- self.options = parse_options(
+ self.options = dict(
icon_url=image_to_url(icon_image),
icon_size=icon_size,
icon_anchor=icon_anchor,
diff --git a/folium/folium.py b/folium/folium.py
index 0b7b23887..d44c26364 100644
--- a/folium/folium.py
+++ b/folium/folium.py
@@ -8,17 +8,16 @@
from typing import Any, List, Optional, Sequence, Union
from branca.element import Element, Figure
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.map import Evented, FitBounds, Layer
from folium.raster_layers import TileLayer
+from folium.template import Template
from folium.utilities import (
TypeBounds,
TypeJsonValue,
_parse_size,
parse_font_size,
- parse_options,
temp_html_filepath,
validate_location,
)
@@ -204,9 +203,8 @@ class Map(JSCSSMixin, Evented):
{
center: {{ this.location|tojson }},
crs: L.CRS.{{ this.crs }},
- {%- for key, value in this.options.items() %}
- {{ key }}: {{ value|tojson }},
- {%- endfor %}
+ ...{{this.options|tojavascript}}
+
}
);
@@ -305,7 +303,7 @@ def __init__(
else:
self.zoom_control_position = False
- self.options = parse_options(
+ self.options = dict(
max_bounds=max_bounds_array,
zoom=zoom_start,
zoom_control=False if self.zoom_control_position else zoom_control,
diff --git a/folium/map.py b/folium/map.py
index 26a333ca1..b860956cc 100644
--- a/folium/map.py
+++ b/folium/map.py
@@ -5,17 +5,16 @@
import warnings
from collections import OrderedDict
-from typing import Dict, List, Optional, Sequence, Tuple, Type, Union
+from typing import List, Optional, Sequence, Union
from branca.element import Element, Figure, Html, MacroElement
-from jinja2 import Template
from folium.elements import ElementAddToElement, EventHandler
+from folium.template import Template
from folium.utilities import (
JsCode,
TypeBounds,
TypeJsonValue,
- camelize,
escape_backticks,
parse_options,
validate_location,
@@ -109,7 +108,7 @@ class FeatureGroup(Layer):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.featureGroup(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
@@ -126,7 +125,7 @@ def __init__(
super().__init__(name=name, overlay=overlay, control=control, show=show)
self._name = "FeatureGroup"
self.tile_name = name if name is not None else self.get_name()
- self.options = parse_options(**kwargs)
+ self.options = kwargs
class LayerControl(MacroElement):
@@ -180,7 +179,7 @@ class LayerControl(MacroElement):
let {{ this.get_name() }} = L.control.layers(
{{ this.get_name() }}_layers.base_layers,
{{ this.get_name() }}_layers.overlays,
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{this._parent.get_name()}});
{%- if this.draggable %}
@@ -201,7 +200,7 @@ def __init__(
):
super().__init__()
self._name = "LayerControl"
- self.options = parse_options(
+ self.options = dict(
position=position, collapsed=collapsed, autoZIndex=autoZIndex, **kwargs
)
self.draggable = draggable
@@ -263,7 +262,7 @@ class Icon(MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.AwesomeMarkers.icon(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{ this._parent.get_name() }}.setIcon({{ this.get_name() }});
{% endmacro %}
@@ -307,7 +306,7 @@ def __init__(
f"color argument of Icon should be one of: {self.color_options}.",
stacklevel=2,
)
- self.options = parse_options(
+ self.options = dict(
marker_color=color,
icon_color=icon_color,
icon=icon,
@@ -356,7 +355,7 @@ class Marker(MacroElement):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.marker(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{% endmacro %}
"""
@@ -374,7 +373,7 @@ def __init__(
super().__init__()
self._name = "Marker"
self.location = validate_location(location) if location is not None else None
- self.options = parse_options(
+ self.options = dict(
draggable=draggable or None, autoPan=draggable or None, **kwargs
)
if icon is not None:
@@ -424,7 +423,7 @@ class Popup(Element):
_template = Template(
"""
- var {{this.get_name()}} = L.popup({{ this.options|tojson }});
+ var {{this.get_name()}} = L.popup({{ this.options|tojavascript }});
{% for name, element in this.html._children.items() %}
{% if this.lazy %}
@@ -476,7 +475,7 @@ def __init__(
self.show = show
self.lazy = lazy
- self.options = parse_options(
+ self.options = dict(
max_width=max_width,
autoClose=False if show or sticky else None,
closeOnClick=False if sticky else None,
@@ -526,22 +525,11 @@ class Tooltip(MacroElement):
`
{{ this.text }}
`,
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
)
- valid_options: Dict[str, Tuple[Type, ...]] = {
- "pane": (str,),
- "offset": (tuple,),
- "direction": (str,),
- "permanent": (bool,),
- "sticky": (bool,),
- "interactive": (bool,),
- "opacity": (float, int),
- "attribution": (str,),
- "className": (str,),
- }
def __init__(
self,
@@ -556,7 +544,7 @@ def __init__(
self.text = str(text)
kwargs.update({"sticky": sticky})
- self.options = self.parse_options(kwargs)
+ self.options = kwargs
if style:
assert isinstance(
@@ -565,23 +553,6 @@ def __init__(
# noqa outside of type checking.
self.style = style
- def parse_options(
- self,
- kwargs: Dict[str, TypeJsonValue],
- ) -> Dict[str, TypeJsonValue]:
- """Validate the provided kwargs and return options as json string."""
- kwargs = {camelize(key): value for key, value in kwargs.items()}
- for key in kwargs.keys():
- assert (
- key in self.valid_options
- ), "The option {} is not in the available options: {}.".format(
- key, ", ".join(self.valid_options)
- )
- assert isinstance(
- kwargs[key], self.valid_options[key]
- ), f"The option {key} must be one of the following types: {self.valid_options[key]}."
- return kwargs
-
class FitBounds(MacroElement):
"""Fit the map to contain a bounding box with the
@@ -660,7 +631,7 @@ class FitOverlays(MacroElement):
}
});
if (bounds.isValid()) {
- {{ this._parent.get_name() }}.{{ this.method }}(bounds, {{ this.options|tojson }});
+ {{ this._parent.get_name() }}.{{ this.method }}(bounds, {{ this.options|tojavascript }});
}
}
{{ this._parent.get_name() }}.on('overlayadd', customFlyToBounds);
@@ -682,7 +653,7 @@ def __init__(
self._name = "FitOverlays"
self.method = "flyToBounds" if fly else "fitBounds"
self.fit_on_map_load = fit_on_map_load
- self.options = parse_options(padding=(padding, padding), max_zoom=max_zoom)
+ self.options = dict(padding=(padding, padding), max_zoom=max_zoom)
class CustomPane(MacroElement):
diff --git a/folium/plugins/antpath.py b/folium/plugins/antpath.py
index c578a3ec2..1711718d6 100644
--- a/folium/plugins/antpath.py
+++ b/folium/plugins/antpath.py
@@ -1,6 +1,5 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
+from folium.template import Template
from folium.vector_layers import BaseMultiLocation, path_options
@@ -31,7 +30,7 @@ class AntPath(JSCSSMixin, BaseMultiLocation):
{% macro script(this, kwargs) %}
{{ this.get_name() }} = L.polyline.antPath(
{{ this.locations|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{this._parent.get_name()}});
{% endmacro %}
"""
diff --git a/folium/plugins/beautify_icon.py b/folium/plugins/beautify_icon.py
index 99a8e1e6c..b43f301e6 100644
--- a/folium/plugins/beautify_icon.py
+++ b/folium/plugins/beautify_icon.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class BeautifyIcon(JSCSSMixin, MacroElement):
@@ -56,7 +55,7 @@ class BeautifyIcon(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = new L.BeautifyIcon.icon(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
)
{{ this._parent.get_name() }}.setIcon({{ this.get_name() }});
{% endmacro %}
@@ -95,12 +94,12 @@ def __init__(
inner_icon_style="",
spin=False,
number=None,
- **kwargs,
+ **kwargs
):
super().__init__()
self._name = "BeautifyIcon"
- self.options = parse_options(
+ self.options = dict(
icon=icon,
icon_shape=icon_shape,
border_width=border_width,
@@ -111,5 +110,5 @@ def __init__(
spin=spin,
isAlphaNumericIcon=number is not None,
text=number,
- **kwargs,
+ **kwargs
)
diff --git a/folium/plugins/boat_marker.py b/folium/plugins/boat_marker.py
index f53ba99cc..c88e46834 100644
--- a/folium/plugins/boat_marker.py
+++ b/folium/plugins/boat_marker.py
@@ -1,8 +1,6 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.map import Marker
-from folium.utilities import parse_options
+from folium.template import Template
class BoatMarker(JSCSSMixin, Marker):
@@ -30,7 +28,7 @@ class BoatMarker(JSCSSMixin, Marker):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.boatMarker(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{% if this.wind_heading is not none -%}
{{ this.get_name() }}.setHeadingWind(
@@ -67,4 +65,4 @@ def __init__(
self.heading = heading
self.wind_heading = wind_heading
self.wind_speed = wind_speed
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
diff --git a/folium/plugins/draw.py b/folium/plugins/draw.py
index 6e10987b4..b00311e08 100644
--- a/folium/plugins/draw.py
+++ b/folium/plugins/draw.py
@@ -1,7 +1,7 @@
from branca.element import Element, Figure, MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
+from folium.template import Template
class Draw(JSCSSMixin, MacroElement):
diff --git a/folium/plugins/dual_map.py b/folium/plugins/dual_map.py
index 2e1000f4a..ffd760f64 100644
--- a/folium/plugins/dual_map.py
+++ b/folium/plugins/dual_map.py
@@ -1,9 +1,9 @@
from branca.element import Figure, MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.folium import Map
from folium.map import LayerControl
+from folium.template import Template
from folium.utilities import deep_copy
diff --git a/folium/plugins/encoded.py b/folium/plugins/encoded.py
index 14f0adaa3..cc13b41c2 100644
--- a/folium/plugins/encoded.py
+++ b/folium/plugins/encoded.py
@@ -1,9 +1,8 @@
from abc import ABC, abstractmethod
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.features import MacroElement
+from folium.template import Template
from folium.vector_layers import path_options
@@ -28,7 +27,7 @@ class _BaseFromEncoded(JSCSSMixin, MacroElement, ABC):
var {{ this.get_name() }} = L.{{ this._encoding_type }}.fromEncoded(
{{ this.encoded|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{% endmacro %}
diff --git a/folium/plugins/fast_marker_cluster.py b/folium/plugins/fast_marker_cluster.py
index 0a55ab37c..cf889cedd 100644
--- a/folium/plugins/fast_marker_cluster.py
+++ b/folium/plugins/fast_marker_cluster.py
@@ -1,6 +1,5 @@
-from jinja2 import Template
-
from folium.plugins.marker_cluster import MarkerCluster
+from folium.template import Template
from folium.utilities import if_pandas_df_convert_to_numpy, validate_location
@@ -50,7 +49,7 @@ class FastMarkerCluster(MarkerCluster):
{{ this.callback }}
var data = {{ this.data|tojson }};
- var cluster = L.markerClusterGroup({{ this.options|tojson }});
+ var cluster = L.markerClusterGroup({{ this.options|tojavascript }});
{%- if this.icon_create_function is not none %}
cluster.options.iconCreateFunction =
{{ this.icon_create_function.strip() }};
diff --git a/folium/plugins/feature_group_sub_group.py b/folium/plugins/feature_group_sub_group.py
index ae07e0320..81245ff3f 100644
--- a/folium/plugins/feature_group_sub_group.py
+++ b/folium/plugins/feature_group_sub_group.py
@@ -1,7 +1,6 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.map import Layer
+from folium.template import Template
class FeatureGroupSubGroup(JSCSSMixin, Layer):
diff --git a/folium/plugins/float_image.py b/folium/plugins/float_image.py
index 2f171d21c..d0f5ad5ea 100644
--- a/folium/plugins/float_image.py
+++ b/folium/plugins/float_image.py
@@ -1,5 +1,6 @@
from branca.element import MacroElement
-from jinja2 import Template
+
+from folium.template import Template
class FloatImage(MacroElement):
diff --git a/folium/plugins/fullscreen.py b/folium/plugins/fullscreen.py
index 84ab7e730..7ec969d54 100644
--- a/folium/plugins/fullscreen.py
+++ b/folium/plugins/fullscreen.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class Fullscreen(JSCSSMixin, MacroElement):
@@ -31,7 +30,7 @@ class Fullscreen(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
L.control.fullscreen(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{this._parent.get_name()}});
{% endmacro %}
"""
@@ -60,7 +59,7 @@ def __init__(
):
super().__init__()
self._name = "Fullscreen"
- self.options = parse_options(
+ self.options = dict(
position=position,
title=title,
title_cancel=title_cancel,
diff --git a/folium/plugins/geocoder.py b/folium/plugins/geocoder.py
index 3d267a05d..7866dd58e 100644
--- a/folium/plugins/geocoder.py
+++ b/folium/plugins/geocoder.py
@@ -1,10 +1,9 @@
from typing import Optional
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class Geocoder(JSCSSMixin, MacroElement):
@@ -36,7 +35,7 @@ class Geocoder(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
- var geocoderOpts_{{ this.get_name() }} = {{ this.options|tojson }};
+ var geocoderOpts_{{ this.get_name() }} = {{ this.options|tojavascript }};
// note: geocoder name should start with lowercase
var geocoderName_{{ this.get_name() }} = geocoderOpts_{{ this.get_name() }}["provider"];
@@ -82,7 +81,7 @@ def __init__(
):
super().__init__()
self._name = "Geocoder"
- self.options = parse_options(
+ self.options = dict(
collapsed=collapsed,
position=position,
default_mark_geocode=add_marker,
diff --git a/folium/plugins/groupedlayercontrol.py b/folium/plugins/groupedlayercontrol.py
index 6745f8aa4..5d7391b90 100644
--- a/folium/plugins/groupedlayercontrol.py
+++ b/folium/plugins/groupedlayercontrol.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class GroupedLayerControl(JSCSSMixin, MacroElement):
@@ -55,7 +54,7 @@ class GroupedLayerControl(JSCSSMixin, MacroElement):
},
{%- endfor %}
},
- {{ this.options|tojson }},
+ {{ this.options|tojavascript }},
).addTo({{this._parent.get_name()}});
{%- for val in this.layers_untoggle %}
@@ -69,7 +68,7 @@ class GroupedLayerControl(JSCSSMixin, MacroElement):
def __init__(self, groups, exclusive_groups=True, **kwargs):
super().__init__()
self._name = "GroupedLayerControl"
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
if exclusive_groups:
self.options["exclusiveGroups"] = list(groups.keys())
self.layers_untoggle = set()
diff --git a/folium/plugins/heat_map.py b/folium/plugins/heat_map.py
index cc6a981d5..b49e98850 100644
--- a/folium/plugins/heat_map.py
+++ b/folium/plugins/heat_map.py
@@ -1,15 +1,14 @@
import warnings
import numpy as np
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.map import Layer
+from folium.template import Template
from folium.utilities import (
if_pandas_df_convert_to_numpy,
none_max,
none_min,
- parse_options,
validate_location,
)
@@ -49,7 +48,7 @@ class HeatMap(JSCSSMixin, Layer):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.heatLayer(
{{ this.data|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
@@ -90,7 +89,7 @@ def __init__(
"The largest intensity is calculated automatically.",
stacklevel=2,
)
- self.options = parse_options(
+ self.options = dict(
min_opacity=min_opacity,
max_zoom=max_zoom,
radius=radius,
diff --git a/folium/plugins/heat_map_withtime.py b/folium/plugins/heat_map_withtime.py
index 11f8ee9b7..162313354 100644
--- a/folium/plugins/heat_map_withtime.py
+++ b/folium/plugins/heat_map_withtime.py
@@ -1,8 +1,8 @@
from branca.element import Element, Figure
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.map import Layer
+from folium.template import Template
from folium.utilities import none_max, none_min
diff --git a/folium/plugins/locate_control.py b/folium/plugins/locate_control.py
index fb1c825d1..bf495d4fd 100644
--- a/folium/plugins/locate_control.py
+++ b/folium/plugins/locate_control.py
@@ -4,10 +4,9 @@
"""
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class LocateControl(JSCSSMixin, MacroElement):
@@ -74,4 +73,4 @@ def __init__(self, auto_start=False, **kwargs):
super().__init__()
self._name = "LocateControl"
self.auto_start = auto_start
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
diff --git a/folium/plugins/marker_cluster.py b/folium/plugins/marker_cluster.py
index b6460e088..0af5f154e 100644
--- a/folium/plugins/marker_cluster.py
+++ b/folium/plugins/marker_cluster.py
@@ -1,8 +1,7 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.map import Layer, Marker
-from folium.utilities import parse_options, validate_locations
+from folium.template import Template
+from folium.utilities import validate_locations
class MarkerCluster(JSCSSMixin, Layer):
@@ -48,7 +47,7 @@ class MarkerCluster(JSCSSMixin, Layer):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.markerClusterGroup(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{%- if this.icon_create_function is not none %}
{{ this.get_name() }}.options.iconCreateFunction =
@@ -103,7 +102,7 @@ def __init__(
)
)
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
if icon_create_function is not None:
assert isinstance(icon_create_function, str)
self.icon_create_function = icon_create_function
diff --git a/folium/plugins/measure_control.py b/folium/plugins/measure_control.py
index 4b543dc2f..6371a3226 100644
--- a/folium/plugins/measure_control.py
+++ b/folium/plugins/measure_control.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class MeasureControl(JSCSSMixin, MacroElement):
@@ -25,7 +24,7 @@ class MeasureControl(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = new L.Control.Measure(
- {{ this.options|tojson }});
+ {{ this.options|tojavascript }});
{{this._parent.get_name()}}.addControl({{this.get_name()}});
// Workaround for using this plugin with Leaflet>=1.8.0
@@ -73,7 +72,7 @@ def __init__(
super().__init__()
self._name = "MeasureControl"
- self.options = parse_options(
+ self.options = dict(
position=position,
primary_length_unit=primary_length_unit,
secondary_length_unit=secondary_length_unit,
diff --git a/folium/plugins/minimap.py b/folium/plugins/minimap.py
index 999cabd25..9e482ea5a 100644
--- a/folium/plugins/minimap.py
+++ b/folium/plugins/minimap.py
@@ -1,9 +1,8 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.raster_layers import TileLayer
-from folium.utilities import parse_options
+from folium.template import Template
class MiniMap(JSCSSMixin, MacroElement):
@@ -68,7 +67,7 @@ class MiniMap(JSCSSMixin, MacroElement):
);
var {{ this.get_name() }} = new L.Control.MiniMap(
{{ this.tile_layer.get_name() }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{ this._parent.get_name() }}.addControl({{ this.get_name() }});
{% endmacro %}
@@ -115,7 +114,7 @@ def __init__(
else:
self.tile_layer = TileLayer(tile_layer)
- self.options = parse_options(
+ self.options = dict(
position=position,
width=width,
height=height,
diff --git a/folium/plugins/mouse_position.py b/folium/plugins/mouse_position.py
index 2c1b1b6f3..2d6e2d89e 100644
--- a/folium/plugins/mouse_position.py
+++ b/folium/plugins/mouse_position.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class MousePosition(JSCSSMixin, MacroElement):
@@ -49,7 +48,7 @@ class MousePosition(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = new L.Control.MousePosition(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{ this.get_name() }}.options["latFormatter"] =
{{ this.lat_formatter }};
@@ -88,7 +87,7 @@ def __init__(
super().__init__()
self._name = "MousePosition"
- self.options = parse_options(
+ self.options = dict(
position=position,
separator=separator,
empty_string=empty_string,
diff --git a/folium/plugins/pattern.py b/folium/plugins/pattern.py
index 2f90d32df..e9b0b853a 100644
--- a/folium/plugins/pattern.py
+++ b/folium/plugins/pattern.py
@@ -1,9 +1,9 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.folium import Map
-from folium.utilities import get_obj_in_upper_tree, parse_options
+from folium.template import Template
+from folium.utilities import get_obj_in_upper_tree
class StripePattern(JSCSSMixin, MacroElement):
@@ -35,7 +35,7 @@ class StripePattern(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = new L.StripePattern(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{ this.get_name() }}.addTo({{ this.parent_map.get_name() }});
{% endmacro %}
@@ -59,7 +59,7 @@ def __init__(
):
super().__init__()
self._name = "StripePattern"
- self.options = parse_options(
+ self.options = dict(
angle=angle,
weight=weight,
space_weight=space_weight,
@@ -107,10 +107,10 @@ class CirclePattern(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
var {{ this.get_name() }}_shape = new L.PatternCircle(
- {{ this.options_pattern_circle|tojson }}
+ {{ this.options_pattern_circle|tojavascript }}
);
var {{ this.get_name() }} = new L.Pattern(
- {{ this.options_pattern|tojson }}
+ {{ this.options_pattern|tojavascript }}
);
{{ this.get_name() }}.addShape({{ this.get_name() }}_shape);
{{ this.get_name() }}.addTo({{ this.parent_map }});
@@ -135,7 +135,7 @@ def __init__(
):
super().__init__()
self._name = "CirclePattern"
- self.options_pattern_circle = parse_options(
+ self.options_pattern_circle = dict(
x=radius + 2 * weight,
y=radius + 2 * weight,
weight=weight,
@@ -146,7 +146,7 @@ def __init__(
fill_opacity=fill_opacity,
fill=True,
)
- self.options_pattern = parse_options(
+ self.options_pattern = dict(
width=width,
height=height,
)
diff --git a/folium/plugins/polyline_text_path.py b/folium/plugins/polyline_text_path.py
index 660d15909..dbd97d093 100644
--- a/folium/plugins/polyline_text_path.py
+++ b/folium/plugins/polyline_text_path.py
@@ -1,8 +1,6 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.features import MacroElement
-from folium.utilities import parse_options
+from folium.template import Template
class PolyLineTextPath(JSCSSMixin, MacroElement):
@@ -40,7 +38,7 @@ class PolyLineTextPath(JSCSSMixin, MacroElement):
{% macro script(this, kwargs) %}
{{ this.polyline.get_name() }}.setText(
{{ this.text|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
@@ -69,7 +67,7 @@ def __init__(
self._name = "PolyLineTextPath"
self.polyline = polyline
self.text = text
- self.options = parse_options(
+ self.options = dict(
repeat=repeat,
center=center,
below=below,
diff --git a/folium/plugins/realtime.py b/folium/plugins/realtime.py
index 7944e3fe1..56f8c64c7 100644
--- a/folium/plugins/realtime.py
+++ b/folium/plugins/realtime.py
@@ -1,11 +1,10 @@
from typing import Optional, Union
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.features import GeoJson
from folium.map import FeatureGroup
-from folium.utilities import JsCode, camelize, parse_options
+from folium.template import Template
+from folium.utilities import JsCode
class Realtime(JSCSSMixin, FeatureGroup):
@@ -70,26 +69,17 @@ class Realtime(JSCSSMixin, FeatureGroup):
_template = Template(
"""
{% macro script(this, kwargs) %}
- var {{ this.get_name() }}_options = {{ this.options|tojson }};
- {% for key, value in this.functions.items() %}
- {{ this.get_name() }}_options["{{key}}"] = {{ value }};
- {% endfor %}
-
- {% if this.container -%}
- {{ this.get_name() }}_options["container"]
- = {{ this.container.get_name() }};
- {% endif -%}
-
var {{ this.get_name() }} = L.realtime(
{% if this.src is string or this.src is mapping -%}
{{ this.src|tojson }},
{% else -%}
{{ this.src.js_code }},
{% endif -%}
- {{ this.get_name() }}_options
+ {{ this.options | tojavascript }}
);
{{ this._parent.get_name() }}.addLayer(
- {{ this.get_name() }}._container);
+ {{ this.get_name() }}._container
+ );
{% endmacro %}
"""
)
@@ -115,7 +105,6 @@ def __init__(
super().__init__()
self._name = "Realtime"
self.src = source
- self.container = container
kwargs["start"] = start
kwargs["interval"] = interval
@@ -124,12 +113,6 @@ def __init__(
if update_feature is not None:
kwargs["update_feature"] = JsCode(update_feature)
kwargs["remove_missing"] = remove_missing
+ kwargs["container"] = container
- # extract JsCode objects
- self.functions = {}
- for key, value in list(kwargs.items()):
- if isinstance(value, JsCode):
- self.functions[camelize(key)] = value.js_code
- kwargs.pop(key)
-
- self.options = parse_options(**kwargs)
+ self.options = kwargs
diff --git a/folium/plugins/scroll_zoom_toggler.py b/folium/plugins/scroll_zoom_toggler.py
index a8061b5a8..f932e1abb 100644
--- a/folium/plugins/scroll_zoom_toggler.py
+++ b/folium/plugins/scroll_zoom_toggler.py
@@ -1,5 +1,6 @@
from branca.element import MacroElement
-from jinja2 import Template
+
+from folium.template import Template
class ScrollZoomToggler(MacroElement):
diff --git a/folium/plugins/search.py b/folium/plugins/search.py
index b477456b5..8ddbf6f3c 100644
--- a/folium/plugins/search.py
+++ b/folium/plugins/search.py
@@ -1,11 +1,10 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium import Map
from folium.elements import JSCSSMixin
from folium.features import FeatureGroup, GeoJson, TopoJson
from folium.plugins import MarkerCluster
-from folium.utilities import parse_options
+from folium.template import Template
class Search(JSCSSMixin, MacroElement):
@@ -69,7 +68,7 @@ class Search(JSCSSMixin, MacroElement):
return feature.properties.style
})
{% if this.options %}
- e.layer.setStyle({{ this.options|tojson }});
+ e.layer.setStyle({{ this.options|tojavascript }});
{% endif %}
if(e.layer._popup)
e.layer.openPopup();
@@ -122,7 +121,7 @@ def __init__(
self.position = position
self.placeholder = placeholder
self.collapsed = collapsed
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
def test_params(self, keys):
if keys is not None and self.search_label is not None:
diff --git a/folium/plugins/semicircle.py b/folium/plugins/semicircle.py
index 6e85b1b1b..1c2ea83c8 100644
--- a/folium/plugins/semicircle.py
+++ b/folium/plugins/semicircle.py
@@ -1,8 +1,6 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.map import Marker
-from folium.utilities import parse_options
+from folium.template import Template
from folium.vector_layers import path_options
@@ -41,7 +39,7 @@ class SemiCircle(JSCSSMixin, Marker):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.semiCircle(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
)
{%- if this.direction %}
.setDirection({{ this.direction[0] }}, {{ this.direction[1] }})
@@ -77,7 +75,7 @@ def __init__(
)
self.options = path_options(line=False, radius=radius, **kwargs)
self.options.update(
- parse_options(
+ dict(
start_angle=start_angle,
stop_angle=stop_angle,
)
diff --git a/folium/plugins/side_by_side.py b/folium/plugins/side_by_side.py
index 9df98973c..e62ce3aa5 100644
--- a/folium/plugins/side_by_side.py
+++ b/folium/plugins/side_by_side.py
@@ -1,7 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
+from folium.template import Template
class SideBySideLayers(JSCSSMixin, MacroElement):
diff --git a/folium/plugins/tag_filter_button.py b/folium/plugins/tag_filter_button.py
index 4fe342a89..5f8a0e1ce 100644
--- a/folium/plugins/tag_filter_button.py
+++ b/folium/plugins/tag_filter_button.py
@@ -1,8 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
-from folium.utilities import parse_options
+from folium.template import Template
class TagFilterButton(JSCSSMixin, MacroElement):
@@ -44,7 +43,7 @@ class TagFilterButton(JSCSSMixin, MacroElement):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.control.tagFilterButton(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{% endmacro %}
"""
@@ -86,7 +85,7 @@ def __init__(
):
super().__init__()
self._name = "TagFilterButton"
- self.options = parse_options(
+ self.options = dict(
data=data,
icon=icon,
clear_text=clear_text,
diff --git a/folium/plugins/terminator.py b/folium/plugins/terminator.py
index a345ebe10..4be68ca5f 100644
--- a/folium/plugins/terminator.py
+++ b/folium/plugins/terminator.py
@@ -1,7 +1,7 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
+from folium.template import Template
class Terminator(JSCSSMixin, MacroElement):
diff --git a/folium/plugins/time_slider_choropleth.py b/folium/plugins/time_slider_choropleth.py
index ce1367d31..29ff6549d 100644
--- a/folium/plugins/time_slider_choropleth.py
+++ b/folium/plugins/time_slider_choropleth.py
@@ -1,8 +1,7 @@
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.features import GeoJson
from folium.map import Layer
+from folium.template import Template
class TimeSliderChoropleth(JSCSSMixin, Layer):
diff --git a/folium/plugins/timeline.py b/folium/plugins/timeline.py
index 77ba81cb2..cefe5d0d7 100644
--- a/folium/plugins/timeline.py
+++ b/folium/plugins/timeline.py
@@ -1,12 +1,12 @@
from typing import List, Optional, TextIO, Union
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.features import GeoJson
from folium.folium import Map
-from folium.utilities import JsCode, camelize, get_bounds, parse_options
+from folium.template import Template
+from folium.utilities import JsCode, get_bounds
class Timeline(GeoJson):
@@ -83,10 +83,7 @@ class Timeline(GeoJson):
_template = Template(
"""
{% macro script(this, kwargs) %}
- var {{ this.get_name() }}_options = {{ this.options|tojson }};
- {% for key, value in this.functions.items() %}
- {{ this.get_name() }}_options["{{key}}"] = {{ value }};
- {% endfor %}
+ var {{ this.get_name() }}_options = {{ this.options|tojavascript }};
var {{ this.get_name() }} = L.timeline(
{{ this.data|tojson }},
@@ -120,14 +117,7 @@ def __init__(
if get_interval is not None:
kwargs["get_interval"] = get_interval
- # extract JsCode objects
- self.functions = {}
- for key, value in list(kwargs.items()):
- if isinstance(value, JsCode):
- self.functions[camelize(key)] = value.js_code
- kwargs.pop(key)
-
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
def _get_self_bounds(self):
"""
@@ -191,13 +181,8 @@ class TimelineSlider(JSCSSMixin, MacroElement):
{% endmacro %}
{% macro script(this, kwargs) %}
- var {{ this.get_name() }}_options = {{ this.options|tojson }};
- {% for key, value in this.functions.items() %}
- {{ this.get_name() }}_options["{{key}}"] = {{ value }};
- {% endfor %}
-
var {{ this.get_name() }} = L.timelineSliderControl(
- {{ this.get_name() }}_options
+ {{ this.options|tojavascript }};
);
{{ this.get_name() }}.addTo({{ this._parent.get_name() }});
@@ -257,15 +242,8 @@ def __init__(
"""
)
- # extract JsCode objects
- self.functions = {}
- for key, value in list(kwargs.items()):
- if isinstance(value, JsCode):
- self.functions[camelize(key)] = value.js_code
- kwargs.pop(key)
-
self.timelines: List[Timeline] = []
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
def add_timelines(self, *args):
"""Add timelines to the control"""
diff --git a/folium/plugins/timestamped_geo_json.py b/folium/plugins/timestamped_geo_json.py
index 3fe66ac04..1062f7367 100644
--- a/folium/plugins/timestamped_geo_json.py
+++ b/folium/plugins/timestamped_geo_json.py
@@ -1,11 +1,11 @@
import json
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.folium import Map
-from folium.utilities import get_bounds, parse_options
+from folium.template import Template
+from folium.utilities import get_bounds
class TimestampedGeoJson(JSCSSMixin, MacroElement):
@@ -94,7 +94,7 @@ class TimestampedGeoJson(JSCSSMixin, MacroElement):
}
);
var timeDimensionControl = new L.Control.TimeDimensionCustom(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{this._parent.get_name()}}.addControl(this.timeDimensionControl);
@@ -211,7 +211,7 @@ def __init__(
self.date_options = date_options
self.duration = "undefined" if duration is None else '"' + duration + '"'
- self.options = parse_options(
+ self.options = dict(
position="bottomleft",
min_speed=min_speed,
max_speed=max_speed,
diff --git a/folium/plugins/timestamped_wmstilelayer.py b/folium/plugins/timestamped_wmstilelayer.py
index 6f1147638..53288f755 100644
--- a/folium/plugins/timestamped_wmstilelayer.py
+++ b/folium/plugins/timestamped_wmstilelayer.py
@@ -1,9 +1,8 @@
from branca.element import MacroElement
-from jinja2 import Template
from folium.elements import JSCSSMixin
from folium.raster_layers import WmsTileLayer
-from folium.utilities import parse_options
+from folium.template import Template
class TimestampedWmsTileLayers(JSCSSMixin, MacroElement):
@@ -66,11 +65,11 @@ class TimestampedWmsTileLayers(JSCSSMixin, MacroElement):
"""
{% macro script(this, kwargs) %}
{{ this._parent.get_name() }}.timeDimension = L.timeDimension(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{ this._parent.get_name() }}.timeDimensionControl =
L.control.timeDimension(
- {{ this.options_control|tojson }}
+ {{ this.options_control|tojavascript }}
);
{{ this._parent.get_name() }}.addControl(
{{ this._parent.get_name() }}.timeDimensionControl
@@ -129,11 +128,11 @@ def __init__(
):
super().__init__()
self._name = "TimestampedWmsTileLayers"
- self.options = parse_options(
+ self.options = dict(
period=period,
time_interval=time_interval,
)
- self.options_control = parse_options(
+ self.options_control = dict(
position="bottomleft",
auto_play=auto_play,
player_options={
diff --git a/folium/plugins/treelayercontrol.py b/folium/plugins/treelayercontrol.py
index 4e828f2d7..5b3028e12 100644
--- a/folium/plugins/treelayercontrol.py
+++ b/folium/plugins/treelayercontrol.py
@@ -4,7 +4,6 @@
from folium.elements import JSCSSMixin
from folium.template import Template
-from folium.utilities import parse_options
class TreeLayerControl(JSCSSMixin, MacroElement):
@@ -128,7 +127,7 @@ class TreeLayerControl(JSCSSMixin, MacroElement):
L.control.layers.tree(
{{this.base_tree|tojavascript}},
{{this.overlay_tree|tojavascript}},
- {{this.options|tojson}}
+ {{this.options|tojavascript}}
).addTo({{this._parent.get_name()}});
{% endmacro %}
"""
@@ -158,6 +157,6 @@ def __init__(
kwargs["collapse_all"] = collapse_all
kwargs["expand_all"] = expand_all
kwargs["label_is_selector"] = label_is_selector
- self.options = parse_options(**kwargs)
+ self.options = dict(**kwargs)
self.base_tree = base_tree
self.overlay_tree = overlay_tree
diff --git a/folium/plugins/vectorgrid_protobuf.py b/folium/plugins/vectorgrid_protobuf.py
index 9a37cac7f..356188bd3 100644
--- a/folium/plugins/vectorgrid_protobuf.py
+++ b/folium/plugins/vectorgrid_protobuf.py
@@ -1,9 +1,8 @@
from typing import Optional, Union
-from jinja2 import Template
-
from folium.elements import JSCSSMixin
from folium.map import Layer
+from folium.template import Template
class VectorGridProtobuf(JSCSSMixin, Layer):
@@ -110,7 +109,7 @@ class VectorGridProtobuf(JSCSSMixin, Layer):
var {{ this.get_name() }} = L.vectorGrid.protobuf(
'{{ this.url }}',
{%- if this.options is defined %}
- {{ this.options if this.options is string else this.options|tojson }}
+ {{ this.options if this.options is string else this.options|tojavascript }}
{%- endif %}
);
{%- endmacro %}
diff --git a/folium/raster_layers.py b/folium/raster_layers.py
index 032cb14f5..b4eec8ab9 100644
--- a/folium/raster_layers.py
+++ b/folium/raster_layers.py
@@ -7,9 +7,9 @@
import xyzservices
from branca.element import Element, Figure
-from jinja2 import Template
from folium.map import Layer
+from folium.template import Template
from folium.utilities import (
TypeBounds,
TypeJsonValue,
@@ -82,7 +82,8 @@ class TileLayer(Layer):
{% macro script(this, kwargs) %}
var {{ this.get_name() }} = L.tileLayer(
{{ this.tiles|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
+
);
{% endmacro %}
"""
@@ -139,7 +140,7 @@ def __init__(
if not attr:
raise ValueError("Custom tiles must have an attribution.")
- self.options = parse_options(
+ self.options = dict(
min_zoom=min_zoom or 0,
max_zoom=max_zoom or 18,
max_native_zoom=max_native_zoom,
@@ -228,8 +229,8 @@ def __init__(
attribution=attr,
**kwargs,
)
+ # special parameter that shouldn't be camelized
if cql_filter:
- # special parameter that shouldn't be camelized
self.options["cql_filter"] = cql_filter
@@ -286,7 +287,7 @@ class ImageOverlay(Layer):
var {{ this.get_name() }} = L.imageOverlay(
{{ this.url|tojson }},
{{ this.bounds|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
@@ -309,7 +310,7 @@ def __init__(
super().__init__(name=name, overlay=overlay, control=control, show=show)
self._name = "ImageOverlay"
self.bounds = bounds
- self.options = parse_options(**kwargs)
+ self.options = kwargs
self.pixelated = pixelated
if mercator_project:
image = mercator_transform(
@@ -385,7 +386,7 @@ class VideoOverlay(Layer):
var {{ this.get_name() }} = L.videoOverlay(
{{ this.video_url|tojson }},
{{ this.bounds|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{% endmacro %}
"""
@@ -408,7 +409,7 @@ def __init__(
self.video_url = video_url
self.bounds = bounds
- self.options = parse_options(autoplay=autoplay, loop=loop, **kwargs)
+ self.options = dict(autoplay=autoplay, loop=loop, **kwargs)
def _get_self_bounds(self) -> TypeBounds:
"""
diff --git a/folium/vector_layers.py b/folium/vector_layers.py
index 9f535467a..850c88949 100644
--- a/folium/vector_layers.py
+++ b/folium/vector_layers.py
@@ -6,9 +6,9 @@
from typing import List, Optional, Sequence, Union
from branca.element import MacroElement
-from jinja2 import Template
from folium.map import Marker, Popup, Tooltip
+from folium.template import Template
from folium.utilities import (
TypeLine,
TypeMultiLine,
@@ -230,7 +230,7 @@ def __init__(
locations: TypeMultiLine,
popup: Union[Popup, str, None] = None,
tooltip: Union[Tooltip, str, None] = None,
- **kwargs: TypePathOptions
+ **kwargs: TypePathOptions,
):
super().__init__(locations, popup=popup, tooltip=tooltip)
self._name = "Polygon"
@@ -272,7 +272,7 @@ def __init__(
bounds: TypeLine,
popup: Union[Popup, str, None] = None,
tooltip: Union[Tooltip, str, None] = None,
- **kwargs: TypePathOptions
+ **kwargs: TypePathOptions,
):
super().__init__()
self._name = "rectangle"
@@ -333,7 +333,7 @@ def __init__(
radius: float = 50,
popup: Union[Popup, str, None] = None,
tooltip: Union[Tooltip, str, None] = None,
- **kwargs: TypePathOptions
+ **kwargs: TypePathOptions,
):
super().__init__(location, popup=popup, tooltip=tooltip)
self._name = "circle"
@@ -379,7 +379,7 @@ def __init__(
radius: float = 10,
popup: Union[Popup, str, None] = None,
tooltip: Union[Tooltip, str, None] = None,
- **kwargs: TypePathOptions
+ **kwargs: TypePathOptions,
):
super().__init__(location, popup=popup, tooltip=tooltip)
self._name = "CircleMarker"
diff --git a/tests/plugins/test_antpath.py b/tests/plugins/test_antpath.py
index 45c881f90..4dba6ebfc 100644
--- a/tests/plugins/test_antpath.py
+++ b/tests/plugins/test_antpath.py
@@ -3,10 +3,9 @@
-------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -46,7 +45,7 @@ def test_antpath():
"""
{{this.get_name()}} = L.polyline.antPath(
{{ this.locations|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
)
.addTo({{this._parent.get_name()}});
"""
diff --git a/tests/plugins/test_beautify_icon.py b/tests/plugins/test_beautify_icon.py
index d07f4b0ef..3bfdcf9e3 100644
--- a/tests/plugins/test_beautify_icon.py
+++ b/tests/plugins/test_beautify_icon.py
@@ -4,10 +4,9 @@
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -46,7 +45,7 @@ def test_beautify_icon():
# We verify that the Beautiful Icons are rendered correctly.
tmpl = Template(
"""
- var {{this.get_name()}} = new L.BeautifyIcon.icon({{ this.options|tojson }})
+ var {{this.get_name()}} = new L.BeautifyIcon.icon({{ this.options|tojavascript }})
{{this._parent.get_name()}}.setIcon({{this.get_name()}});
"""
) # noqa
diff --git a/tests/plugins/test_boat_marker.py b/tests/plugins/test_boat_marker.py
index 8fd880d3d..9c70eff3c 100644
--- a/tests/plugins/test_boat_marker.py
+++ b/tests/plugins/test_boat_marker.py
@@ -4,10 +4,9 @@
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -35,7 +34,7 @@ def test_boat_marker():
"""
var {{ this.get_name() }} = L.boatMarker(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{{ this.get_name() }}.setHeadingWind(
{{ this.heading }},
@@ -64,7 +63,7 @@ def test_boat_marker_with_no_wind_speed_or_heading():
"""
var {{ this.get_name() }} = L.boatMarker(
{{ this.location|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{ this._parent.get_name() }});
{{ this.get_name() }}.setHeading({{ this.heading }});
"""
diff --git a/tests/plugins/test_dual_map.py b/tests/plugins/test_dual_map.py
index bf15d66c8..6d1fe5c9e 100644
--- a/tests/plugins/test_dual_map.py
+++ b/tests/plugins/test_dual_map.py
@@ -3,10 +3,9 @@
------------
"""
-from jinja2 import Template
-
import folium
import folium.plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_encoded.py b/tests/plugins/test_encoded.py
index 3377548a0..1c885a0d0 100644
--- a/tests/plugins/test_encoded.py
+++ b/tests/plugins/test_encoded.py
@@ -1,9 +1,8 @@
"""Test PolyLineFromEncoded Plugin."""
-from jinja2 import Template
-
from folium import Map
from folium.plugins import PolygonFromEncoded, PolyLineFromEncoded
+from folium.template import Template
from folium.utilities import normalize
@@ -33,7 +32,7 @@ def test_polyline_from_encoded():
"""
var {{this.get_name()}} = L.Polyline.fromEncoded(
{{ this.encoded|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{this._parent.get_name()}});
"""
)
@@ -69,7 +68,7 @@ def test_polygon_from_encoded():
"""
var {{this.get_name()}} = L.Polygon.fromEncoded(
{{ this.encoded|tojson }},
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
)
.addTo({{this._parent.get_name()}});
"""
diff --git a/tests/plugins/test_fast_marker_cluster.py b/tests/plugins/test_fast_marker_cluster.py
index 25aa3e266..ba6451377 100644
--- a/tests/plugins/test_fast_marker_cluster.py
+++ b/tests/plugins/test_fast_marker_cluster.py
@@ -6,10 +6,10 @@
import numpy as np
import pandas as pd
import pytest
-from jinja2 import Template
import folium
from folium.plugins import FastMarkerCluster
+from folium.template import Template
from folium.utilities import normalize
@@ -48,7 +48,7 @@ def test_fast_marker_cluster():
{{ this.callback }}
var data = {{ this.data|tojson }};
- var cluster = L.markerClusterGroup({{ this.options|tojson }});
+ var cluster = L.markerClusterGroup({{ this.options|tojavascript }});
{%- if this.icon_create_function is not none %}
cluster.options.iconCreateFunction =
{{ this.icon_create_function.strip() }};
diff --git a/tests/plugins/test_feature_group_sub_group.py b/tests/plugins/test_feature_group_sub_group.py
index 6a97ca7f8..463ca73e6 100644
--- a/tests/plugins/test_feature_group_sub_group.py
+++ b/tests/plugins/test_feature_group_sub_group.py
@@ -3,10 +3,9 @@
------------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_float_image.py b/tests/plugins/test_float_image.py
index d289e0e49..6dd78d0cf 100644
--- a/tests/plugins/test_float_image.py
+++ b/tests/plugins/test_float_image.py
@@ -3,10 +3,9 @@
---------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_fullscreen.py b/tests/plugins/test_fullscreen.py
index 4e0029b38..6844ef582 100644
--- a/tests/plugins/test_fullscreen.py
+++ b/tests/plugins/test_fullscreen.py
@@ -4,10 +4,9 @@
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -21,7 +20,7 @@ def test_fullscreen():
tmpl = Template(
"""
L.control.fullscreen(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
).addTo({{this._parent.get_name()}});
"""
)
diff --git a/tests/plugins/test_grouped_layer_control.py b/tests/plugins/test_grouped_layer_control.py
index 18166e173..d55bba1dc 100644
--- a/tests/plugins/test_grouped_layer_control.py
+++ b/tests/plugins/test_grouped_layer_control.py
@@ -16,16 +16,17 @@ def test_grouped_layer_control():
m.add_child(fg3)
lc = groupedlayercontrol.GroupedLayerControl(groups={"groups1": [fg1, fg2]})
lc.add_to(m)
- out = normalize(m._parent.render())
+ out = m._parent.render()
+ print(out)
+ out = normalize(out)
assert (
"https://cdnjs.cloudflare.com/ajax/libs/leaflet-groupedlayercontrol/0.6.1/leaflet.groupedlayercontrol.min.js"
in out
)
- assert (
- normalize(
- f"""
+ expected = normalize(
+ f"""
L.control.groupedLayers(
null,
{{
@@ -34,10 +35,9 @@ def test_grouped_layer_control():
"g2" : {fg2.get_name()},
}},
}},
- {{"exclusiveGroups": ["groups1"]}},
+ {{"exclusiveGroups": ["groups1",],}},
).addTo({m.get_name()});
{fg2.get_name()}.remove();
"""
- )
- in out
)
+ assert expected in out
diff --git a/tests/plugins/test_heat_map.py b/tests/plugins/test_heat_map.py
index 736175366..d306563e6 100644
--- a/tests/plugins/test_heat_map.py
+++ b/tests/plugins/test_heat_map.py
@@ -5,10 +5,10 @@
import numpy as np
import pytest
-from jinja2 import Template
import folium
from folium.plugins import HeatMap
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_heat_map_withtime.py b/tests/plugins/test_heat_map_withtime.py
index ade6b4e68..1f228fce8 100644
--- a/tests/plugins/test_heat_map_withtime.py
+++ b/tests/plugins/test_heat_map_withtime.py
@@ -4,10 +4,10 @@
"""
import numpy as np
-from jinja2 import Template
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_marker_cluster.py b/tests/plugins/test_marker_cluster.py
index 4c3d635ce..0b01db746 100644
--- a/tests/plugins/test_marker_cluster.py
+++ b/tests/plugins/test_marker_cluster.py
@@ -4,10 +4,10 @@
"""
import numpy as np
-from jinja2 import Template
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -26,7 +26,7 @@ def test_marker_cluster():
tmpl_for_expected = Template(
"""
var {{this.get_name()}} = L.markerClusterGroup(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{%- if this.icon_create_function is not none %}
{{ this.get_name() }}.options.iconCreateFunction =
@@ -36,7 +36,7 @@ def test_marker_cluster():
{% for marker in this._children.values() %}
var {{marker.get_name()}} = L.marker(
{{ marker.location|tojson }},
- {}
+ {"draggable": null,"autoPan": null,}
).addTo({{this.get_name()}});
{% endfor %}
diff --git a/tests/plugins/test_polyline_text_path.py b/tests/plugins/test_polyline_text_path.py
index fdd83dc7d..31804b17c 100644
--- a/tests/plugins/test_polyline_text_path.py
+++ b/tests/plugins/test_polyline_text_path.py
@@ -3,10 +3,9 @@
---------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -52,7 +51,7 @@ def test_polyline_text_path():
"""
{{ this.polyline.get_name() }}.setText(
"{{this.text}}",
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
"""
)
diff --git a/tests/plugins/test_realtime.py b/tests/plugins/test_realtime.py
index 03bfb7716..4e0743888 100644
--- a/tests/plugins/test_realtime.py
+++ b/tests/plugins/test_realtime.py
@@ -3,10 +3,9 @@
------------------
"""
-from jinja2 import Template
-
import folium
from folium.plugins import MarkerCluster, Realtime
+from folium.template import Template
from folium.utilities import JsCode, normalize
@@ -30,7 +29,7 @@ def test_realtime():
tmpl_for_expected = Template(
"""
{% macro script(this, kwargs) %}
- var {{ this.get_name() }}_options = {{ this.options|tojson }};
+ var {{ this.get_name() }}_options = {{ this.options|tojavascript }};
{% for key, value in this.functions.items() %}
{{ this.get_name() }}_options["{{key}}"] = {{ value }};
{% endfor %}
diff --git a/tests/plugins/test_scroll_zoom_toggler.py b/tests/plugins/test_scroll_zoom_toggler.py
index 1c4afea41..2f3a24a2c 100644
--- a/tests/plugins/test_scroll_zoom_toggler.py
+++ b/tests/plugins/test_scroll_zoom_toggler.py
@@ -3,10 +3,9 @@
----------------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_semicircle.py b/tests/plugins/test_semicircle.py
index 191f73ca4..de674ec64 100644
--- a/tests/plugins/test_semicircle.py
+++ b/tests/plugins/test_semicircle.py
@@ -4,10 +4,9 @@
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -49,7 +48,7 @@ def test_semicircle():
"""
var {{ this.get_name() }} = L.semiCircle(
{{ this.location|tojson }},
- {{ this.options | tojson }}
+ {{ this.options|tojavascript }}
)
.setDirection{{ this.direction }}
.addTo({{ this._parent.get_name() }});
@@ -60,7 +59,7 @@ def test_semicircle():
"""
var {{ this.get_name() }} = L.semiCircle(
{{ this.location|tojson }},
- {{ this.options | tojson }}
+ {{ this.options|tojavascript }}
)
.addTo({{ this._parent.get_name() }});
"""
diff --git a/tests/plugins/test_tag_filter_button.py b/tests/plugins/test_tag_filter_button.py
index 434fb6d64..3f6e3f5ee 100644
--- a/tests/plugins/test_tag_filter_button.py
+++ b/tests/plugins/test_tag_filter_button.py
@@ -6,10 +6,10 @@
import random
import numpy as np
-from jinja2 import Template
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_terminator.py b/tests/plugins/test_terminator.py
index 3d111bc55..08eda9c80 100644
--- a/tests/plugins/test_terminator.py
+++ b/tests/plugins/test_terminator.py
@@ -3,10 +3,9 @@
---------------
"""
-from jinja2 import Template
-
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
diff --git a/tests/plugins/test_timeline.py b/tests/plugins/test_timeline.py
index 1846ec2ea..b41df405f 100644
--- a/tests/plugins/test_timeline.py
+++ b/tests/plugins/test_timeline.py
@@ -6,11 +6,10 @@
import json
-from jinja2 import Template
-
import folium
from folium import plugins
from folium.features import GeoJsonPopup
+from folium.template import Template
from folium.utilities import normalize
@@ -63,7 +62,7 @@ def test_timeline():
{% endmacro %}
{% macro script(this, kwargs) %}
- var {{ this.get_name() }}_options = {{ this.options|tojson }};
+ var {{ this.get_name() }}_options = {{ this.options|tojavascript }};
{% for key, value in this.functions.items() %}
{{ this.get_name() }}_options["{{key}}"] = {{ value }};
{% endfor %}
diff --git a/tests/plugins/test_timestamped_geo_json.py b/tests/plugins/test_timestamped_geo_json.py
index 66ce645b2..89c525c0c 100644
--- a/tests/plugins/test_timestamped_geo_json.py
+++ b/tests/plugins/test_timestamped_geo_json.py
@@ -5,10 +5,10 @@
"""
import numpy as np
-from jinja2 import Template
import folium
from folium import plugins
+from folium.template import Template
from folium.utilities import normalize
@@ -146,7 +146,7 @@ def test_timestamped_geo_json():
}
);
var timeDimensionControl = new L.Control.TimeDimensionCustom(
- {{ this.options|tojson }}
+ {{ this.options|tojavascript }}
);
{{this._parent.get_name()}}.addControl(this.timeDimensionControl);
diff --git a/tests/test_features.py b/tests/test_features.py
index 94d27d329..1f1e64f1a 100644
--- a/tests/test_features.py
+++ b/tests/test_features.py
@@ -100,7 +100,7 @@ def test_divicon():
""" # noqa
div = folium.DivIcon(html=html)
assert isinstance(div, Element)
- assert div.options["className"] == "empty"
+ assert div.options["class_name"] == "empty"
assert div.options["html"] == html
diff --git a/tests/test_folium.py b/tests/test_folium.py
index e66392aee..58ad28c97 100644
--- a/tests/test_folium.py
+++ b/tests/test_folium.py
@@ -12,12 +12,12 @@
import pandas as pd
import pytest
import xyzservices.providers as xyz
-from jinja2 import Template
from jinja2.utils import htmlsafe_json_dumps
import folium
from folium import TileLayer
from folium.features import Choropleth, GeoJson
+from folium.template import Template
rootpath = os.path.abspath(os.path.dirname(__file__))
@@ -92,7 +92,7 @@ def test_init(self):
assert self.m.get_root() == self.m._parent
assert self.m.location == [45.5236, -122.6750]
assert self.m.options["zoom"] == 4
- assert self.m.options["maxBounds"] == [[-90, -180], [90, 180]]
+ assert self.m.options["max_bounds"] == [[-90, -180], [90, 180]]
assert self.m.position == "relative"
assert self.m.height == (400, "px")
assert self.m.width == (900, "px")
@@ -464,28 +464,28 @@ def test_global_switches(self):
m = folium.Map(prefer_canvas=True)
out = m._parent.render()
out_str = "".join(out.split())
- assert "preferCanvas:true" in out_str
+ assert '"preferCanvas":true' in out_str
assert not m.global_switches.no_touch
assert not m.global_switches.disable_3d
m = folium.Map(no_touch=True)
out = m._parent.render()
out_str = "".join(out.split())
- assert "preferCanvas:false" in out_str
+ assert '"preferCanvas":false' in out_str
assert m.global_switches.no_touch
assert not m.global_switches.disable_3d
m = folium.Map(disable_3d=True)
out = m._parent.render()
out_str = "".join(out.split())
- assert "preferCanvas:false" in out_str
+ assert '"preferCanvas":false' in out_str
assert not m.global_switches.no_touch
assert m.global_switches.disable_3d
m = folium.Map(prefer_canvas=True, no_touch=True, disable_3d=True)
out = m._parent.render()
out_str = "".join(out.split())
- assert "preferCanvas:true" in out_str
+ assert '"preferCanvas":true' in out_str
assert m.global_switches.no_touch
assert m.global_switches.disable_3d
diff --git a/tests/test_map.py b/tests/test_map.py
index e67022d18..7104971a6 100644
--- a/tests/test_map.py
+++ b/tests/test_map.py
@@ -112,8 +112,11 @@ def test_popup_sticky():
rendered = popup._template.render(this=popup, kwargs={})
expected = """
var {popup_name} = L.popup({{
- "autoClose": false, "closeOnClick": false, "maxWidth": "100%"
+ "maxWidth": "100%",
+ "autoClose": false,
+ "closeOnClick": false,
}});
+
var {html_name} = $(`Some text.
`)[0];
{popup_name}.setContent({html_name});
{map_name}.bindPopup({popup_name});
@@ -131,7 +134,7 @@ def test_popup_show():
rendered = popup._template.render(this=popup, kwargs={})
expected = """
var {popup_name} = L.popup({{
- "autoClose": false, "maxWidth": "100%"
+ "maxWidth": "100%","autoClose": false,"closeOnClick": null,
}});
var {html_name} = $(`Some text.
`)[0];
{popup_name}.setContent({html_name});
@@ -150,7 +153,11 @@ def test_popup_backticks():
popup = Popup("back`tick`tick").add_to(m)
rendered = popup._template.render(this=popup, kwargs={})
expected = """
- var {popup_name} = L.popup({{"maxWidth": "100%"}});
+ var {popup_name} = L.popup({{
+ "maxWidth": "100%",
+ "autoClose": null,
+ "closeOnClick": null,
+ }});
var {html_name} = $(`back\\`tick\\`tick
`)[0];
{popup_name}.setContent({html_name});
{map_name}.bindPopup({popup_name});
@@ -167,7 +174,11 @@ def test_popup_backticks_already_escaped():
popup = Popup("back\\`tick").add_to(m)
rendered = popup._template.render(this=popup, kwargs={})
expected = """
- var {popup_name} = L.popup({{"maxWidth": "100%"}});
+ var {popup_name} = L.popup({{
+ "maxWidth": "100%",
+ "autoClose": null,
+ "closeOnClick": null,
+ }});
var {html_name} = $(`back\\`tick
`)[0];
{popup_name}.setContent({html_name});
{map_name}.bindPopup({popup_name});
diff --git a/tests/test_raster_layers.py b/tests/test_raster_layers.py
index dcef20c3a..07e9f7eda 100644
--- a/tests/test_raster_layers.py
+++ b/tests/test_raster_layers.py
@@ -6,9 +6,9 @@
import pytest
import xyzservices
-from jinja2 import Template
import folium
+from folium.template import Template
from folium.utilities import normalize