Multiple locations per item#66
Open
jimsafley wants to merge 24 commits into
Open
Conversation
Items can now have any number of named locations. The admin edit form uses a Leaflet.draw toolbar to add, reposition, and delete markers. Each marker has an optional label editable via popup. The browse map, item show pages, exhibit map blocks, and static site export all reflect multiple locations.
The multi-location rewrite broke the pre-existing behavior of initializing the edit map at the item's saved coordinates and zoom. For single-location items the saved zoom is now respected. For multi-location items fitBounds overrides the center on tab select.
The multi-location rewrite dropped the panTo call after adding a geocoded marker, so the map no longer moved to the found location.
Switch from single-resource format (id/url) to multi-resource format (count/url) to support items with multiple locations. Adds item_id as a whitelisted index param with applySearchFilters support so the url is resolvable.
Leaflet.draw is needed on the item edit form and the contribution form. Loading it globally is not ideal but matches the existing approach for Leaflet itself.
Adds a button to every map (browse, item show, item edit) that fits all markers in the viewport. Translatable strings for the control are passed from PHP to JS via the options object.
KML was a Google Maps era holdover, never a natural fit for Leaflet. A dedicated browseJsonAction() now serves browse-json.php, moving marker HTML assembly to PHP where Omeka helpers are available. Removes the KML route, context switch filters, and ~80 lines of client-side XML parsing.
Before multi-location support, the item marker was placed at the map center via center.show. That was replaced by the options.points loop. Inline and remove the now-single-use _getCenter() helper.
zerocrates
reviewed
May 2, 2026
Member
zerocrates
left a comment
There was a problem hiding this comment.
Mostly minor points, though a couple would be a little more significant as changes (probably just the JSON form submission, really).
| } | ||
|
|
||
| foreach ($remaining as $loc) { | ||
| $loc->delete(); |
Member
There was a problem hiding this comment.
This goes beyond this location to touch several other "form" spots but: do we want to just submit a single locations JSON array instead of a bunch of hidden fields for each one? You'd be able to skip all the monkeying around setting indexes you're doing on the JS side of the form.
Instead of building the popup HTML server-side and sending it down with each location, send raw fields (title, thumbnailUrl, snippet, itemUrl) and build the DOM client-side. This avoids repeating the balloon wrapper markup for every marker in the JSON response.
OmekaMapForm now maintains a locationData object in memory and serializes it to a single geolocation_locations hidden input via _syncJson() on every state change. PHP reads and decodes this field in hookAfterSaveItem and _mapForm, replacing the previous indexed geolocation[n][field] inputs.
Replace locationCounter/locationData/markerMap/_syncJson() with _locationData on each layer. Serialize to JSON once on form submit via drawnItems.getLayers() instead of on every change. Removes the DELETED handler -- Leaflet.draw already removes deleted layers from drawnItems, so they are excluded naturally.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Items can now have more than one location. Each location has an optional label, and the item edit form uses Leaflet.draw to add, reposition, and delete markers. All map views have been updated to reflect this. Includes a database migration.
Breaking changes
This feature requires a major version bump (4.0) due to some breaking changes:
geolocationsfield — the shape of this field in the items API response has changed to support multiple locations per item.Table_Location::findLocationByItem()— removed and replaced byfindLocationsByItem()to support multiple locations per item.Existing API consumers and any code calling these methods directly will need to update.
Cleanup / Refactors
Several pieces of holdover code have been removed:
map_type(49e375a) — a database column and API field from the Google Maps era, later repurposed to track which mapping library was in use. Once Google Maps support was dropped it was always'Leaflet'and served no purpose.geolocation[n][field]) with a singlegeolocation_locationsJSON field; OmekaMapForm maintains alocationDataobject synced via_syncJson()markerHtmlin JSON) to JS (buildMarkerContent); raw data fields sent instead and JS builds the popup DOM client-side