Skip to content

Commit d503553

Browse files
committed
Add leaflet_method decorator
This allows javascript method calls to be generated using an empty method body and a signature. Useful for writing plugins. As an example (and the driving motivation) I implemented this on the geoman plugin.
1 parent e3ca7ba commit d503553

File tree

2 files changed

+42
-3
lines changed

2 files changed

+42
-3
lines changed

folium/elements.py

Lines changed: 34 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
from functools import wraps
12
from typing import List, Tuple
23

34
from branca.element import (
@@ -9,7 +10,15 @@
910
)
1011

1112
from folium.template import Template
12-
from folium.utilities import JsCode
13+
from folium.utilities import JsCode, camelize
14+
15+
16+
def leaflet_method(fn):
17+
@wraps(fn)
18+
def inner(self, *args, **kwargs):
19+
self.add_child(MethodCall(self, fn.__name__, *args, **kwargs))
20+
21+
return inner
1322

1423

1524
class JSCSSMixin(MacroElement):
@@ -148,3 +157,27 @@ def __init__(self, element_name: str, element_parent_name: str):
148157
super().__init__()
149158
self.element_name = element_name
150159
self.element_parent_name = element_parent_name
160+
161+
162+
class MethodCall(MacroElement):
163+
"""Abstract class to add an element to another element."""
164+
165+
_template = Template(
166+
"""
167+
{% macro script(this, kwargs) %}
168+
{{ this.target }}.{{ this.method }}(
169+
{% for arg in this.args %}
170+
{{ arg | tojavascript }},
171+
{% endfor %}
172+
{{ this.kwargs | tojavascript }}
173+
);
174+
{% endmacro %}
175+
"""
176+
)
177+
178+
def __init__(self, target: MacroElement, method: str, *args, **kwargs):
179+
super().__init__()
180+
self.target = target.get_name()
181+
self.method = camelize(method)
182+
self.args = args
183+
self.kwargs = kwargs

folium/plugins/geoman.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from branca.element import MacroElement
22

3-
from folium.elements import JSCSSMixin
3+
from folium.elements import JSCSSMixin, leaflet_method
44
from folium.template import Template
55
from folium.utilities import remove_empty
66

@@ -22,6 +22,8 @@ class GeoMan(JSCSSMixin, MacroElement):
2222
_template = Template(
2323
"""
2424
{% macro script(this, kwargs) %}
25+
/* ensure the name is usable */
26+
var {{this.get_name()}} = {{this._parent.get_name()}}.pm;
2527
{%- if this.feature_group %}
2628
var drawnItems_{{ this.get_name() }} =
2729
{{ this.feature_group.get_name() }};
@@ -37,7 +39,7 @@ class GeoMan(JSCSSMixin, MacroElement):
3739
*/
3840
var drawnItems = drawnItems_{{ this.get_name() }};
3941
40-
{{this._parent.get_name()}}.pm.addControls(
42+
{{this.get_name()}}.addControls(
4143
{{this.options|tojavascript}}
4244
)
4345
drawnItems_{{ this.get_name() }}.eachLayer(function(layer){
@@ -99,3 +101,7 @@ def __init__(
99101
self.options = remove_empty(
100102
position=position, layer_group=feature_group, **kwargs
101103
)
104+
105+
@leaflet_method
106+
def set_global_options(self, **kwargs):
107+
pass

0 commit comments

Comments
 (0)