/ Сайтостроение / Scripts & jquery / Посты — метки на карте

Посты — метки на карте

11.08.2018

232


Deprecated: Function create_function() is deprecated in /home/htvtwmhs/public_html/wp-content/plugins/wp-spamshield/wp-spamshield.php on line 2033

Пытаясь реализовать удобный функционал по созданию меток на интерактивной карте я пришел к следующей системе. Заводим произвольный тип записи и таксономии чтобы структурировать и удобно манипулировать городами и точками.

Основа

В основе решения находиться плагин Oi Yandex.Maps for WordPress (хотя я использую его только частично), который в свою очередь основан на Яндекс Api. т.е. плагин необходимо установить.

Создаем пользовательский тип записи city (название не вполне соответствует, т.к. это будут точки. конкретное место в городе):

// Добавляем произвольный тип записей
add_action( 'init', 'register_post_type_city' ); // Использовать функцию только внутри хука init
function register_post_type_city() {
	$labels = array(
	    'name' => 'Где купить',
	    'singular_name' => 'City', // админ панель Добавить->Функцию
		'add_new' => 'Добавить точку',
		'add_new_item' => 'Добавить новую точку', // заголовок тега <title>
		'edit_item' => 'Редактировать точку',
		'new_item' => 'Новая точка',
		'all_items' => 'Все точки',
		'view_item' => 'Просмотр страницы точки на сайте',
		'search_items' => 'Искать точку',
		'not_found' =>  'Точка не найдена.',
		'not_found_in_trash' => 'В корзине нет точки.',
		'menu_name' => 'Где купить' // ссылка в меню в админке
	);
	$args = array(
		'labels' => $labels,
		'public' => true,
		'show_ui' => true, // показывать интерфейс в админке
		'has_archive' => true, // показывать страницу архива данного типа записей
		'menu_icon' => 'dashicons-location-alt', // иконка dashicons в меню
		'menu_position' => 20, // порядок в меню
		'supports' => array( 'title', 'editor', 'comments', 'author', 'thumbnail'),
	    //'taxonomies' => array('cities') // добавляем поддержку стандартных таксономий 'post_tag', 'category', либо пользовательскую 'album' (через запятую)
	);
	register_post_type('city', $args);
}


// Тексты уведомлений для типа постов
add_filter( 'post_updated_messages', 'true_post_type_messages_city' );
function true_post_type_messages_city( $messages ) {
	global $post, $post_ID;
	$messages['city'] = array( // city - название созданного нами типа записей
		0 => '', // Данный индекс не используется.
		1 => sprintf( 'Точка обновлена. Просмотр', esc_url( get_permalink($post_ID) ) ),
		2 => 'Точка обновлёна.',
		3 => 'Точка удалёна.',
		4 => 'Точка обновлена.',
		5 => isset($_GET['revision']) ? sprintf( 'Точка восстановлена из редакции: %s', wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
		6 => sprintf( 'Точка опубликована на сайте. Просмотр', esc_url( get_permalink($post_ID) ) ),
		7 => 'Точка сохранена.',
		8 => sprintf( 'Отправлена на проверку. Просмотр', esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
		9 => sprintf( 'Запланирована на публикацию: %1$s. Просмотр', date_i18n( __( 'M j, Y @ G:i' ), strtotime( $post->post_date ) ), esc_url( get_permalink($post_ID) ) ),
		10 => sprintf( 'Черновик обновлён. Просмотр', esc_url( add_query_arg( 'preview', 'true', get_permalink($post_ID) ) ) ),
	);
	return $messages;
}


// Произвольные поля для пользовательского типа записей
function true_custom_fields_city() {
add_post_type_support( 'city', 'custom-fields'); // в качестве первого параметра укажите название типа поста
}
add_action('init', 'true_custom_fields_city');

Создаем пользовательскую таксономию (элементами этой таксономии будут города)

// Пользовательская таксономия Город
function add_new_taxonomies() {
	register_taxonomy('cities', // создаем функцию с произвольным именем и вставляем в неё register_taxonomy()
		array('city'),
		array(
			'hierarchical' => false, // true - по типу рубрик, false - по типу меток, по умолчанию - false 
			'labels' => array(
				/* ярлыки, нужные при создании UI, можете не писать ничего, тогда будут использованы ярлыки по умолчанию */
				'name' => 'Город',
				'singular_name' => 'City',
				'search_items' => 'Найти город',
				'popular_items' => 'Популярные города',
				'all_items' => 'Все города',
				'parent_item' => null,
				'parent_item_colon' => null,
				'edit_item' => 'Редактировать город',
				'update_item' => 'Обновить город',
				'add_new_item' => 'Добавить новый город',
				'new_item_name' => 'Название нового города',
				'separate_items_with_commas' => 'Разделяйте города запятыми',
				'add_or_remove_items' => 'Добавить или удалить город',
				'choose_from_most_used' => 'Выбрать из наиболее часто используемых городов',
				'menu_name' => 'Города'
			),
		'public' => true, // каждый может использовать таксономию, либо только администраторы, по умолчанию - true
		'show_in_nav_menus' => true, // добавить на страницу создания меню
		'show_ui' => true, // добавить интерфейс создания и редактирования
		'show_tagcloud' => true, // нужно ли разрешить облако тегов для этой таксономии
		'update_count_callback' => '_update_post_term_count', // callback-функция для обновления счетчика $object_type
		'query_var' => true, // разрешено ли использование query_var, также можно указать строку, которая будет использоваться в качестве него, по умолчанию - имя таксономии
		'rewrite' => array(		// настройки URL пермалинков
			'slug' => 'cities', // ярлык
			'hierarchical' => false // разрешить вложенность
		),
		)
	);
}
add_action( 'init', 'add_new_taxonomies', 0 );

Города точкам назначать будем как метки.

Произвольные поля

Задаем для записей типа city поля Координаты точки, Название точки, Контакты точки:

// Поле Координаты точки
add_action('add_meta_boxes', 'coordinati_tochka_box');
function coordinati_tochka_box() { add_meta_box('material_box', 'Координаты', 'coordinati_tochka_box_func', 'city', 'normal'); }
function coordinati_tochka_box_func($post){
	$coordinati_tochka = get_post_meta($post->ID, 'coordinati_tochka', 1);
	?>
	<label><input style="width:100%;" type="text" name="extra[coordinati_tochka]" value="<?php if($coordinati_tochka){echo $coordinati_tochka;}?>" /></label>
	<input type="hidden" name="atb_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
	<?php
}

add_action('save_post', 'coordinati_tochka_box_update');
function coordinati_tochka_box_update($post_id){
	if (!wp_verify_nonce($_POST['atb_nonce'], __FILE__)) return false; // Проверка, что сохраняется именно нужная нам страница.
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return false; // Проверка, что это не автосохранение
	if (!current_user_can('edit_post', $post_id)) return false; // Проверка, что пользователь может изменять этот пост
	if(!isset($_POST['extra']) ) return false;    // Проверка, что нам пришли все поля
	foreach($_POST['extra'] as $key=>$value){ // Циклом добавляем поля. Можно и в ручную это делать... Но так проще добавить новое поле
	if(empty($value) AND $value != 0){ // Если значение пустое и не равно 0
		delete_post_meta($post_id, $key); // Удаляем это поле из мета-данных
		continue; // Продолжаем
	}
	update_post_meta($post_id, $key, $value); // Обновляем или добавляем мета-данные
	}
	return $post_id;
}



// Поле Название точки
add_action('add_meta_boxes', 'name_tochka_box');
function name_tochka_box() { add_meta_box('material_box_2', 'Название точки', 'name_tochka_box_func', 'city', 'normal'); }
function name_tochka_box_func($post){
	$name_tochka = get_post_meta($post->ID, 'name_tochka', 1);
	?>
	<label><input style="width:100%;" type="text" name="extra[name_tochka]" value="<?php if($name_tochka){echo $name_tochka;}?>" /></label>
	<input type="hidden" name="atb_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
	<?php
}

add_action('save_post', 'name_tochka_box_update');
function name_tochka_box_update($post_id){
	if (!wp_verify_nonce($_POST['atb_nonce'], __FILE__)) return false; // Проверка, что сохраняется именно нужная нам страница.
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return false; // Проверка, что это не автосохранение
	if (!current_user_can('edit_post', $post_id)) return false; // Проверка, что пользователь может изменять этот пост
	if(!isset($_POST['extra']) ) return false;    // Проверка, что нам пришли все поля
	foreach($_POST['extra'] as $key=>$value){ // Циклом добавляем поля. Можно и в ручную это делать... Но так проще добавить новое поле
	if(empty($value) AND $value != 0){ // Если значение пустое и не равно 0
		delete_post_meta($post_id, $key); // Удаляем это поле из мета-данных
		continue; // Продолжаем
	}
	update_post_meta($post_id, $key, $value); // Обновляем или добавляем мета-данные
	}
	return $post_id;
}



// Поле Контакты точки
add_action('add_meta_boxes', 'contacts_tochka_box');
function contacts_tochka_box() { add_meta_box('material_box_3', 'Контакты точки', 'contacts_tochka_box_func', 'city', 'normal'); }
function contacts_tochka_box_func($post){
	$contacts_tochka = get_post_meta($post->ID, 'contacts_tochka', 1);
	?>
	<label><input style="width:100%;" type="text" name="extra[contacts_tochka]" value="<?php if($contacts_tochka){echo $contacts_tochka;}?>" /></label>
	<input type="hidden" name="atb_nonce" value="<?php echo wp_create_nonce(__FILE__); ?>" />
	<?php
}

add_action('save_post', 'contacts_tochka_box_update');
function contacts_tochka_box_update($post_id){
	if (!wp_verify_nonce($_POST['atb_nonce'], __FILE__)) return false; // Проверка, что сохраняется именно нужная нам страница.
	if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) return false; // Проверка, что это не автосохранение
	if (!current_user_can('edit_post', $post_id)) return false; // Проверка, что пользователь может изменять этот пост
	if(!isset($_POST['extra']) ) return false;    // Проверка, что нам пришли все поля
	foreach($_POST['extra'] as $key=>$value){ // Циклом добавляем поля. Можно и в ручную это делать... Но так проще добавить новое поле
	if(empty($value) AND $value != 0){ // Если значение пустое и не равно 0
		delete_post_meta($post_id, $key); // Удаляем это поле из мета-данных
		continue; // Продолжаем
	}
	update_post_meta($post_id, $key, $value); // Обновляем или добавляем мета-данные
	}
	return $post_id;
}

В последствии в поле Координаты точки мы будем прописывать реальные координаты точки, беря их из карт Яндекс. Поля Название точки и Контакты точки нужны для сопроводительного текста при нажатии на точку, или если точки выводить в виде списка.

Зададим произвольное поле и для таксономии с городами:

// Создание метаполя Координаты для города
function pippin_taxonomy_add_new_meta_field() { // this will add the custom meta field to the add new term page
	?>
	<div class="form-field">
	<label for="term_meta[custom_term_meta]"><?php _e( 'Example meta field', 'pippin' ); ?></label>
	<input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="">
	<p class="description"><?php _e( 'Enter a value for this field','pippin' ); ?></p>
	</div>
	<?php
}
add_action( 'cities_add_form_fields', 'pippin_taxonomy_add_new_meta_field', 10, 2 );


// Редактирование мета поля
function pippin_taxonomy_edit_meta_field($term) {
	$t_id = $term->term_id;  // put the term ID into a variable
	$term_meta = get_option( "taxonomy_$t_id" ); // retrieve the existing value(s) for this meta field. This returns an array
	?> 
	<tr class="form-field">
	<th scope="row" valign="top"><label for="term_meta[custom_term_meta]"><?php _e( 'Example meta field', 'pippin' ); ?></label></th>
	<td>
	<input type="text" name="term_meta[custom_term_meta]" id="term_meta[custom_term_meta]" value="<?php echo esc_attr( $term_meta['custom_term_meta'] ) ? esc_attr( $term_meta['custom_term_meta'] ) : ''; ?>">
	<p class="description"><?php _e( 'Enter a value for this field','pippin' ); ?></p>
	</td>
	</tr>
	<?php
}
add_action( 'cities_edit_form_fields', 'pippin_taxonomy_edit_meta_field', 10, 2 );


// Сохранение метаполя
function save_taxonomy_custom_meta( $term_id ) {
	if ( isset( $_POST['term_meta'] ) ) {
		$t_id = $term_id;
		$term_meta = get_option( "taxonomy_$t_id" );
		$cat_keys = array_keys( $_POST['term_meta'] );
		foreach ( $cat_keys as $key ) {
			if ( isset ( $_POST['term_meta'][$key] ) ) { $term_meta[$key] = $_POST['term_meta'][$key]; }
		}
		update_option( "taxonomy_$t_id", $term_meta ); // Save the option array.
	}
}
add_action( 'edited_cities', 'save_taxonomy_custom_meta', 10, 2 );
add_action( 'create_cities', 'save_taxonomy_custom_meta', 10, 2 );

Это поле нужно чтобы вписывать координаты городов, которые придется предварительно уточнять в Яндекс картах.

Найти способ генерации координатов налету по адресу точки или города

Шаблоны вывода

Шаблон archive-city.php — здесь будем выводить список всех городов, причем размечая их по алфавиту. Для меню шаблон доступен по ссылке /city/

<?php $terms = get_terms( 'cities'); ?>

<script type="text/javascript" src="https://api-maps.yandex.ru/2.1/?lang=ru_RU"></script>
<style>.YMaps {position: relative;} .YMaps .oi_yamaps_author_link {position: absolute;bottom: 9px; right:330px; z-index: 999;padding:0;display: table!important;line-height:12px;text-decoration:underline!important;white-space: nowrap!important;font-family: Verdana,serif!important;font-size: 10px!important;padding-left: 2px!important;color: #000!important;background-color: rgba(255, 255, 255, 0.7)!important;border:none;}</style>
<div id="YMaps_0" class="YMaps" style="width:100%;height:720px;"><a class="oi_yamaps_author_link" target="_blank" href="https://oiplug.com/">OiYM</a></div>
<script type="text/javascript">
	ymaps.ready(init);
	function init () {
		var myMap = new ymaps.Map("YMaps_0", {
			center: [47.413167,40.532044],
			zoom: 7
		});
		myMap.controls.add("routeEditor");
		
		<?php foreach( $terms as $term ): ?>
		<?php $term_meta = get_option( "taxonomy_$term->term_id" ); 
		$term_link = get_term_link($term->term_id, 'cities'); ?>
			myPlacemark_1 = new ymaps.Placemark([<?php echo esc_attr( $term_meta['custom_term_meta'] ) ? esc_attr( $term_meta['custom_term_meta'] ) : ''; ?>], 
			{balloonContentHeader: "<a href='<?php echo $term_link; ?>'><?php echo $term->name; ?></a>",},
			{preset: "islands#redDotIcon"}
			);
			myMap.geoObjects.add(myPlacemark_1);
		<?php endforeach; ?>
	}
</script>

<h1 id="title"><i class="fa fa-map-marker" aria-hidden="true"></i> Где купить</h1> 

<div id="all-city">
	<?php global $query_string;
	parse_str($query_string, $args);  // добавляем базовые параметры в массив $args
	$args['posts_per_page'] = -1;  // добавляем/заменяем параметр в массиве
	query_posts( $args ); ?>  

	<?php echo '<div class="city-letter">'; 
	foreach( $terms as $k => $term ){
		$fl = get_first_letter( $term->name );  // первая буква
		$prev_fl = isset( $terms[ ($k-1) ] ) ? get_first_letter( $terms[ ($k-1) ]->name ) : '';
		if( $prev_fl !== $fl ) 
		echo '</div><div class="city-letter"><h3>'.$fl.'</h3>'; // Буква
		printf ( '<a href="%s">%s</a><br>' , get_term_link($term->term_id, 'cities'), $term->name ); // Выводим название записи в виде ссылки на неё
	}
	echo '</div>';
	wp_reset_postdata(); ?>

	<?php // Функция возвращает первую букву переданного в неё слова
	function get_first_letter( $str ){ return mb_substr($str, 0, 1, 'utf-8'); } ?>  
</div>

Выглядеть это должно примерно так:

Шаблон taxonomy-cities.php будет выводить элементы пользовательской таксономии (отдельный город с точками)

<?php $term_slug = get_query_var( 'cities' ); 
$term = get_term_by('slug', $term_slug, 'cities'); 
$term_meta = get_option( "taxonomy_$term->term_id" ); ?>

<script type="text/javascript" src="https://api-maps.yandex.ru/2.1/?lang=ru_RU"></script>
<style>.YMaps {position: relative;} .YMaps .oi_yamaps_author_link {position: absolute;bottom: 9px; right:330px; z-index: 999;padding:0;display: table!important;line-height:12px;text-decoration:underline!important;white-space: nowrap!important;font-family: Verdana,serif!important;font-size: 10px!important;padding-left: 2px!important;color: #000!important;background-color: rgba(255, 255, 255, 0.7)!important;border:none;}</style>
<div id="YMaps_0" class="YMaps" style="width:100%;height:650px;"><a class="oi_yamaps_author_link" target="_blank" href="https://oiplug.com/">OiYM</a></div>
<script type="text/javascript">
	ymaps.ready(init);
	function init () {
		var myMap = new ymaps.Map("YMaps_0", {
			center: [<?php echo esc_attr( $term_meta['custom_term_meta'] ) ? esc_attr( $term_meta['custom_term_meta'] ) : ''; ?>], //найти какая функция отвечает за определение центра, а пока сделать полем
			zoom: 11
		});
		myMap.controls.add("routeEditor");
		
		<?php if ( have_posts() ) : ?>
		<?php while ( have_posts() ) : the_post(); ?>	
			myPlacemark_1 = new ymaps.Placemark([<?php echo get_post_meta($post->ID, 'coordinati_tochka', 1); ?>], //научиться налету конвертировать координаты
			{balloonContentHeader: "<?php echo get_post_meta($post->ID, 'name_tochka', 1); ?>",
			balloonContentBody: "<?php echo get_post_meta($post->ID, 'contacts_tochka', 1); ?>"},
			{preset: "islands#redDotIcon"}
			);
			myMap.geoObjects.add(myPlacemark_1);
		<?php endwhile; ?>
		<?php endif; ?>
	}
</script>

<h1 id="title"><?php echo $term->name; ?></h1>


<?php if ( have_posts() ) : ?><ul>	
<?php while ( have_posts() ) : the_post(); ?>
					
	<li><strong><?php echo get_post_meta($post->ID, 'name_tochka', 1); ?></strong> <?php the_title(); ?> <?php echo get_post_meta($post->ID, 'contacts_tochka', 1); ?></li>
  
<?php endwhile; ?></ul>
<?php endif; ?>

В этом шаблоне мне пришлось оказаться от хлебных крошек от Kama (получалась несуразица) и прописать свои:

<div id="path"><div class="kama_breadcrumbs" itemscope="" itemtype="http://schema.org/BreadcrumbList">
<span itemprop="itemListElement" itemscope="" itemtype="http://schema.org/ListItem"><a href="https://birsmix.ru" itemprop="item"><span itemprop="name">Главная</span></a></span> / 
<a href="/city/" itemprop="item"><span itemprop="name">Где купить</span></a> / <span class="current"><?php echo $term->name; ?></span></div>
</div>

В итоге должно получиться примерно так:

Тэги:

Поделится информацией с друзьями

  • Похожие записи
  • Комментарии
  • Вложения
API Яндекс.Карт

API Яндекс.Карт

Если нам нужно кастомизировать карту Яндекс, то будет не достаточно подключить ее через iframe, т.к. в нем не будет никаких настроек. Необходимо подключить API Яндекс.Карт Подключаем API Яндекс.Карт На данный Читать далее »

Карта на сайт

Карта на сайт

Для добавления интерактивной карты в раздел контакты, нужно поместить в страницу или шаблон сгенерированный код Yandex карты, Google Map, или 2GIS. На данной странице я собрал популярные решения по добавлению Читать далее »

Записи-метки на картах

Записи-метки на картах


Deprecated: Function create_function() is deprecated in /home/htvtwmhs/public_html/wp-content/plugins/wp-spamshield/wp-spamshield.php on line 2033

Сделаем функционал привязки записи (любого типа) к картам Google или Yandex. Это может быть востребовано для контактов дилерских центров, филиалов и т.п. Это статья является как бы вступительной теоретической. Более Читать далее »

Добавить комментарий

Пока нет комментариев. Будь первым!

Посты — метки на карте Посты — метки на карте Посты — метки на карте
Аккордеон jquery
Рекомендации для васАккордеон jqueryOpttour.ru
Спасибо! Наш менеджер свяжется с Вами в течении 5 минут.