Движок WordPress, благодаря своей открытости и популярности, сравнительно просто настраивается и расширяется. В третьей его версии появилась возможность ввода дополнительных полей для каждой записи. Причем сделано это весьма удобно: создав однажды новое поле для каких-нибудь сведений, в дальнейшем можно будет просто выбирать его из соответствующего списка. Для обсуждаемой здесь задачи определим поле latlng и будем заносить в него координаты (широту и долготу) географических объектов. Помимо того, напишем несложную веб-программу, объединяющую записи блога и карты Google. Впрочем, аналогичный функционал несложно сделать и на основе любых других сервисов, предоставляющих API для добавления маркеров на карту, скажем, на базе «Яндекс.Карты». В результате удастся сделать более наглядными блоги, посвященные, к примеру, театральной жизни города, рассказывающие о магазинчиках с интересными товарами или скидках в них, о выставках, конференциях, семинарах и т. п.
Думается, что такой дополнительный режим отображения лишь добавит блогам привлекательности, ведь читатели смогут увидеть текст, фото и видео, привязанные к сайту. Кроме того, они, например, узнают, как проехать или пройти к нужному объекту на карте, что находится с ним по соседству, а также рассчитать время движения и выяснить еще много чего полезного. Конечный результат нашего эксперимента получится примерно таким: в окне браузера поверх карты появятся маркеры, привязанные к записям блога. Щелчок на них перебросит к статье, отображаемой стандартными средствами WordPress в соответствии со сделанными там настройками и выбранным шаблоном.
Внутри WordPress
Сперва рассмотрим серверную часть нашей программы. Она включает в себя главный файл index.html и ряд модулей на PHP для конвертирования записей БД в формат JSON, понятный JavaScript. Самый простой способ интегрироваться с WordPress — это воспользоваться его же классами и функциями для доступа к таблицам базы данных блога. Узнать, как именно движок хранит данные, то бишь структуру и поля таблиц, позволяет утилита PhpMyAdmin. Она, напомним, предустановлена на веб-хостингах и доступна в таком популярном пакете для Windows-разработчиков сайтов, как Denwer, — в нем она запускается из браузера по ссылке localhost/Tools/phpMyAdmin.
Итак, записи WordPress добавляются к таблице с именем <префикс>_posts (через символ подчеркивания), а метаданные, включая дополнительные поля для записей блога, хранятся в таблице <префикс>_postmeta. В обоих случаях префикс — это идентификатор, заданный при установке WordPress. По умолчанию он имеет значение wp. Для доступа к БД в WordPress предусмотрены класс wpdb и уже объявленная глобальная переменная $wpdb. Остается лишь подключить соответствующий модуль с помощью команды require_once «/wordpress/wp-load.php».
Теперь создадим SQL-запрос и присвоим его переменной $request. В нем свяжем две таблицы по полю ID, используя ссылки на имена таблиц в переменных $wpdb->posts и $wpdb->postmeta. В запросе выбираются уже опубликованные данные (имеющие статус publish, что позволит исключить черновые копии записей), в которых объявлено поле address (если используется другое название, его нужно указать в условии для поля meta_key). Кроме того, они упорядочиваются по дате от наиболее поздней к ранней (опция DESC). Отметим, что дополнительно можно ограничить число записей посредством опции LIMIT — в данном случае отбираются десять последних записей.
Итак, запрос выглядит так, как показано в листинге
Следующий этап — перебор в цикле foreach () строк запроса и добавление значений в массив:
$posts=$wpdb->get_results ($request);
$b=array ();
foreach ($posts as $post) {:}
Внутри цикла foreach, собственно, и определяется, какие именно поля и в какой последовательности попадают в массив $b. Для рассматриваемой задачи достаточно трех: содержимое записи (поле post_content, которое при необходимости можно обрезать строковыми функциями), ссылка на полный текст записи и поле с адресом.
$post_content=stripslashes
($post->post_content);
$permalink=get_permalink ($post->ID);
$address=$post->meta_value;
$b [$post->ID]=array (latlng’ => $post->meta_value, ‘address’=>‘’, ‘title’=>$post_title, ‘link’ => $permalink, ‘content’=>$post_content);
Последний этап — конвертирование массива с помощью функции json_encode () в понимаемую JavaScript-сценариями JSON-структуру и ее печать:
$mapjson = json_encode ($b);
echo $mapjson;
Все эти действия можно записать в виде функции echo_json_map (), расположить в отдельном модуле (к примеру, functions.php) и вызывать их при запросе данных с сервера. Назовем этот модуль get_map.php. Не считая открывающего и закрывающего тегов, он занимает всего две строки:
HTML-страница изнутри
Клиентский модуль, как уже отмечалось, использует jQuery. Так что не забудьте подключить фреймворк jQuery к html-файлу. Кроме того, он использует официальный плагин «шаблонизатор», позволяющий динамически формировать контент страницы по шаблону (этот шаблон, предложенный Microsoft, в октябре стал официальным плагином jQuery):
Также потребуется модуль для управления картами Google:
Алгоритм работы создаваемой программы примерно таков. Сначала нужно определить параметры карты и способ ее отображения, далее обратиться через ajax-запрос к блогу и получить от нашего PHP-скрипта данные в формате JSON-массива, а затем перебрать этот массив и динамически добавить его на страницу: маркеры появляются на карте, а подсказки добавляются в отдельный блок div.
Изначально веб-страница пуста. Никаких данных в ней нет, есть лишь пара блоков
Для идентификатора map непременно должны быть указаны стили, определяющие положение карты на странице, отступы, границы и др. Вот, например, как может выглядеть стиль (стили описываются в заголовке страницы в тегах ):
#map { width:900px; height:80?%; margin:5px auto; border: 1px;}
Не менее важный блок — шаблон всплывающей подсказки. Он записывается внутри тегов и обозначается как text/x-jquery-tmpl. Заметим, что веб-браузер это описание игнорирует, но в нашем JavaScript-сценарии оно используется. В шаблон включены не только теги HTML, но и особым образом отформатированные поля, например $ {title}. Наименования этих полей должны совпадать с теми, что передаются с сервера в виде JSON-массива.
Итак, шаблон выглядит так, как показано чуть ниже. Обратите внимание — переменные шаблона можно включать и в обозначения ссылок в теге , и в идентификаторы блока в div (по этому идентификатору, собственно, и отыскивается сообщение для выбранного на карте маркера):
$ {title}
JavaScript-сценарии
Теперь перейдем непосредственно к сценариям JavaScript. В библиотеке jQuery доступен весьма удобный механизм инициализации страницы по мере ее готовности (в ней вызывается функция resetmarkers ():
$ (document). ready (function () { resetmarkers ();})
Прежде всего, в JavaScript-модуле объявляются две глобальные переменные: map для карт и infowindow для всплывающих окон, привязанных к маркерам. Функция resetmarkers () инициализирует переменную map, ссылающуюся на карты Google, добавляет ее к веб-странице, а затем подгружает записи блога.
Карты подключаются следующим образом: в первой строке в myOptions определяются масштаб и способ отображения, во второй карта появляется в блоке div с идентификатором map:
var myOptions = { zoom: 11, mapTypeId: google.maps.MapTypeId.HYBRID};
map = new google.maps.Map ($ (¨#map¨). get (0), myOptions);
Кроме того, в функции resetmarkers () город Москва центрируется на карте (вы, впрочем, можете подставить любой другой город, известный Google). Для этого используется объект geocoder:
geocoder.geocode ( { ‘address’: ‘Москва, Россия’}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) { map.setCenter (results [0].geometry.location);}});
Вторая часть функции resetmarkers () загружает данные из блога, используя вспомогательный PHP-модуль (речь о нем шла выше). Получив с сервера JSON-массив, сценарий на JavaScript перебирает записи в цикле и подставляет строки в div с идентификатором infodata с помощью такой конструкции:
$ ( ¨#infotemplate¨). tmpl (data [key]). appendTo ( ¨#infodata¨)
Кроме того, в цикле вызывается функция createmarker (), добавляющая маркеры на карту. Их число соответствует длине JSON-массива с записями блога (напомним также, что в PHP число записей было ограничено десятью, и значит, большее число маркеров не получить). Для создания каждого нового маркера используется команда new google.maps.Marker (), в которой указываются ссылка на карту, заголовок и координаты. А еще добавляется обработчик события click в методе google.maps.event.addListener (). В нем в цикле отыскиваются совпадающие координаты и появляется информационное окно с подсказкой — следующий код как раз и загружает в него ранее созданный по шаблону элемент:
for (key in data) {
if (data [key].latlng == marker.getPosition (). toUrlValue ()) {
infoid = ¨#¨+data [key].id;
infowindow.content = $ (infoid). html ();
infowindow.open (map, marker);
}}
Описанные скрипты и полная версия статьи выложены на «Мир ПК-диске». Работу скриптов можно увидеть на сайте giksapiens.ru/html/maps.
$request =¨select id, post_title, post_content, meta_value from
$wpdb->posts, $wpdb->postmeta¨;
$request.=¨where $wpdb->posts.id = $wpdb->postmeta.post_id¨;
$request.=¨and post_status=’publish’ and post_type=’post’ and meta_key=’address’¨;
$request.=¨order by $wpdb->posts.post_date desc limit 10¨;
О координатах в «Картах Google»
Чтобы максимально упростить ввод правильных координат, составим еще один незамысловатый JavaScript-сценарий. Он делает только одну операцию: отображает над картой координаты и полное название улицы, выбранной щелчком мыши. Теперь требуется лишь аккуратно скопировать текст и вставить его в соответствующее поле в редакторе блогов.
Та часть html-файла, которая обрабатывает событие click (щелчок мыши на карте), обращается к Geocoder для поиска координат и в завершение динамически подставляет текст в заранее определенный блок div с идентификатором content. На эту функцию следует сослаться в событии onload для тега
:function resetmap ()
{
var myOptions = { zoom: 16, mapTypeId: google.maps.MapTypeId.HYBRID};
var map = new google.maps.Map (document.getElementById (¨map_canvas¨), myOptions);
var geocoder = new google.maps.Geocoder (); address = ¨Москва¨;
// центрируем карту — где-то в районе Кремля
geocoder.geocode ( { ‘address’: address}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
map.setCenter (results [0].geometry.location);}});
// щелчком мыши определяем и печатаем улицу google.maps.event.addListener (map, ‘click’, function (event) {
geocoder.geocode ( { ‘location’: event.latLng}, function (results, status) {
if (status == google.maps.GeocoderStatus.OK) {
document.getElementById (¨content¨). innerHTML = results [0].geometry.location.toUrlValue () +¨ ¨+results [0].formatted_address;}});});};
Добавим, что, в отличие от главного модуля, нуждающегося в веб-сервере и PHP-скриптах, данный html-файл с этим JavaScript-сценарием можно запускать с локального компьютера. Естественно, доступ в Сеть при этом необходим, так как вся информация грузится с сайта Google.