@prefix sioc: <http://rdfs.org/sioc/ns#> .
@prefix dc: <http://purl.org/dc/elements/1.1/> .
@prefix dcterms: <http://purl.org/dc/terms/> .
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
@prefix content: <http://purl.org/rss/1.0/modules/content/> .
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .

<https://lhero.org/portfolio/lh-places/>
  a sioc:Post ;
  dc:title "Changelog" ;
  dcterms:identifier 149925 ;
  dc:modified "2026-10-11T15:45:22Z"^^xsd:dateTime ;
  dc:created "2026-10-11T15:45:22Z"^^xsd:dateTime ;
  sioc:link <https://lhero.org/portfolio/lh-places/changelog/> ;
  sioc:has_creator <https://lhero.org/author/1/#account> ;
  sioc:has_container <https://lhero.org/#posts> ;
  content:encoded "<ul class=\"lh_portfolio-meta\"><li><strong>Part of:</strong> <a href=\"https://lhero.org/portfolio/lh-places/\">LH Places</a></li></ul><ul class=\"lh_portfolio-changelog\"><li><strong>1.30.1:</strong> Fixes a PHP deprecation notice in the bundled wp-geometa-lib when GeoJSON stored as a string is merged into a FeatureCollection, which happens when a post with geo_json is saved or indexed. WP_GeoUtil::merge_geojson() passed an undefined $encoding variable to iconv(), so iconv() always received null as its source encoding and PHP 8.1+ logged a deprecation that the @ operator did not suppress. Invalid UTF-8 is now stripped with WordPress&#039;s wp_check_invalid_utf8() before the string is decoded, which is what the iconv() call was meant to do. Valid GeoJSON is decoded exactly as before.</li><li><strong>1.30:</strong> Legacy release, recorded retrospectively. No release notes survive for this version: the on-disk readme changelog stops at 1.29. The date is when this version&#039;s files were installed, the only record of when it was released.</li><li><strong>1.29:</strong> Fixes geo fields not saving from the block editor for post types registered late on init: the geo meta is now registered at init priority 9999 instead of 10, so those types already exist and declare geo support when it runs, and the fields appear in their REST responses.</li><li><strong>1.28:</strong> Import from media now falls back to reading EXIF directly when WordPress&#039;s image metadata has no coordinates, which is common for iPhone photos on WordPress 7. It parses the raw GPS degree, minute and second values into decimal degrees, prefers the original upload over the rotated copy, and still checks WordPress&#039;s metadata first.</li><li><strong>1.27:</strong> Adds an Import from media button to the block editor Geo Data panel. It looks through the post&#039;s attachments for EXIF GPS data, applies southern and western hemisphere signs, and fills latitude, longitude and GeoJSON from the first usable pair, reporting which attachment it used or that none had GPS data. Backed by a new REST endpoint, lh-places/v1/attachment-exif-gps/{id}, which requires edit_post, validates coordinate ranges and treats 0,0 as missing.</li><li><strong>1.26:</strong> Adds a Show numbered list toggle to the map block&#039;s display settings, on by default. Turning it off hides the list below the map. Single-place maps never show a list.</li><li><strong>1.25:</strong> Multi-place maps now use numbered markers (CSS teardrops with no image files, for any count) and render an ordered list below the map with each post&#039;s linked title and address. The list is plain HTML and works without JavaScript. Single-place maps keep the standard pin and no list.</li><li><strong>1.24:</strong> Removes the lh_places_geomap and lh_places_geojson shortcodes, which the lh-places/map block replaces. map_output() now uses wp_parse_args() with post_type defaulting to any, and the static-map OG image now detects the map block rather than the shortcode.</li><li><strong>1.23:</strong> The map&#039;s post status setting (shortcode attribute and block field) now accepts a comma-separated list such as publish,member,featured, including custom statuses. Each is sanitised and passed to WP_Query as an array. The default is still publish.</li><li><strong>1.22:</strong> Makes maps fully responsive: the map fills a wrapper that holds the configured height, so it always spans the container width, and a ResizeObserver tells Leaflet to redraw whenever the container resizes (sidebar toggles, window resizes, theme layout changes).</li><li><strong>1.21:</strong> Fixes the zoom calculation choosing the closer zoom instead of the further one. The map now fits all markers and only uses the zoom setting when the fitted view would be further out.</li><li><strong>1.20:</strong> Makes the zoom floor reliable by calculating synchronously the zoom fitBounds would choose, taking the closer of that and the zoom setting, and setting the view directly, with no dependence on animation events.</li><li><strong>1.19:</strong> Fixes the zoom floor having no effect on multi-place maps: fitBounds is asynchronous, so the zoom check now runs after the map has finished moving.</li><li><strong>1.18:</strong> Zoom on multi-place maps becomes a floor: the map fits all markers first, then zooms in to the zoom setting if it ended up further out than that.</li><li><strong>1.17:</strong> Reworks zoom for multi-place maps: zoom is now passed to fitBounds as its maximum, so markers are never over-zoomed but the map always zooms out far enough to show them all. Single-place zoom is unchanged. The block&#039;s zoom control gains help text explaining both behaviours.</li><li><strong>1.16:</strong> Fixes the zoom setting having no effect on multi-place maps (the comparison was inverted), and relabels the block&#039;s zoom control from &quot;Default zoom (single-point maps)&quot; to &quot;Default zoom&quot;.</li><li><strong>1.15:</strong> Fixes the map block rendering nothing when the post type was left blank and specific post IDs were given: it now queries all post types, and passes any to WP_Query as a plain string rather than an array. An empty map now shows a visible placeholder in the editor preview so misconfiguration is easy to spot, and stays silent on the public site.</li><li><strong>1.14:</strong> Adds the lh-places/map block, server-side rendered through the same map_output() logic as the map shortcode, with post type, post count, height, zoom, default layer, category, post parent and specific post IDs in the sidebar and a settings summary on the editor canvas. Registered from block.json with no build step. The geo panel still loads only on geo-enabled post types, while the map block loads on every block editor screen. The lh_places_geomap shortcode was kept for existing posts.</li><li><strong>1.13:</strong> Adds a satellite tile layer (Esri World Imagery, no API key) to every map through Leaflet&#039;s layer control, and a layer attribute to start a map on street or satellite view.</li><li><strong>1.12:</strong> Fixes missing Leaflet marker icons: the marker images now sit where Leaflet&#039;s CSS expects them (assets/css/images/), and the map passes the plugin&#039;s absolute image URL to the script instead of relying on Leaflet&#039;s relative-path guessing.</li><li><strong>1.11:</strong> Fixes a false &quot;ST_AsGeoJSON not supported&quot; notice on MariaDB 11 caused by a stale wp_geometa_capabilities option. The notice now says the cache may be stale and offers a Re-scan database capabilities link, which deletes the cached option and runs a live function test (nonce-checked, handled on admin_init with a safe redirect).</li><li><strong>1.10:</strong> Bundles wp-geometa-lib 0.4.0 for spatial indexing, so no separate plugin is needed. Adds a geo_json post meta field for full GeoJSON (polygons, lines, feature collections), REST endpoints lh-places/v1/geojson/{id} and lh-places/v1/geojson, and an lh_places_geojson shortcode. Replaces the Google Maps renderer with bundled Leaflet 1.9.4, so maps need no API key, and lh_places_geomap now renders points, polygons and lines natively. Adds a GeoJSON field to the block editor panel and classic meta box, keeps point GeoJSON and latitude/longitude in sync both ways, and shows an admin notice if the database lacks ST_AsGeoJSON. The OpenStreetMap attribution link replaces the Google Maps link, and the Google Maps API key is now optional (static OG images only). Fixes nonce handling to unslash before sanitising, and escapes all meta box output.</li><li><strong>1.03:</strong> Block editor geo panel using useEntityProp, and a classic editor meta box with geolocation lookup. Stores the WordPress geodata standard fields geo_latitude, geo_longitude and geo_address. Adds GeoRSS namespace and item output to feeds, ICBM and DC.title head meta tags, and Tribe Events and GatherPress integrations. The exact release date of this version is not recorded.</li></ul>"^^rdf:XMLLiteral ;
  sioc:content "Part of: LH Places1.30.1: Fixes a PHP deprecation notice in the bundled wp-geometa-lib when GeoJSON stored as a string is merged into a FeatureCollection, which happens when a post with geo_json is saved or indexed. WP_GeoUtil::merge_geojson() passed an undefined $encoding variable to iconv(), so iconv() always received null as its source encoding and PHP 8.1+ logged a deprecation that the @ operator did not suppress. Invalid UTF-8 is now stripped with WordPress&#039;s wp_check_invalid_utf8() before the string is decoded, which is what the iconv() call was meant to do. Valid GeoJSON is decoded exactly as before.1.30: Legacy release, recorded retrospectively. No release notes survive for this version: the on-disk readme changelog stops at 1.29. The date is when this version&#039;s files were installed, the only record of when it was released.1.29: Fixes geo fields not saving from the block editor for post types registered late on init: the geo meta is now registered at init priority 9999 instead of 10, so those types already exist and declare geo support when it runs, and the fields appear in their REST responses.1.28: Import from media now falls back to reading EXIF directly when WordPress&#039;s image metadata has no coordinates, which is common for iPhone photos on WordPress 7. It parses the raw GPS degree, minute and second values into decimal degrees, prefers the original upload over the rotated copy, and still checks WordPress&#039;s metadata first.1.27: Adds an Import from media button to the block editor Geo Data panel. It looks through the post&#039;s attachments for EXIF GPS data, applies southern and western hemisphere signs, and fills latitude, longitude and GeoJSON from the first usable pair, reporting which attachment it used or that none had GPS data. Backed by a new REST endpoint, lh-places/v1/attachment-exif-gps/{id}, which requires edit_post, validates coordinate ranges and treats 0,0 as missing.1.26: Adds a Show numbered list toggle to the map block&#039;s display settings, on by default. Turning it off hides the list below the map. Single-place maps never show a list.1.25: Multi-place maps now use numbered markers (CSS teardrops with no image files, for any count) and render an ordered list below the map with each post&#039;s linked title and address. The list is plain HTML and works without JavaScript. Single-place maps keep the standard pin and no list.1.24: Removes the lh_places_geomap and lh_places_geojson shortcodes, which the lh-places/map block replaces. map_output() now uses wp_parse_args() with post_type defaulting to any, and the static-map OG image now detects the map block rather than the shortcode.1.23: The map&#039;s post status setting (shortcode attribute and block field) now accepts a comma-separated list such as publish,member,featured, including custom statuses. Each is sanitised and passed to WP_Query as an array. The default is still publish.1.22: Makes maps fully responsive: the map fills a wrapper that holds the configured height, so it always spans the container width, and a ResizeObserver tells Leaflet to redraw whenever the container resizes (sidebar toggles, window resizes, theme layout changes).1.21: Fixes the zoom calculation choosing the closer zoom instead of the further one. The map now fits all markers and only uses the zoom setting when the fitted view would be further out.1.20: Makes the zoom floor reliable by calculating synchronously the zoom fitBounds would choose, taking the closer of that and the zoom setting, and setting the view directly, with no dependence on animation events.1.19: Fixes the zoom floor having no effect on multi-place maps: fitBounds is asynchronous, so the zoom check now runs after the map has finished moving.1.18: Zoom on multi-place maps becomes a floor: the map fits all markers first, then zooms in to the zoom setting if it ended up further out than that.1.17: Reworks zoom for multi-place maps: zoom is now passed to fitBounds as its maximum, so markers are never over-zoomed but the map always zooms out far enough to show them all. Single-place zoom is unchanged. The block&#039;s zoom control gains help text explaining both behaviours.1.16: Fixes the zoom setting having no effect on multi-place maps (the comparison was inverted), and relabels the block&#039;s zoom control from &quot;Default zoom (single-point maps)&quot; to &quot;Default zoom&quot;.1.15: Fixes the map block rendering nothing when the post type was left blank and specific post IDs were given: it now queries all post types, and passes any to WP_Query as a plain string rather than an array. An empty map now shows a visible placeholder in the editor preview so misconfiguration is easy to spot, and stays silent on the public site.1.14: Adds the lh-places/map block, server-side rendered through the same map_output() logic as the map shortcode, with post type, post count, height, zoom, default layer, category, post parent and specific post IDs in the sidebar and a settings summary on the editor canvas. Registered from block.json with no build step. The geo panel still loads only on geo-enabled post types, while the map block loads on every block editor screen. The lh_places_geomap shortcode was kept for existing posts.1.13: Adds a satellite tile layer (Esri World Imagery, no API key) to every map through Leaflet&#039;s layer control, and a layer attribute to start a map on street or satellite view.1.12: Fixes missing Leaflet marker icons: the marker images now sit where Leaflet&#039;s CSS expects them (assets/css/images/), and the map passes the plugin&#039;s absolute image URL to the script instead of relying on Leaflet&#039;s relative-path guessing.1.11: Fixes a false &quot;ST_AsGeoJSON not supported&quot; notice on MariaDB 11 caused by a stale wp_geometa_capabilities option. The notice now says the cache may be stale and offers a Re-scan database capabilities link, which deletes the cached option and runs a live function test (nonce-checked, handled on admin_init with a safe redirect).1.10: Bundles wp-geometa-lib 0.4.0 for spatial indexing, so no separate plugin is needed. Adds a geo_json post meta field for full GeoJSON (polygons, lines, feature collections), REST endpoints lh-places/v1/geojson/{id} and lh-places/v1/geojson, and an lh_places_geojson shortcode. Replaces the Google Maps renderer with bundled Leaflet 1.9.4, so maps need no API key, and lh_places_geomap now renders points, polygons and lines natively. Adds a GeoJSON field to the block editor panel and classic meta box, keeps point GeoJSON and latitude/longitude in sync both ways, and shows an admin notice if the database lacks ST_AsGeoJSON. The OpenStreetMap attribution link replaces the Google Maps link, and the Google Maps API key is now optional (static OG images only). Fixes nonce handling to unslash before sanitising, and escapes all meta box output.1.03: Block editor geo panel using useEntityProp, and a classic editor meta box with geolocation lookup. Stores the WordPress geodata standard fields geo_latitude, geo_longitude and geo_address. Adds GeoRSS namespace and item output to feeds, ICBM and DC.title head meta tags, and Tribe Events and GatherPress integrations. The exact release date of this version is not recorded." ;
  sioc:topic <https://lhero.org/?taxonomy=author&term=cap-1> .

<https://lhero.org/author/1/#account> rdfs:seeAlso <https://lhero.org/author/1/?feed=lhrdf&format=turtle> .
<https://lhero.org/?taxonomy=author&term=cap-1> rdfs:seeAlso <https://lhero.org/?taxonomy=author&term=cap-1&feed=lhrdf&format=turtle> .
