Необходимо было разработать федеральный сайт для фирмы имеющей офисы в разных городах. Для каждого города должны были быть свои новости, статьи, и тд. Не имея опыта в подобных задачах я обратился на форум. http://dev.1c-bitrix.ru/community/for...sage198298
Наиболее подходящим решением задачи мне понравилось предложение Дениса Клокова :
На одном из проектов было. Города - эл-ы инфоблоков, довольно удобно туда вбивать контакты, координаты на картах, счетчики статистики и т.д.
Всякие новости, модели товара и т.п имеют свойство типа "привязка к эл-м ИБ" по которому и фильтруем динамический контент, остальные считаются общими для всего сайта вне зависимости от города.
Только я решил сделать города не элементами, а разделами инфоблока "города", но это не важно. Каждый раздел инфоблока "города" должен обязательно иметь символьный код, который и будет являться доменом 3го уровня.
Встал вопрос какую организацию адресов выбрать:
по папкам вида mysite.ru/city_name/bla-bla/
мультидоменную вида city_name.mysite.ru/bla-bla/
Мне больше по душе оказался второй вариант, скорее всего больше из-за эстетичской точки зрения, а не желанием возиться с mod_rewrite) Какой вариант выгодней для сео я не знаю. Если знаете — напишите пожалуйтса в комментариях.
Еще одно требование - пользователь при перезаходе на сайт должен попадать сразу на тот город, который он выбрал в прошлый раз.
Итак, первое что нужно это настройка днс служб. Чтобы днсы адресовали http запрос с адресом типа city_name.mysite.ru веб-серверу, нужно, чтобы присутствовала запись А -типа с названием каждого возможного города. То есть мне можно было добавлять для каждого нового города записи moscow, samara etc. но у администратора сайта должна была быть возможность добавить новый город всего лишь добавлением раздела инфоблока в админке. Поэтому, чтобы любые запросы, где домен второго уровня - "mysite.ru" передавались веб серверу, нужно включить в днс записи такую строку:
* IN A IPадресСервера
Аналогично с веб-сервером. В настройках virtualhost апача я включил такие строки:
ServerName mysite.ru
ServerAlias *.mysite.ru
.htaccess мы не трогаем, никаких танцов с бубнами вокруг mod_rewrite нам не нужно.
Далее осталась программная часть. Думаю тут уже ничего объяснять не нужно, все видно по комментариям. Привожу код из /bitrix/php_interface/ID сайта/init.php
<?if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die();?>
<?php
// посмотрим какой город был выбран этим юзером в прошлый раз
$sUserCity = $APPLICATION->get_cookie('USER_CITY');
// установим глобальную переменную cur_city = код города (из сабдомена)
$GLOBALS['sCurCity'] = preg_replace('/^(?:([^\.]+)\.)?mysite\.ru$/', '\1', $_SERVER['SERVER_NAME']);
// символьные коды возможных городов и полные описания возможных городов
$arCityCodes = $arCities = array();
// кэшируем подключение модуля инфоблоков и выборку возможных городов
$obCache = new CPHPCache;
$iLifeTime = 60*60*3;
$sCacheID = SITE_ID.'City';
// если кеш есть и он ещё не истек, то
if($obCache->InitCache($iLifeTime, $sCacheID, '/')) {
// получаем закешированные переменные
$arVars = $obCache->GetVars();
$arCityCodes = $arVars['arCityCodes'];
$arCities = $arVars['arCities'];
}
else {
// иначе обращаемся к базе
// получим список всех возможных городов на сайте
if (CModule::IncludeModule('iblock')) {
// без этой переменной ругается на вызов метода _CIBlockElement::GetGroups()
global $USER;
$USER = new CUser;
// узнаем все города на сайте с непустым кодом
$arFilter = Array('IBLOCK_ID'=>1, 'GLOBAL_ACTIVE'=>'Y', '!code'=>false);
$dbCities = CIBlockSection::GetList(array('SORT'=>'ASC'), $arFilter);
// заполняем ими массивы $arCityCodes и $arCities
while ($arCity = $dbCities->GetNext(false,false)) {
$arCityCodes[] = $arCity['CODE'];
$arCities[] = $arCity;
}
if (empty($arCityCodes)) ShowError('Нет городов');
} else ShowError('Не получилось подключить модуль «iblock»');
}
if($obCache->StartDataCache()) $obCache->EndDataCache(array('arCityCodes' => $arCityCodes, 'arCities' => $arCities));
// конец кэширования
foreach ($arCities as $arCity) {
if ($arCity['CODE'] == $sCurCity) {
// запишем название города (позже пригодится где-нибудь)
$GLOBALS['sCurCityName'] = $arCity['NAME'];
// это самое главное, id нам нужен будет для фильтров
$GLOBALS['iCurCityID'] = $arCity['ID'];
}
}
// если запрошен сайт с пустым или неверным сабдоменом
if (!in_array($sCurCity,$arCityCodes)) {
// то если существует валидная кука
if (in_array($sUserCity,$arCityCodes)) {
// редирект на город записанный в куках
header("Location: http://{$sUserCity}.mysite.ru/");
} else {
// если кука не валидная или ее не существует
// Устанавливаем ее и редиректим на 1й город по сортировке городов
$APPLICATION->set_cookie('USER_CITY', $arCityCodes[0]);
header("Location: http://{$arCityCodes[0]}.mysite.ru/");
}
}
// после всех редиректов устанавливаем куку на текущий город
if (strlen($sCurCity)) $APPLICATION->set_cookie('USER_CITY', $sCurCity);
// установим фильтр, который будем повсеместно применять
// для списков элементов на сайте, где предполагается зависимость от города
if (intval($iCurCityID) > 0) $GLOBALS['arrFilter'] = array('PROPERTY_CITY'=>$iCurCityID);
?>
Если будет интересно, могу рассказать как я делал саму "переключалку городов" для визуальной части сайта.
Не понял вопроса. Речь идет о публичной или административной части? Что значит "лежат в куче"? В параметрах компонента, будь то news.list или catalog.section указываете фильтр arrFilter и все. Насчет каталога товаров - точно не нужно для каждой новой цены делать копию товара - нужно создать несколько типов цен и в result_modifier.php определять ту цену которую необходимо вывести в зависимости от города. При этом придется переписать колбек-функции добавления товара в корзину и оформления заказа.
Речь шла о куче в административной части. Допустим, есть две новости - одна должна отображаться для Питера, другая для Москвы. Тогда в инфоблоке новости заводим два элемента, каждый привязываем к своему городу. В компоненте на главной странице указываем фильтр. Тогда при заходе на питерскую часть сайта пользователь увидит в разделе новостей ( GOROD.site.com/news/ ) одну новость (допустим, /news/novost1) , а при заходе на московскую - другую ( /news/novost2 ). При этом в админке обе новости находятся "в корне" инфоблока. Если новостей двести, а городов пять, то в админке образуется куча. Как раскидать эти новости по подразделам я не понял, ведь тогда для каждой новости путь получится CITY.site.com/news/CITY/novost_id и для каждого города будет отображаться всё дерево. И это уже как я понял решается приличным перепиливанием компонентов и навигационных меню. Или всё просто? Тогда как?
"ведь тогда для каждой новости путь получится CITY.site.com/news/CITY/novost_id" Да, для удобства можете создать разделы - названия городов, а в публичке чтобы выводились нужные урлы для элементов можно использовать: либо в настройках инфоблока изменить шаблон ссылки детальной страницы элемент (например SITE_DIR/#ELEMENT_CODE#/ вместо SITE_DIR/#SECTION_CODE#/#ELEMENT_CODE#/) либо в каждом компоненте задавать шаблон ссылки через параметр DETAIL_URL , в стандартных компонентах перед GetNext используется SetUrlTemplate()
Ишкачёв Дмитрий, должен работать, недавно внедрял правда немного дорабатывал по рекомендациям сеошников и + с автоматическим определением города по айпи. Попробуйте навремя поставить $iLifeTime = -1; вдруг скрипт прокешировал пустой инфоблок.
Привет, с точки зрения Seo я думаю не выгодным продвигать поддомены, а выборку городов в рамках сайта по второму типу, я считаю более правильной. если не трудно подскажи как её можно реализовать?
2 вариант с поддоменами самый правильный, каждый поддомен можно отдельно продвигать в своем регионе, ранжирование в регионе будет лучше + юзабилити, чпу, статистика и мн.другое.
Спасибо, Александр! Упростил на свой лад: - без проверки куки, т.к. определяющим критерием является используемый субдомен - без обращения к базе/кешу, т.к. 3 региона фиксированно. - без фильтра, т.к. все материалы на сайте (кроме контактов) одинаковые для всех регионов
Шашалевич Станислав, посмотрите на дату моей статьи и когда вы выложили готовое решение? ну заплатить 12к вместо того чтобы чуть чуть подумать головой это альтернативно одаренным лишь под силу
Zontov Alexander, я с Вами соглашусь. Если пользователь является программистом, располагает запасом времени и хочет прокачать свой профит, то тогда Ваша статья будет для него отличным подспорьем.
Но согласитесь, в большинстве случаев даже программистам проще купить готовый модуль и внедрять уже его. Так и правильнее, и быстрее. Зачем городить велосипеды?
К тому же, Александр, данный модуль значительнее функциональнее того кода, который Вы представили в данной статье. А в ближайшем обновлении еще выйдет расчет доставки в карточке товара.
Группы на сайте создаются не только сотрудниками «1С-Битрикс», но и партнерами компании. Поэтому мнения участников групп могут не совпадать с позицией компании «1С-Битрикс».