Skip to content

Commit 5c2f3d1

Browse files
hansthenConengmo
andauthored
Override css and js links (#1898)
* Re: #1519 Override css and js links Add a method to the JSCSSMixin that allows users to override a specific link to css or js. Unfortunately this still requires users to know the name of the of the link, which will require looking at the code or introspection. * Update to also add links when not already present Also added a method to bulk add several links in one call. * Updated after review comments * Update folium/elements.py Co-authored-by: Frank Anema <[email protected]> * Add documentation on overriding css and js links --------- Co-authored-by: Frank Anema <[email protected]>
1 parent aa13026 commit 5c2f3d1

File tree

3 files changed

+101
-0
lines changed

3 files changed

+101
-0
lines changed

docs/advanced_guide.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ Advanced guide
1414
advanced_guide/custom_tiles
1515
advanced_guide/piechart_icons
1616
advanced_guide/polygons_from_list_of_points
17+
advanced_guide/customize_javascript_and_css
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Customizing javascript or css resources
2+
3+
```{code-cell} ipython3
4+
---
5+
nbsphinx: hidden
6+
---
7+
import folium
8+
```
9+
10+
## Adding javascript or css resources
11+
Many leaflet resources require loading of custom css or javascript modules. This is handled in the `folium.elements.JSCSSMixin` class. Anything that inherits from this class can load custom resources.
12+
13+
You can use the methods `add_js_link` and `add_css_link` to ensure these resources are loaded into the map.
14+
15+
### Example 1: overriding the locations from where resources are loaded
16+
One use case is to override the locations from where resources are loaded. This can be useful if you have to use a private CDN for your javascript and css resources, or if you want to use a different version.
17+
18+
```{code-cell}
19+
m = folium.Map()
20+
m.add_css_link(
21+
"bootstrap_css",
22+
"https://example.com/bootstrap/400.5.0/css/bootstrap.min.css"
23+
)
24+
```
25+
26+
27+
### Example 2: loading additional javascript
28+
A second use case is to load library modules that you can then use inside JsCode blocks. Continuing from the Realtime ISS example, see :doc:Realtime <user_guide/plugins/realtime>, we can modify this so that it uses the dayjs library to format the current date.
29+
30+
```{code-cell} ipython3
31+
from folium.utilities import JsCode
32+
from folium.plugins import Realtime
33+
34+
m = folium.Map()
35+
on_each_feature = JsCode("""
36+
function(f, l) {
37+
l.bindPopup(function() {
38+
return '<h5>' + dayjs.unix(f.properties.timestamp).format() + '</h5>';
39+
});
40+
}
41+
""")
42+
43+
source = JsCode("""
44+
function(responseHandler, errorHandler) {
45+
var url = 'https://api.wheretheiss.at/v1/satellites/25544';
46+
47+
fetch(url)
48+
.then((response) => {
49+
return response.json().then((data) => {
50+
var { id, timestamp, longitude, latitude } = data;
51+
52+
return {
53+
'type': 'FeatureCollection',
54+
'features': [{
55+
'type': 'Feature',
56+
'geometry': {
57+
'type': 'Point',
58+
'coordinates': [longitude, latitude]
59+
},
60+
'properties': {
61+
'id': id,
62+
'timestamp': timestamp
63+
}
64+
}]
65+
};
66+
})
67+
})
68+
.then(responseHandler)
69+
.catch(errorHandler);
70+
}
71+
""")
72+
73+
rt = Realtime(source,
74+
on_each_feature=on_each_feature,
75+
interval=1000)
76+
rt.add_js_link("dayjs", "https://cdn.jsdelivr.net/npm/[email protected]/dayjs.min.js")
77+
rt.add_to(m)
78+
m
79+
```

folium/elements.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,27 @@ def render(self, **kwargs) -> None:
2424

2525
super().render(**kwargs)
2626

27+
def add_css_link(self, name: str, url: str):
28+
"""Add or update css resource link."""
29+
self._add_link(name, url, self.default_css)
30+
31+
def add_js_link(self, name: str, url: str):
32+
"""Add or update JS resource link."""
33+
self._add_link(name, url, self.default_js)
34+
35+
def _add_link(self, name: str, url: str, default_list: List[Tuple[str, str]]):
36+
"""Modify a css or js link.
37+
38+
If `name` does not exist, the link will be appended
39+
"""
40+
41+
for i, pair in enumerate(default_list):
42+
if pair[0] == name:
43+
default_list[i] = (name, url)
44+
break
45+
else:
46+
default_list.append((name, url))
47+
2748

2849
class ElementAddToElement(MacroElement):
2950
"""Abstract class to add an element to another element."""

0 commit comments

Comments
 (0)