Как передать метку на карту по координатам из админки?
Сделал страницу настроек в адмике Wordpress.
add_action( 'admin_menu', 'filter_map_menu_page', 25 ); function filter_map_menu_page() { add_menu_page( 'Настройки карты', // тайтл страницы 'Настройки карты', // текст ссылки в меню 'manage_options', // права пользователя, необходимые для доступа к странице 'true_filter', // ярлык страницы 'true_filter_map_callback', // функция, которая выводит содержимое страницы 'dashicons-images-alt2', // иконка, в данном случае из Dashicons 4.3 // позиция в меню ); } // Регистрация настроек add_action( 'admin_init', 'true_filter_settings_init' ); function true_filter_settings_init() { register_setting( 'true_filter_settings', 'latitude_option' ); register_setting( 'true_filter_settings', 'longitude_option' ); add_settings_section( 'true_filter_section', '', 'true_filter_section_callback', 'true_filter' ); add_settings_field( 'latitude_field', 'Широта', 'latitude_field_callback', 'true_filter', 'true_filter_section' ); add_settings_field( 'longitude_field', 'Долгота', 'longitude_field_callback', 'true_filter', 'true_filter_section' ); } function true_filter_section_callback() { // echo '<p>Описание секции</p>'; } function latitude_field_callback() { $latitude = get_option( 'latitude_option' ); echo '<input type="text" name="latitude_option" value="' . esc_attr( $latitude ) . '" />'; } function longitude_field_callback() { $longitude = get_option( 'longitude_option' ); echo '<input type="text" name="longitude_option" value="' . esc_attr( $longitude ) . '" />'; } function true_filter_map_callback() { echo '<div class="wrap"> <h1>' . get_admin_page_title() . '</h1> <form method="post" action="options.php">'; settings_fields( 'true_filter_settings' ); // название настроек do_settings_sections( 'true_filter' ); // ярлык страницы, не более submit_button(); // функция для вывода кнопки сохранения echo '</form>'; } // Добавляем уведомление при сохранении настроек add_action( 'admin_notices', 'true_filter_settings_notice' ); function true_filter_settings_notice() { settings_errors(); } |
add_action( 'admin_menu', 'filter_map_menu_page', 25 ); function filter_map_menu_page() { add_menu_page( 'Настройки карты', // тайтл страницы 'Настройки карты', // текст ссылки в меню 'manage_options', // права пользователя, необходимые для доступа к странице 'true_filter', // ярлык страницы 'true_filter_map_callback', // функция, которая выводит содержимое страницы 'dashicons-images-alt2', // иконка, в данном случае из Dashicons 4.3 // позиция в меню ); } // Регистрация настроек add_action( 'admin_init', 'true_filter_settings_init' ); function true_filter_settings_init() { register_setting( 'true_filter_settings', 'latitude_option' ); register_setting( 'true_filter_settings', 'longitude_option' ); add_settings_section( 'true_filter_section', '', 'true_filter_section_callback', 'true_filter' ); add_settings_field( 'latitude_field', 'Широта', 'latitude_field_callback', 'true_filter', 'true_filter_section' ); add_settings_field( 'longitude_field', 'Долгота', 'longitude_field_callback', 'true_filter', 'true_filter_section' ); } function true_filter_section_callback() { // echo '<p>Описание секции</p>'; } function latitude_field_callback() { $latitude = get_option( 'latitude_option' ); echo '<input type="text" name="latitude_option" value="' . esc_attr( $latitude ) . '" />'; } function longitude_field_callback() { $longitude = get_option( 'longitude_option' ); echo '<input type="text" name="longitude_option" value="' . esc_attr( $longitude ) . '" />'; } function true_filter_map_callback() { echo '<div class="wrap"> <h1>' . get_admin_page_title() . '</h1> <form method="post" action="options.php">'; settings_fields( 'true_filter_settings' ); // название настроек do_settings_sections( 'true_filter' ); // ярлык страницы, не более submit_button(); // функция для вывода кнопки сохранения echo '</form>'; } // Добавляем уведомление при сохранении настроек add_action( 'admin_notices', 'true_filter_settings_notice' ); function true_filter_settings_notice() { settings_errors(); }
Как передать метку на карту из широты и долготы указанных в этих настройках?
Дополнительно:
Создать карту, добавить на неё метку по координатам. Вы справку то по яндексу открывали?
если поля с координатами передавайте его на фронт в json
а в js расставлять метки согласно полученному массиву.
$latitude = get_option( 'latitude_option' );
Вот так и получают опции из настроек.
А вот так вставляют в html (написано в том же коде):
echo '<input type="text" name="latitude_option" value="' . esc_attr( $latitude ) . '" />'; |
echo '<input type="text" name="latitude_option" value="' . esc_attr( $latitude ) . '" />';
Делаете аналогично, но не с input, а с кодом вставки карты.
В js не передаётся значение поля.
Чего это?
<script> var latitude = '<?php echo get_option( 'latitude_option' ); ?>'; alert(latitude); </script> |
<script> var latitude = '<?php echo get_option( 'latitude_option' ); ?>'; alert(latitude); </script>
Вставьте этот код в шаблон и посмотрите.
p.s. Значение опции не должно содержать апострофов и переводов строки. Если содержит, нужно дополнительно фильтровать значение.
При желании можно и .js (в смысле отдельный файл) сдать на обработку php, используя AddHandler и хедер Content-type, но тогда к нему надо еще и wp-load.php подключать. Оно того не стоит. Прокинуть переменную из шаблона в скрипт проще.
Ответы:
Тоже решал подобную проблему, в итоге решил собирать весь скрипт на php. Сначала собираю обычный массив, как в документации object_manager
$mask = array(); $mask['type'] = 'FeatureCollection'; foreach ( $resorts as $key => $resort ) { $geo_point = get_post_meta( $resort->ID, '_geo_location', true ); $geo_point = explode( ',', $geo_point ); // Собираем php массив для карты, который энкодим в json формат $mask['features'][] = array( 'type' => 'Feature', 'id' => $key, 'geometry' => array ( 'type' => 'Point', 'coordinates' => [(float) trim($geo_point[0]), (float) trim($geo_point[1])], ), 'properties' => array ( 'balloonContentBody' => '<strong class="balloon-title"><a class="link" href="' . esc_url( get_the_permalink( $resort->ID ) ) . '" target="_blank">' . $resort->post_title . '</a></strong>', 'clusterCaption' => '<strong>' . $resort->post_title . '</strong>', 'hintContent' => '<strong>' . $resort->post_title . '</strong>' ) ); } |
$mask = array(); $mask['type'] = 'FeatureCollection'; foreach ( $resorts as $key => $resort ) { $geo_point = get_post_meta( $resort->ID, '_geo_location', true ); $geo_point = explode( ',', $geo_point ); // Собираем php массив для карты, который энкодим в json формат $mask['features'][] = array( 'type' => 'Feature', 'id' => $key, 'geometry' => array ( 'type' => 'Point', 'coordinates' => [(float) trim($geo_point[0]), (float) trim($geo_point[1])], ), 'properties' => array ( 'balloonContentBody' => '<strong class="balloon-title"><a class="link" href="' . esc_url( get_the_permalink( $resort->ID ) ) . '" target="_blank">' . $resort->post_title . '</a></strong>', 'clusterCaption' => '<strong>' . $resort->post_title . '</strong>', 'hintContent' => '<strong>' . $resort->post_title . '</strong>' ) ); }
С помощью json_encode() и wp_add_inline_script() вставляю все во фронт
$frontend_scripts = "<script type='text/javascript'> jQuery(function($){ ymaps.ready(init); function init () { var map = new ymaps.Map('ya-map', { center: [55.76, 37.64], zoom: 4, controls: ['geolocationControl' ,'zoomControl'], }, { avoidFractionalZoom: false, }); map.behaviors.disable("scrollZoom"); var objectManager = new ymaps.ObjectManager({ clusterize: true, gridSize: 32, clusterDisableClickZoom: true }); objectManager.objects.options.set( 'preset', 'islands#greenCircleDotIcon' ); objectManager.clusters.options.set( 'preset', 'islands#greenClusterIcons' ); map.geoObjects.add(objectManager); var pointLabels = " . json_encode( $mask ) . "; objectManager.add(pointLabels); // эта костыльная хуйня центрирует карту и делает автозум, чтобы попали все точки var geoObjects = ymaps.geoQuery(pointLabels) .applyBoundsToMap(map, { checkZoomRange: true }); } }); </script>"; wp_add_inline_script( 'main', minify_js( $frontend_scripts ) ); |
$frontend_scripts = "<script type='text/javascript'> jQuery(function($){ ymaps.ready(init); function init () { var map = new ymaps.Map('ya-map', { center: [55.76, 37.64], zoom: 4, controls: ['geolocationControl' ,'zoomControl'], }, { avoidFractionalZoom: false, }); map.behaviors.disable("scrollZoom"); var objectManager = new ymaps.ObjectManager({ clusterize: true, gridSize: 32, clusterDisableClickZoom: true }); objectManager.objects.options.set( 'preset', 'islands#greenCircleDotIcon' ); objectManager.clusters.options.set( 'preset', 'islands#greenClusterIcons' ); map.geoObjects.add(objectManager); var pointLabels = " . json_encode( $mask ) . "; objectManager.add(pointLabels); // эта костыльная хуйня центрирует карту и делает автозум, чтобы попали все точки var geoObjects = ymaps.geoQuery(pointLabels) .applyBoundsToMap(map, { checkZoomRange: true }); } }); </script>"; wp_add_inline_script( 'main', minify_js( $frontend_scripts ) );
- Это добавление через json инфу, а к странице настройки как прикрутить, чтобы в админку зашёл и накидал меток по координатам какие нужны на карту?
- Nik Master, разве ваш код не решает как раз эту задачу?
- Артем Золин, Я бы не спрашивал, если бы работало.) Не передаются значения полей.
-
Не передаются значения
А они в админке сохраняются?
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Координаты из страницы настроек WordPress нужно передавать в JavaScript не через ручную вставку строк в HTML, а через
wp_localize_script()илиwp_add_inline_script(). Тогда данные будут доступны карте как объект, и вы избежите проблем с кавычками, запятыми и экранированием.Сначала зарегистрируйте и подключите ваш JS-файл:
add_action('wp_enqueue_scripts', function () { wp_enqueue_script( 'site-map', get_template_directory_uri() . '/assets/js/map.js', [], '1.0.0', true ); wp_localize_script('site-map', 'SiteMapData', [ 'lat' => (float) get_option('latitude_option'), 'lng' => (float) get_option('longitude_option'), ]); });
В файле
map.jsиспользуйте эти значения:document.addEventListener('DOMContentLoaded', function () { const lat = Number(SiteMapData.lat); const lng = Number(SiteMapData.lng); if (!lat || !lng) { return; } // пример для карты const coords = [lat, lng]; console.log(coords); });document.addEventListener('DOMContentLoaded', function () { const lat = Number(SiteMapData.lat); const lng = Number(SiteMapData.lng); if (!lat || !lng) { return; } // пример для карты const coords = [lat, lng]; console.log(coords); });
Если координаты задаются в админке через Settings API, обязательно валидируйте их при сохранении:
register_setting('true_filter_settings', 'latitude_option', [ 'sanitize_callback' => 'floatval', ]); register_setting('true_filter_settings', 'longitude_option', [ 'sanitize_callback' => 'floatval', ]);
Если меток несколько, храните не две отдельные опции, а массив точек или CPT “Объекты на карте”. Для одной метки двух options достаточно. После сохранения проверьте исходный код страницы: объект
SiteMapDataдолжен содержать актуальные координаты.Не выводите координаты напрямую в JS без проверки, особенно если они сохраняются из админской формы. Даже администратор может случайно вставить запятую вместо точки или лишний текст. На фронте всегда приводите значения к числу и проверяйте диапазон: широта от -90 до 90, долгота от -180 до 180. Если данные невалидны, карту лучше не инициализировать, чем показывать ошибку JavaScript всем посетителям.