Как стать автором
Обновить

Геотаргетинг по городам (регионам, странам) для WordPress

Время на прочтение4 мин
Количество просмотров31K

Причины создания


Недавно попросили сделать геотаргетинг по городам для сайта на wordpress. Пересмотрев существующие геотаргетинг-плагины (в том числе платные), не нашёл не одного работающего с городами (только страны). Поэтому решил сделать свой, используя какую-нибудь существующую базу для определения местоположения по IP-адресу. Сначала начал с разработки функции в шаблоне, но потом решил создать плагин и выложить на github, так как думаю, что он может пригодиться кому-нибудь ещё.

Выбор базы


Первым делом нужно было выбрать базу. И это, наверное, одна из самых сложных проблем. В процессе разработки пробовал много вариантов, даже делал CURL-запросы на сайты, определяющие местоположение по ip, и парсил их. Но все они были не точны, к примеру, один Московский IP определяло как Москву, другой — просто Россия. Также нужно было, чтобы плагин работал не только с Россией, но и с Беларусью и Украиной. Перепробовав кучу множество баз, я остановился на Sypex Geo. У них есть условно-платная и бесплатная версии баз. Условно-платная использует REST API и возвращает данные в виде xml, json и jsonp. Бесплатную можно скачать в виде файла, также можно скачать класс для работы с ней. Условно-платная версия более точная, но бесплатно предоставляет только 10 000 запросов. Бесплатная версия тоже достаточно точна и обновляется на сайте.

Функционал


Как я уже писал, начинал я делать не с плагина, а с функции в шаблоне. Сначала думал только об условно-платной версии базы, но количество бесплатных запросов закончилось за день-два. Поэтому перешёл на бесплатную, используя готовый класс для работы с файлом базы.

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

Также из базы можно вернуть русские и английские имена городов (стран, регионов). В связи с этим сделал выбор языка.
Ещё столкнулся с тем, что нужно включить список несколько городов или наоборот исключить какой-то.


Настройка плагина в админке

Реализация


Так как с Wordpress я работаю редко (как и со всеми CMS) и написанием плагинов для него никогда не занимался, начал читать, как их писать и смотреть, как устроены существующие. Идею реализации взял с существующих гео-плагинов. Ещё долго думал писать функционально или объектно-ориентированно. Решил функционально, так как плагин не большой.

Вкратце опишу его работу.

При активации плагина инициируем две опции: тип бд и язык на котором будем вводить названия.

register_activation_hook(__FILE__, 'wp_sypexgeo_activation');
function wp_sypexgeo_activation() {
	update_option('sgeo_language', 'en');
	update_option('sgeo_dbase', 'loc');
}

Далее
    add_filter('the_content', 'geotargeting_filter');
	add_filter('the_content_rss', 'geotargeting_filter');
	add_filter('the_excerpt', 'geotargeting_filter');
	add_filter('the_excerpt_rss', 'geotargeting_filter');
вызывают функцию
geotargeting_filter
function geotargeting_filter($s) {
		//parse Country
		preg_match_all("#\[" . GEOTARGETING_COUNTY . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_COUNTY . "\]#isu", $s, $country);
		//parse Country
		preg_match_all("#\[" . GEOTARGETING_REGION . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_REGION . "\]#isu", $s, $region);
		//parse Country
		preg_match_all("#\[" . GEOTARGETING_CITY . "\s*(in|out)=([^\]]+)\](.*?)\[/" . GEOTARGETING_CITY . "\]#isu", $s, $city);
		if (empty($country) && empty($region) && empty($city)) {
			return $s;
		}
		$base_type = get_option('sgeo_dbase');
		if ($base_type == 'loc') {
			$ipdata = getLocInfo();
		} elseif ($base_type == 'rm') {
			$ipdata = getRemInfo();
		}
		if (!empty($country)) {
			foreach ($country[0] as $i => $raw) {
				$type = strtolower($country[1][$i]);
				$countries = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t", " "), "", $country[2][$i])));
				$content = $country[3][$i];
				$countries = explode(",", $countries);
				$replacement = "";
				if ((($type == "in") && in_array($ipdata['country'], $countries)) || (($type == "out") && !in_array($ipdata['country'], $countries))) {
					$replacement = $content;
				}
				$s = str_replace($raw, $replacement, $s);
			}
		}
		if (!empty($region)) {
			foreach ($region[0] as $i => $raw) {
				$type = strtolower($region[1][$i]);
				$regions = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t"), "", $region[2][$i])));
				$content = $region[3][$i];
				$regions = explode(",", $regions);
				$replacement = "";
				if ((($type == "in") && in_array($ipdata['region'], $regions)) || (($type == "out") && !in_array($ipdata['region'], $regions))) {
					$replacement = $content;
				}
				$s = str_replace($raw, $replacement, $s);
			}
		}
		if (!empty($city)) {
			foreach ($city[0] as $i => $raw) {
				$type = strtolower($city[1][$i]);
				$cities = strtolower(trim(str_replace(array("\"", "'", "\n", "\r", "\t", " "), "", $city[2][$i])));
				$content = $city[3][$i];
				$cities = explode(",", $cities);
				$replacement = "";
				if ((($type == "in") && in_array($ipdata['city'], $cities)) || (($type == "out") && !in_array($ipdata['city'], $cities))) {
					$replacement = $content;
				}
				$s = str_replace($raw, $replacement, $s);
			}
		}
		return $s;
	}
В которую приходит текущий контент. В зависимости от типа базы вызывается функция для получения данных. Затем идёт поиск специальных тегов в шаблоне и сверка их с данными о местоположении. Если данные совпадают то конструкция заменяется на содержимое из тегов, если нет — она удаляется.

Использование


Для указания списка стран:
[GeoCountry in=Belarus,Russia]Привет Belarus,Russia![/GeoCountry]

Для указания списка регионов:
[GeoRegion in=Moscow]Привет Moscow Region![/GeoRegion]

Для указания списка городов:
[GeoCity in=Минск,Брест]Привет Минск,Брест![/GeoCity]

Если вы хотите выбрать страны (регионы, города) за исключением указанных, используйте «out»:
[GeoRegion out=Minsk,Brest]Привет всем, кроме Minsk,Brest![/GeoRegion]


Пример использования в шаблоне:

Добро пожаловать в WordPress. Это ваша первая запись. Отредактируйте или удалите её, затем пишите! Наши контакты: [GeoCity in=Minsk]+375295552255[/GeoCity][GeoCity out=Minsk]+375475552255[/GeoCity]

Заключение


Надеюсь, мой плагин кому-нибудь пригодится. Если есть вопросы или предложение — пишите. Также, если кто-то считает, что нужно использовать другую базу (геосервис или ещё что-нибудь), предлагайте, я добавлю или можете добавить сами.

Ссылка на плагин: wp-sypexgeo
Теги:
Хабы:
Всего голосов 18: ↑15 и ↓3+12
Комментарии4

Публикации

Истории

Работа

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
14 сентября
Конференция Practical ML Conf
МоскваОнлайн
19 сентября
CDI Conf 2024
Москва
20 – 22 сентября
BCI Hack Moscow
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн
3 – 18 октября
Kokoc Hackathon 2024
Онлайн