{"id":335738,"date":"2026-07-21T08:57:17","date_gmt":"2026-07-21T08:57:17","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/peakmaps\/"},"modified":"2026-08-06T16:10:38","modified_gmt":"2026-08-06T16:10:38","slug":"peakmaps","status":"publish","type":"plugin","link":"https:\/\/de.wordpress.org\/plugins\/peakmaps\/","author":23528056,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"2.9.63","stable_tag":"2.9.63","tested":"7.0.4","requires":"6.2","requires_php":"7.4","requires_plugins":null,"header_name":"PeakMaps","header_author":"consigno","header_description":"Map plugin with GPX tracks, markers, elevation profile, and its own peak database.","assets_banners_color":"","last_updated":"2026-08-06 16:10:38","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"https:\/\/consigno.no\/peakmaps","header_author_uri":"https:\/\/consigno.no","rating":0,"author_block_rating":0,"active_installs":0,"downloads":136,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"2.9.61":{"tag":"2.9.61","author":"consigno","date":"2026-07-21 08:56:48"},"2.9.62":{"tag":"2.9.62","author":"consigno","date":"2026-07-21 09:44:11"},"2.9.63":{"tag":"2.9.63","author":"consigno","date":"2026-08-06 16:10:38"}},"upgrade_notice":{"2.4.61":"<ul>\n<li>Internal: global class, constant, and function names renamed from nu_\/NU_ to a PeakMaps prefix (storage, block names, shortcodes, and AJAX unchanged).<\/li>\n<\/ul>","2.4.60":"<p>Preparation for distribution: readme, metadata, licenses, and cleanup on uninstall. Remember to clear the cache after updating.<\/p>"},"ratings":[],"assets_icons":[],"assets_banners":[],"assets_blueprints":{},"all_blocks":{"nu\/kart":{"name":"nu\/kart","title":"PeakMaps Map"},"nu\/topper":{"name":"nu\/topper","title":"PeakMaps Peaks"}},"tagged_versions":["2.9.61","2.9.62","2.9.63"],"block_files":[],"assets_screenshots":[],"screenshots":{"1":"Interactive map with markers and elevation profile.","2":"Sortable and filterable peak table.","3":"Admin: map settings."}},"plugin_section":[],"plugin_tags":[10682,16150,4595,2660,272587],"plugin_category":[49],"plugin_contributors":[272588],"plugin_business_model":[],"class_list":["post-335738","plugin","type-plugin","status-publish","hentry","plugin_tags-gpx","plugin_tags-hiking","plugin_tags-leaflet","plugin_tags-maps","plugin_tags-peaks","plugin_category-maps-and-location","plugin_contributors-consigno","plugin_committers-consigno"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/s.w.org\/plugins\/geopattern-icon\/peakmaps.svg","icon_2x":false,"generated":true},"screenshots":[],"raw_content":"<!--section=description-->\n<p>Turn your list of summits, trails, and viewpoints into a beautiful, interactive map \u2014 no coding required.<\/p>\n\n<p>PeakMaps is a WordPress plugin built for hiking blogs, outdoor clubs, tourism sites, and anyone who wants to showcase peaks, trails, and points of interest on a real, interactive map. Add a searchable database of locations, complete with GPX tracks and elevation profiles \u2014 then drop it into any page or post with a Gutenberg block or shortcode.<\/p>\n\n<p>PeakMaps is <strong>completely free<\/strong>, with no peak-count cap, no expiring features, and no upgrade popups. <strong>PeakMaps Pro<\/strong> is a separate, optional add-on for sites that want Norwegian topographic maps (Kartverket), custom marker styles, extra data fields, on-map tools, GPX downloads, and bulk CSV import\/export.<\/p>\n\n<p><a href=\"https:\/\/fjellturblogg.no\/fjelltopper\">See it in action: demo table<\/a> | <a href=\"https:\/\/fjellturblogg.no\/kart\">demo map<\/a><\/p>\n\n<h4>What PeakMaps does<\/h4>\n\n<p>Add peaks to your own dedicated database, attach GPX tracks, and PeakMaps takes care of the rest: rendering them on interactive Leaflet maps, generating a sortable and filterable table, calculating elevation profiles \u2014 all without a single line of code. Place as many maps and tables as you like, anywhere on your site, each with its own filters and settings.<\/p>\n\n<h4>\ud83d\uddfa\ufe0f Interactive map<\/h4>\n\n<ul>\n<li>Built on <strong>Leaflet<\/strong> \u2014 fast, lightweight, and mobile-friendly.<\/li>\n<li><strong>Marker clustering<\/strong> keeps busy maps clean at lower zoom levels.<\/li>\n<li>Background layers: <strong>OpenStreetMap<\/strong> and <strong>OpenTopoMap<\/strong>, with an easy switcher for visitors.<\/li>\n<li><strong>Fullscreen mode<\/strong> for an immersive map view.<\/li>\n<li>Smooth touch and pinch-zoom on mobile.<\/li>\n<\/ul>\n\n<h4>\ud83c\udfd4\ufe0f GPX tracks and elevation profiles<\/h4>\n\n<ul>\n<li>Attach a GPX track to any peak and it renders on the map automatically.<\/li>\n<li><strong>Elevation profile charts<\/strong> with interactive hover tooltips \u2014 elevation and distance at any point along the track.<\/li>\n<li>Ascent\/descent totals, min\/max elevation, and total distance calculated automatically.<\/li>\n<li><strong>Secure GPX proxy<\/strong> built in \u2014 tracks hosted anywhere load smoothly without CORS issues.<\/li>\n<\/ul>\n\n<h4>\ud83d\udcca Smart, filterable table<\/h4>\n\n<ul>\n<li>Fully <strong>sortable and searchable<\/strong> \u2014 sort by name, elevation, municipality, county, visited date, and more.<\/li>\n<li><strong>Live filtering<\/strong> by municipality, county, elevation range, free-text search, and visited status \u2014 no page reload.<\/li>\n<li><strong>Pagination<\/strong> with configurable results per page.<\/li>\n<li>Optional row-number column and configurable column selection per instance.<\/li>\n<\/ul>\n\n<h4>\ud83d\uddc4\ufe0f Your own peak database<\/h4>\n\n<ul>\n<li>A dedicated, purpose-built database \u2014 not repurposed WordPress posts \u2014 for fast, clean querying at any scale, with no upper limit.<\/li>\n<li><strong>Visited\/completed tracking<\/strong> \u2014 doubles as a personal or club peak-bagging log.<\/li>\n<li>Show\/hide individual peaks without deleting their data.<\/li>\n<li>Full admin interface: search, filter, sort, bulk-edit, bulk-delete, and duplicate entries.<\/li>\n<\/ul>\n\n<h4>\ud83c\udf0d Built for real-world use<\/h4>\n\n<ul>\n<li>Works via <strong>Gutenberg blocks<\/strong> (with live editor preview) or classic <strong>shortcodes<\/strong> (<code>[peakmaps]<\/code> and <code>[peakmaps_item]<\/code>).<\/li>\n<li><strong>Norwegian Bokm\u00e5l translation<\/strong> included; standard WordPress i18n for adding more languages.<\/li>\n<li>Automatic <strong>cache clearing<\/strong> on settings changes, compatible with WP Rocket, W3 Total Cache, WP Super Cache, LiteSpeed Cache, and WP-Optimize.<\/li>\n<li>Assets load only on pages that actually contain a map or table.<\/li>\n<\/ul>\n\n<h4>PeakMaps Pro<\/h4>\n\n<p><a href=\"https:\/\/consigno.no\/peakmaps\">PeakMaps Pro<\/a> is a separate, optional add-on that extends the free plugin without removing anything from it. Pro adds:<\/p>\n\n<p><strong>\ud83c\uddf3\ud83c\uddf4 Norwegian Kartverket maps<\/strong>\nNorway's official topographic map, raster map, and nautical chart as additional background layers. When a Kartverket layer is active, Pro also refines elevation profiles against Kartverket's own terrain model for extra accuracy.<\/p>\n\n<p><strong>\ud83c\udfa8 Custom marker styles<\/strong>\nChoose from circular, square, triangular, diamond, or star markers in any colour \u2014 or upload your own custom marker image.<\/p>\n\n<p><strong>\ud83d\udcdd Five custom extra fields<\/strong>\nAdd up to five fields with labels you choose \u2014 difficulty, parking notes, permit info, or anything your project needs. Supports wildcards (<code>*<\/code>, <code>?<\/code>), exclusion (<code>!<\/code>), and numeric comparisons (<code>&gt;<\/code>, <code>&lt;<\/code>, <code>&gt;=<\/code>, <code>&lt;=<\/code>) in filters.<\/p>\n\n<p><strong>\ud83d\udee0\ufe0f On-map tools<\/strong>\nA distance-measuring tool and a \u00abfind my position\u00bb GPS button for visitors browsing on mobile.<\/p>\n\n<p><strong>\u2b07\ufe0f GPX download<\/strong>\nLet visitors download GPX files, with an optional terms\/consent dialog.<\/p>\n\n<p><strong>\ud83d\udce5 CSV import and export<\/strong>\nBulk-load or update peaks from a spreadsheet, with insert mode (add new entries) and update mode (fill in missing fields on existing ones). Export your full peak database to CSV at any time \u2014 perfect for backups or editing in Excel.<\/p>\n\n<p><a href=\"https:\/\/consigno.no\/peakmaps\">Find out more about PeakMaps Pro \u2192<\/a><\/p>\n\n<h4>Perfect for<\/h4>\n\n<ul>\n<li>Hiking and outdoor blogs documenting summits, trails, and viewpoints<\/li>\n<li>Tourism boards and destination sites showcasing regional attractions<\/li>\n<li>Hiking clubs maintaining a shared, browsable peak list<\/li>\n<li>Personal peak-bagging logs for trackers working through a summit list<\/li>\n<\/ul>\n\n<h4>External services<\/h4>\n\n<p>This plugin connects to external services to display maps, elevation profiles, and GPX tracks. Details for each service are below.<\/p>\n\n<p><strong>Map tiles (loaded directly by the visitor's browser)<\/strong><\/p>\n\n<p>When a map is shown, the visitor's browser requests map tile images (small square map images) directly from one or more of the following providers, depending on which background map is selected. Only standard tile-image requests are sent (map coordinates, zoom level, and the browser's normal request headers such as IP address and user agent) \u2014 no personal data, peak data, or site content is transmitted beyond what a normal image request contains.<\/p>\n\n<ul>\n<li><strong>OpenStreetMap<\/strong> (tile.openstreetmap.org) \u2014 open, community-maintained world map. Terms: https:\/\/operations.osmfoundation.org\/policies\/tiles\/ \u2014 Privacy: https:\/\/wiki.osmfoundation.org\/wiki\/Privacy_Policy<\/li>\n<li><strong>OpenTopoMap<\/strong> (tile.opentopomap.org) \u2014 open topographic map based on OpenStreetMap and elevation data. Terms\/usage: https:\/\/opentopomap.org\/about#verwendung<\/li>\n<\/ul>\n\n<p><strong>GPX file proxy (server-side request)<\/strong><\/p>\n\n<p>The server also fetches GPX track files, via a proxy, from the URLs stored on each peak (so the file can be shown on a map without cross-origin browser restrictions). The proxy only fetches URLs that exactly match a <code>gpx_url<\/code> already saved on a peak in this site's own database; no other URL can be requested through it. Where a GPX file is hosted determines which third party (if any) receives that request \u2014 this is set by the site owner when adding a peak, not by this plugin's own servers.<\/p>\n\n<h3>Source Code<\/h3>\n\n<p>This plugin's own frontend script, <code>assets\/js\/nu_script.js<\/code>, is shipped as a whitespace-minified build for faster loading. Its full human-readable source \u2014 same code, same behavior, just formatted \u2014 is included in this plugin at <code>assets\/src\/nu_script.js<\/code>. No bundler, transpiler, or other build step is used beyond whitespace minification; regenerating the minified file from the source is a single pass through any standard JS minifier.<\/p>\n\n<p>All other JavaScript and CSS files written for this plugin (everything under <code>assets\/js\/<\/code> and <code>assets\/css\/<\/code> not listed below) are already shipped in their normal, unminified, human-readable form \u2014 no separate source is needed for those.<\/p>\n\n<p>Bundled third-party libraries (Leaflet, Leaflet.markercluster, Leaflet.fullscreen, Leaflet.UTM, GPXParser.js) are minified as distributed upstream; each file includes a header comment with its name, license, and source repository URL.<\/p>\n\n<h3>External services<\/h3>\n\n<p>This plugin's map displays background map tiles from a small set of publicly available tile providers, selectable per-site under PeakMaps \u2192 Settings \u2192 Background maps. Each provider's tiles are only loaded when the site owner has selected that specific layer to be shown on the map \u2014 no data is sent to any of them unless a map using that layer is actually displayed to a visitor. The data sent in every case is limited to what any map-tile request needs: the visitor's browser requests image tiles for the map area currently in view (an approximate geographic tile coordinate, not the visitor's precise location), the same as loading any other embedded map.<\/p>\n\n<ul>\n<li><strong>OpenStreetMap<\/strong> \u2014 the default background map. Tiles are requested from <code>tile.openstreetmap.org<\/code>. <a href=\"https:\/\/operations.osmfoundation.org\/policies\/tiles\/\">Terms of use<\/a> \u00b7 <a href=\"https:\/\/wiki.osmfoundation.org\/wiki\/Privacy_Policy\">Privacy policy<\/a><\/li>\n<li><strong>OpenTopoMap<\/strong> \u2014 a topographic map style built on OpenStreetMap data. Tiles are requested from <code>tile.opentopomap.org<\/code>. <a href=\"https:\/\/opentopomap.org\/about\">Usage policy<\/a> \u00b7 <a href=\"https:\/\/wiki.osmfoundation.org\/wiki\/Privacy_Policy\">OpenStreetMap privacy policy<\/a> (OpenTopoMap does not publish a separate one)<\/li>\n<li><strong>Esri<\/strong> \u2014 satellite and topographic map styles. Tiles are requested from <code>server.arcgisonline.com<\/code>. <a href=\"https:\/\/www.esri.com\/en-us\/legal\/terms\/full-master-agreement\">Terms of use<\/a> \u00b7 <a href=\"https:\/\/www.esri.com\/en-us\/privacy\/overview\">Privacy policy<\/a><\/li>\n<li><strong>CARTO<\/strong> \u2014 light and dark map styles. Tiles are requested from <code>basemaps.cartocdn.com<\/code>. <a href=\"https:\/\/carto.com\/legal\/\">Terms of use<\/a> \u00b7 <a href=\"https:\/\/carto.com\/privacy\/\">Privacy policy<\/a><\/li>\n<\/ul>\n\n<!--section=installation-->\n<ol>\n<li>Upload the <code>peakmaps<\/code> folder to <code>\/wp-content\/plugins\/<\/code>, or install the ZIP via Plugins &gt; Add New &gt; Upload Plugin.<\/li>\n<li>Activate the plugin from the Plugins menu in WordPress.<\/li>\n<li>Go to PeakMaps in the admin menu to set up map defaults and add peaks.<\/li>\n<li>Add a map or table with the \"PeakMaps\" Gutenberg blocks, or the shortcodes <code>[peakmaps_map]<\/code> \/ <code>[peakmaps_table]<\/code>.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"how%20do%20i%20add%20peaks%3F\"><h3>How do I add peaks?<\/h3><\/dt>\n<dd><p>Use the \"New peak\" button under the PeakMaps menu to add peaks one at a time \u2014 name, position, GPX track, and the other details.<\/p><\/dd>\n<dt id=\"how%20do%20i%20display%20the%20map%20or%20table%3F\"><h3>How do I display the map or table?<\/h3><\/dt>\n<dd><p>Use the Gutenberg blocks, or the shortcodes <code>[peakmaps_map]<\/code> and <code>[peakmaps_table]<\/code>. Parameters are documented on the Help page in admin.<\/p><\/dd>\n<dt id=\"the%20plugin%20uses%20a%20caching%20plugin%20%E2%80%94%20why%20don%27t%20my%20changes%20show%20up%3F\"><h3>The plugin uses a caching plugin \u2014 why don't my changes show up?<\/h3><\/dt>\n<dd><p>The page cache may serve old HTML. PeakMaps clears the cache automatically when you save the map settings, but also remember to hard-refresh your browser.<\/p><\/dd>\n<dt id=\"do%20i%20have%20to%20pay%20to%20use%20peakmaps%3F\"><h3>Do I have to pay to use PeakMaps?<\/h3><\/dt>\n<dd><p>No. PeakMaps is completely free, with no locked features, limits, or license requirements.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>2.9.63<\/h4>\n\n<ul>\n<li><strong>Fixed: the elevation profile chart could render at a fixed narrow width (a thin ~100px strip) and never correct itself, mainly in Chrome\/macOS.<\/strong> The chart sizes its canvas from the container's width at the moment it's drawn; when it was first drawn before the container had a laid-out width (a hidden tab, a column not yet measured, or the browser drawing before layout settled), that width was 0 and the chart locked to a 100px fallback. It was only re-drawn on a window resize, which never happened, so it stayed wrong. A ResizeObserver now redraws the chart the moment its container gets a real width, so it appears correctly without needing the window to be resized. (If you added a site-wide script or snippet to work around this, you can remove it.)<\/li>\n<\/ul>\n\n<h4>2.9.62<\/h4>\n\n<ul>\n<li>Updated plugin description on WordPress.org with full feature overview, Pro add-on details, demo links, and map tile provider information.<\/li>\n<\/ul>\n\n<h4>2.9.61<\/h4>\n\n<ul>\n<li>Cleared the remaining Plugin Check warnings on our own custom-table queries. The <code>DESCRIBE<\/code>\/<code>SHOW INDEX<\/code>\/<code>ALTER TABLE<\/code> block in the installer is now wrapped in a single scoped <code>phpcs:disable\/enable<\/code> for <code>WordPress.DB.DirectDatabaseQuery<\/code>, and the remaining direct reads\/writes (slug checks, single-row lookups, visibility toggle, the shortcode peak lookup, and the GPX-proxy allow-list check) carry a one-line justified ignore. Added <code>PluginCheck.Security.DirectDB.UnescapedDBParameter<\/code> to the three genuinely-dynamic query ignores (the variable-length <code>WHERE<\/code> in the list\/count queries and the two-value column whitelist in the filter-options query), where every value is already bound through <code>%s<\/code>\/<code>%f<\/code>\/<code>%i<\/code> placeholders. No behavioural changes \u2014 comments only.<\/li>\n<\/ul>\n\n<h4>2.9.60<\/h4>\n\n<ul>\n<li><strong>Fixed the last \"unsafe SQL calls\" flagged in review: table names are now bound through <code>wpdb::prepare()<\/code>'s <code>%i<\/code> identifier placeholder<\/strong> (e.g. <code>$wpdb-&gt;prepare( \"SELECT * FROM %i WHERE id = %d\", $table, $id )<\/code>), instead of being validated and interpolated into the query text ourselves as a bare, backtick-quoted identifier. <code>%i<\/code> requires WordPress 6.2+, so <strong>\"Requires at least\" is now 6.2<\/strong> (previously 5.8). Every query that touched the peaks table was rewritten \u2014 install\/upgrade (<code>DESCRIBE<\/code>, <code>SHOW INDEX<\/code>, <code>ALTER TABLE<\/code>), the peak list\/count\/filter-option queries, slug uniqueness checks, single-peak lookups, bulk actions, duplication, visibility toggling, the map shortcode's peak lookup, and the GPX proxy's SSRF allow-list check. <code>PeakMaps_Database::table_sql()<\/code> (the old validate-and-quote helper) is removed; <code>PeakMaps_Database::table()<\/code> is now used directly as the <code>%i<\/code> argument everywhere.<\/li>\n<\/ul>\n\n<h4>2.9.59<\/h4>\n\n<ul>\n<li><strong>Fixed: waypoints inside a GPX file were drawn in a different colour from the rest of the map.<\/strong> They were created with a bare <code>L.marker()<\/code>, which gives them Leaflet's own default blue pin, while every other marker went through the plugin's marker function and got the configured style (the standard green pin, or whatever PeakMaps Pro is set to). A map whose GPX track contained waypoints therefore showed a mix of blue and green pins. Waypoints now go through the same marker function as everything else, so the whole map uses one consistent marker style.<\/li>\n<\/ul>\n\n<h4>2.9.58<\/h4>\n\n<ul>\n<li>Markers created with an add-on's own icon are now flagged as already styled, so the catch-up pass that exists for add-on scripts arriving late no longer re-applies an icon that is already correct. Together with the matching change in PeakMaps Pro 1.8.9 (which now loads its script before the map is drawn rather than lazily afterwards), this removes the brief flash where every marker appeared in the default green pin before switching to its configured colour.<\/li>\n<\/ul>\n\n<h4>2.9.57<\/h4>\n\n<ul>\n<li><strong>Fixed: a \"Read more\" column appeared in the peaks table without being selected.<\/strong> The Gutenberg block registered different default columns in PHP (<code>\u2026,gpx,lenke<\/code>) than in its editor script (<code>\u2026,gpx<\/code>) \u2014 which Gutenberg requires to match \u2014 so the block rendered a column the editor never showed as checked. The <code>[peakmaps_table]<\/code> shortcode had the same default. All three now agree, and <code>link<\/code> is <strong>off by default<\/strong>: the Name column already links to the peak, so a separate \"Read more\" column only duplicated that link. It is now an explicit, opt-in choice \u2014 selectable in the block's Columns panel (where it previously wasn't offered at all) or via <code>columns=\"\u2026,link\"<\/code> in the shortcode.<\/li>\n<\/ul>\n\n<p>For versions before 2.9.57, see CHANGELOG.md in the plugin's files (this section is trimmed to stay under WordPress.org's 5000-character readme changelog limit).<\/p>","raw_excerpt":"Leaflet map with GPX tracks, markers, elevation profile, and its own filterable peak database with table and Gutenberg blocks.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/335738","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=335738"}],"author":[{"embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/consigno"}],"wp:attachment":[{"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=335738"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=335738"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=335738"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=335738"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=335738"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/de.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=335738"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}