Skip to content

Commit 0de6914

Browse files
authored
Merge pull request #1416 from Conengmo/js-css-in-class
2 parents 2e11e89 + f0dc32b commit 0de6914

27 files changed

Lines changed: 329 additions & 613 deletions

folium/elements.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
from branca.element import Figure, Element, JavascriptLink, CssLink
2+
3+
4+
class JSCSSMixin(Element):
5+
"""Render links to external Javascript and CSS resources."""
6+
7+
default_js = []
8+
default_css = []
9+
10+
def render(self, **kwargs):
11+
figure = self.get_root()
12+
assert isinstance(figure, Figure), ('You cannot render this Element '
13+
'if it is not in a Figure.')
14+
15+
for name, url in self.default_js:
16+
figure.header.add_child(JavascriptLink(url), name=name)
17+
18+
for name, url in self.default_css:
19+
figure.header.add_child(CssLink(url), name=name)
20+
21+
super().render(**kwargs)

folium/features.py

Lines changed: 25 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
from branca.element import (Element, Figure, JavascriptLink, MacroElement)
1515
from branca.utilities import color_brewer
1616

17+
from folium.elements import JSCSSMixin
1718
from folium.folium import Map
1819
from folium.map import (FeatureGroup, Icon, Layer, Marker, Tooltip)
1920
from folium.utilities import (
@@ -36,7 +37,7 @@
3637
import requests
3738

3839

39-
class RegularPolygonMarker(Marker):
40+
class RegularPolygonMarker(JSCSSMixin, Marker):
4041
"""
4142
Custom markers using the Leaflet Data Vis Framework.
4243
@@ -69,6 +70,11 @@ class RegularPolygonMarker(Marker):
6970
{% endmacro %}
7071
""")
7172

73+
default_js = [
74+
('dvf_js',
75+
'https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.0/leaflet-dvf.markers.min.js'),
76+
]
77+
7278
def __init__(self, location, number_of_sides=4, rotation=0, radius=15,
7379
popup=None, tooltip=None, **kwargs):
7480
super(RegularPolygonMarker, self).__init__(
@@ -83,21 +89,8 @@ def __init__(self, location, number_of_sides=4, rotation=0, radius=15,
8389
radius=radius,
8490
))
8591

86-
def render(self, **kwargs):
87-
"""Renders the HTML representation of the element."""
88-
super(RegularPolygonMarker, self).render()
89-
90-
figure = self.get_root()
91-
assert isinstance(figure, Figure), ('You cannot render this Element '
92-
'if it is not in a Figure.')
93-
94-
figure.header.add_child(
95-
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/leaflet-dvf/0.3.0/leaflet-dvf.markers.min.js'),
96-
# noqa
97-
name='dvf_js')
9892

99-
100-
class Vega(Element):
93+
class Vega(JSCSSMixin, Element):
10194
"""
10295
Creates a Vega chart element.
10396
@@ -128,6 +121,15 @@ class Vega(Element):
128121
"""
129122
_template = Template(u'')
130123

124+
default_js = [
125+
('d3',
126+
'https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'),
127+
('vega',
128+
'https://cdnjs.cloudflare.com/ajax/libs/vega/1.4.3/vega.min.js'),
129+
('jquery',
130+
'https://code.jquery.com/jquery-2.1.0.min.js'),
131+
]
132+
131133
def __init__(self, data, width=None, height=None,
132134
left='0%', top='0%', position='relative'):
133135
super(Vega, self).__init__()
@@ -147,6 +149,8 @@ def __init__(self, data, width=None, height=None,
147149

148150
def render(self, **kwargs):
149151
"""Renders the HTML representation of the element."""
152+
super().render(**kwargs)
153+
150154
self.json = json.dumps(self.data)
151155

152156
self._parent.html.add_child(Element(Template("""
@@ -171,18 +175,6 @@ def render(self, **kwargs):
171175
</style>
172176
""").render(this=self, **kwargs)), name=self.get_name())
173177

174-
figure.header.add_child(
175-
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.5/d3.min.js'), # noqa
176-
name='d3')
177-
178-
figure.header.add_child(
179-
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/vega/1.4.3/vega.min.js'), # noqa
180-
name='vega')
181-
182-
figure.header.add_child(
183-
JavascriptLink('https://code.jquery.com/jquery-2.1.0.min.js'),
184-
name='jquery')
185-
186178
figure.script.add_child(
187179
Template("""function vega_parse(spec, div) {
188180
vg.parse.spec(spec, function(chart) { chart({el:div}).update(); });}"""), # noqa
@@ -649,7 +641,7 @@ def _set_default_key(mapping):
649641
del (mapping[key_longest])
650642

651643

652-
class TopoJson(Layer):
644+
class TopoJson(JSCSSMixin, Layer):
653645
"""
654646
Creates a TopoJson object for plotting into a Map.
655647
@@ -721,6 +713,11 @@ class TopoJson(Layer):
721713
{% endmacro %}
722714
""") # noqa
723715

716+
default_js = [
717+
('topojson',
718+
'https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js'),
719+
]
720+
724721
def __init__(self, data, object_path, style_function=None,
725722
name=None, overlay=True, control=True, show=True,
726723
smooth_factor=None, tooltip=None):
@@ -770,14 +767,6 @@ def render(self, **kwargs):
770767
self.style_data()
771768
super(TopoJson, self).render(**kwargs)
772769

773-
figure = self.get_root()
774-
assert isinstance(figure, Figure), ('You cannot render this Element '
775-
'if it is not in a Figure.')
776-
777-
figure.header.add_child(
778-
JavascriptLink('https://cdnjs.cloudflare.com/ajax/libs/topojson/1.6.9/topojson.min.js'), # noqa
779-
name='topojson')
780-
781770
def get_bounds(self):
782771
"""
783772
Computes the bounds of the object itself (not including it's children)

folium/folium.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@
88
import time
99
import warnings
1010

11-
from branca.element import CssLink, Element, Figure, JavascriptLink, MacroElement
11+
from branca.element import Element, Figure, MacroElement
1212

13+
from folium.elements import JSCSSMixin
1314
from folium.map import FitBounds
1415
from folium.raster_layers import TileLayer
1516
from folium.utilities import (
@@ -67,7 +68,7 @@ def __init__(self, no_touch=False, disable_3d=False):
6768
self.disable_3d = disable_3d
6869

6970

70-
class Map(MacroElement):
71+
class Map(JSCSSMixin, MacroElement):
7172
"""Create a Map with Folium and Leaflet.js
7273
7374
Generate a base map of given width and height with either default
@@ -208,6 +209,10 @@ class Map(MacroElement):
208209
{% endmacro %}
209210
""")
210211

212+
# use the module variables for backwards compatibility
213+
default_js = _default_js
214+
default_css = _default_css
215+
211216
def __init__(
212217
self,
213218
location=None,
@@ -341,14 +346,6 @@ def render(self, **kwargs):
341346
# Set global switches
342347
figure.header.add_child(self.global_switches, name='global_switches')
343348

344-
# Import Javascripts
345-
for name, url in _default_js:
346-
figure.header.add_child(JavascriptLink(url), name=name)
347-
348-
# Import Css
349-
for name, url in _default_css:
350-
figure.header.add_child(CssLink(url), name=name)
351-
352349
figure.header.add_child(Element(
353350
'<style>html, body {'
354351
'width: 100%;'

folium/plugins/antpath.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,12 @@
11
# -*- coding: utf-8 -*-
22

3-
from branca.element import Figure, JavascriptLink
4-
3+
from folium.elements import JSCSSMixin
54
from folium.vector_layers import path_options, BaseMultiLocation
65

76
from jinja2 import Template
87

9-
_default_js = [
10-
('antpath',
11-
'https://cdn.jsdelivr.net/npm/leaflet-ant-path@1.1.2/dist/leaflet-ant-path.min.js')
12-
]
13-
148

15-
class AntPath(BaseMultiLocation):
9+
class AntPath(JSCSSMixin, BaseMultiLocation):
1610
"""
1711
Class for drawing AntPath polyline overlays on a map.
1812
@@ -42,6 +36,11 @@ class AntPath(BaseMultiLocation):
4236
{% endmacro %}
4337
""")
4438

39+
default_js = [
40+
('antpath',
41+
'https://cdn.jsdelivr.net/npm/leaflet-ant-path@1.1.2/dist/leaflet-ant-path.min.js')
42+
]
43+
4544
def __init__(self, locations, popup=None, tooltip=None, **kwargs):
4645
super(AntPath, self).__init__(
4746
locations,
@@ -63,14 +62,3 @@ def __init__(self, locations, popup=None, tooltip=None, **kwargs):
6362
'color': kwargs.pop('color', '#0000FF'),
6463
'pulseColor': kwargs.pop('pulse_color', '#FFFFFF'),
6564
})
66-
67-
def render(self, **kwargs):
68-
super(AntPath, self).render()
69-
70-
figure = self.get_root()
71-
assert isinstance(figure, Figure), ('You cannot render this Element '
72-
'if it is not in a Figure.')
73-
74-
# Import Javascripts
75-
for name, url in _default_js:
76-
figure.header.add_child(JavascriptLink(url), name=name)

folium/plugins/beautify_icon.py

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,14 @@
11
# -*- coding: utf-8 -*-
22

3-
from branca.element import CssLink, Figure, JavascriptLink, MacroElement
3+
from branca.element import MacroElement
44

5+
from folium.elements import JSCSSMixin
56
from folium.utilities import parse_options
67

78
from jinja2 import Template
89

9-
_default_js = [
10-
('beautify_icon_js',
11-
'https://cdn.jsdelivr.net/gh/marslan390/BeautifyMarker/leaflet-beautify-marker-icon.min.js')
12-
]
13-
14-
_default_css = [
15-
('beautify_icon_css',
16-
'https://cdn.jsdelivr.net/gh/marslan390/BeautifyMarker/leaflet-beautify-marker-icon.min.css')
17-
]
1810

19-
20-
class BeautifyIcon(MacroElement):
11+
class BeautifyIcon(JSCSSMixin, MacroElement):
2112
"""
2213
Create a BeautifyIcon that can be added to a Marker
2314
@@ -65,6 +56,15 @@ class BeautifyIcon(MacroElement):
6556
ICON_SHAPE_TYPES = ['circle', 'circle-dot', 'doughnut', 'rectangle-dot',
6657
'marker', None]
6758

59+
default_js = [
60+
('beautify_icon_js',
61+
'https://cdn.jsdelivr.net/gh/marslan390/BeautifyMarker/leaflet-beautify-marker-icon.min.js')
62+
]
63+
default_css = [
64+
('beautify_icon_css',
65+
'https://cdn.jsdelivr.net/gh/marslan390/BeautifyMarker/leaflet-beautify-marker-icon.min.css')
66+
]
67+
6868
def __init__(self, icon=None, icon_shape=None, border_width=3,
6969
border_color='#000', text_color='#000',
7070
background_color='#FFF', inner_icon_style='', spin=False,
@@ -85,18 +85,3 @@ def __init__(self, icon=None, icon_shape=None, border_width=3,
8585
text=number,
8686
**kwargs
8787
)
88-
89-
def render(self, **kwargs):
90-
super(BeautifyIcon, self).render(**kwargs)
91-
92-
figure = self.get_root()
93-
assert isinstance(figure, Figure), ('You cannot render this Element '
94-
'if it is not in a Figure.')
95-
96-
# Import Javascripts
97-
for name, url in _default_js:
98-
figure.header.add_child(JavascriptLink(url), name=name)
99-
100-
# Import Css
101-
for name, url in _default_css:
102-
figure.header.add_child(CssLink(url), name=name)

folium/plugins/boat_marker.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,13 @@
11
# -*- coding: utf-8 -*-
22

3-
from branca.element import Figure, JavascriptLink
4-
3+
from folium.elements import JSCSSMixin
54
from folium.map import Marker
65
from folium.utilities import parse_options
76

87
from jinja2 import Template
98

10-
_default_js = [
11-
('markerclusterjs',
12-
'https://unpkg.com/leaflet.boatmarker/leaflet.boatmarker.min.js'),
13-
]
14-
159

16-
class BoatMarker(Marker):
10+
class BoatMarker(JSCSSMixin, Marker):
1711
"""Add a Marker in the shape of a boat.
1812
1913
Parameters
@@ -50,6 +44,11 @@ class BoatMarker(Marker):
5044
{% endmacro %}
5145
""")
5246

47+
default_js = [
48+
('markerclusterjs',
49+
'https://unpkg.com/leaflet.boatmarker/leaflet.boatmarker.min.js'),
50+
]
51+
5352
def __init__(self, location, popup=None, icon=None,
5453
heading=0, wind_heading=None, wind_speed=0, **kwargs):
5554
super(BoatMarker, self).__init__(
@@ -62,14 +61,3 @@ def __init__(self, location, popup=None, icon=None,
6261
self.wind_heading = wind_heading
6362
self.wind_speed = wind_speed
6463
self.options = parse_options(**kwargs)
65-
66-
def render(self, **kwargs):
67-
super(BoatMarker, self).render(**kwargs)
68-
69-
figure = self.get_root()
70-
assert isinstance(figure, Figure), ('You cannot render this Element '
71-
'if it is not in a Figure.')
72-
73-
# Import Javascripts
74-
for name, url in _default_js:
75-
figure.header.add_child(JavascriptLink(url), name=name)

0 commit comments

Comments
 (0)