From 53ab5439ce2c6f6d90c629ce0d15978a84818bb2 Mon Sep 17 00:00:00 2001 From: adarshsm <24850536+adarshsm@users.noreply.github.com> Date: Sat, 14 Nov 2026 11:28:30 +0530 Subject: [PATCH] Preserve every HTML child in a Popup Combine multiple child nodes before setting popup content so later children do not overwrite earlier ones. Load lazy children together while keeping single-child markup unchanged. Co-Authored-By: Claude Code --- folium/map.py | 23 ++++++++++++++++++----- tests/test_map.py | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/folium/map.py b/folium/map.py index daf7ee84cb..9fcda49cbd 100644 --- a/folium/map.py +++ b/folium/map.py @@ -615,16 +615,29 @@ class Popup(MacroElement): _template = Template(""" var {{this.get_name()}} = L.popup({{ this.options|tojavascript }}); + {% set multiple = this.html._children|length > 1 %} + {% if this.lazy and this.html._children %} + {{ this._parent.get_name() }}.once('click', function() { + {% endif %} + {% if multiple %} + var {{ this.get_name() }}_content = document.createElement('div'); + {% endif %} {% for name, element in this.html._children.items() %} - {% if this.lazy %} - {{ this._parent.get_name() }}.once('click', function() { - {{ this.get_name() }}.setContent($(`{{ element.render(**kwargs).replace('\\n',' ') }}`)[0]); - }); + var {{ name }} = $(`{{ element.render(**kwargs).replace('\\n',' ') }}`)[0]; + {% if multiple %} + if ({{ name }}) { + {{ this.get_name() }}_content.appendChild({{ name }}); + } {% else %} - var {{ name }} = $(`{{ element.render(**kwargs).replace('\\n',' ') }}`)[0]; {{ this.get_name() }}.setContent({{ name }}); {% endif %} {% endfor %} + {% if multiple %} + {{ this.get_name() }}.setContent({{ this.get_name() }}_content); + {% endif %} + {% if this.lazy and this.html._children %} + }); + {% endif %} {{ this._parent.get_name() }}.bindPopup({{ this.get_name() }}) {% if this.show %}.openPopup(){% endif %}; diff --git a/tests/test_map.py b/tests/test_map.py index 594c42ce0e..4f4c1a34aa 100644 --- a/tests/test_map.py +++ b/tests/test_map.py @@ -106,6 +106,24 @@ def test_popup_unicode(): assert "".join(popup.html.render().split()) == "".join(tmpl(**kw).split()) +@pytest.mark.parametrize("lazy", [False, True]) +def test_popup_multiple_children(lazy): + popup = Popup("First", lazy=lazy) + popup.html.add_child(Popup("Second").html) + marker = Marker([0, 0], popup=popup).add_to(Map(tiles=None)) + rendered = popup._template.render(this=popup, kwargs={}) + + # Setting content once per child discards all but the last child. + assert rendered.count(".setContent(") == 1 + assert "First" in rendered + assert "Second" in rendered + for name in popup.html._children: + assert f"{popup.get_name()}_content.appendChild({name});" in rendered + if lazy: + assert rendered.count(".once('click'") == 1 + assert f"{marker.get_name()}.bindPopup({popup.get_name()})" in rendered + + def test_popup_sticky(): m = Map() popup = Popup("Some text.", sticky=True).add_to(m)