'Version'), 'plugin'); $version = isset($header['Version']) && $header['Version'] ? $header['Version'] : null; } return $version; } // Append a cache busting query argument to a bundled asset URL. Every bundled // asset (vendored or not) shares the plugin's Version header, so bumping that // header on release is what invalidates caches -- including for vendored // files (e.g. a new MapLibre or OpenFreeMap style release) that don't carry // their own version number. function openfreemap_versioned_url($relative_path) { $url = plugin_dir_url(__FILE__) . $relative_path; $version = openfreemap_plugin_version(); return $version ? add_query_arg('ver', $version, $url) : $url; } // URL of a bundled OpenFreeMap style, versioned like every other shipped asset function openfreemap_style_url($style) { return openfreemap_versioned_url('vendor/openfreemap/styles/' . sanitize_key($style)); } // Styles bundled under vendor/openfreemap/styles/. Kept as an explicit allow-list // so the shortcode can't be used to probe for arbitrary files on disk. function openfreemap_available_styles() { return array('bright', 'dark', 'fiord', 'liberty', 'positron'); } // Restrict the shortcode's style attribute to a known, bundled style function openfreemap_sanitize_style($value, $default) { $value = sanitize_key($value); if (in_array($value, openfreemap_available_styles(), true)) { return $value; } return $default; } // Register the shortcode function openfreemap_handler($atts) { $atts = shortcode_atts(array( 'lat' => '47.1092664', 'lon' => '12.3453356', 'popup_text' => '', 'color' => '#ff0000', 'height' => '450px', 'zoom' => '16.5', 'style' => 'bright' ), $atts, 'openfreemap'); $lat = openfreemap_clamp_float($atts['lat'], 47.1092664, -90, 90); $lon = openfreemap_clamp_float($atts['lon'], 12.3453356, -180, 180); $zoom = openfreemap_clamp_float($atts['zoom'], 16.5, 0, 22); $color = sanitize_hex_color($atts['color']); if (!$color) { $color = '#ff0000'; } $height = openfreemap_sanitize_css_length($atts['height'], '450px'); $popup_text = wp_kses_post($atts['popup_text']); $style = openfreemap_sanitize_style($atts['style'], 'bright'); $map_id = wp_unique_id('openfreemap-'); ob_start(); ?>
post_content, 'openfreemap') && !has_block('core/shortcode', $post)) { return; } } $enqueued = true; // The loader is a classic script: it conditionally dynamic-imports the ES // module below and injects the stylesheet, so both the ~1 MB of MapLibre JS // and its CSS are only fetched on pages that actually render a map. // Detection happens in the DOM rather than in post content, which also // covers widgets, blocks, template parts and secondary loops. The // is_singular() check above is just a cheap best-effort early exit that // skips even the tiny loader request on obviously map-free singular pages; // it is not relied on for correctness. wp_enqueue_script( 'openfreemap-loader', plugin_dir_url(__FILE__) . 'assets/loader.js', array(), openfreemap_plugin_version(), true ); $module_url = openfreemap_versioned_url('assets/openfreemap.js'); $style_href = openfreemap_versioned_url('vendor/maplibre-gl/maplibre-gl.css'); // JSON_HEX_TAG keeps the values from terminating the inline script early. wp_add_inline_script( 'openfreemap-loader', 'var openfreemapModuleUrl = ' . wp_json_encode($module_url, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES) . ';' . 'var openfreemapStyleUrl = ' . wp_json_encode($style_href, JSON_HEX_TAG | JSON_UNESCAPED_SLASHES) . ';', 'before' ); } add_action('wp_enqueue_scripts', 'openfreemap_enqueue_assets');