О web-разработке
и даже немного больше...

Как изменить символы подчервикания (_) на символы минуса (-) в ЧПУ 1С-Битрикс

Привет. Для успешной работы поисковых машин с сайтом в качестве URL доступа к страницам рекомендуется использовать ЧПУ. ЧПУ – человеко-понятные URL, удобные URL-адреса для восприятия человеком. На самом деле, сегодня это делается для поисковых машин, тем самым оптимизируя страницы для лучшей индексации сайта.
Сайты, работающие под управлением 1С-Битрикс, в основном хранят свои данные в инфоблоках. При выводе содержимого элемента, это могут быть новости, обзоры, карточка товара и т.д., компонент может генерировать человеко-понятные URL, если в настройках включен режим ЧПУ. Большая часть символьных кодов элементов и разделов генерируется динамически, путем транслитерации из названия разделов и элементов инфоблока. По умолчанию знаки пробелов заменяются нижним подчеркиванием. Однако бытует мнение, что в ЧПУ лучше всего использовать символы из ограниченного набора ASCII-символов. В частности, вместо пробела лучше использовать символы минус «-» или подчеркиванием «_». Рассмотрим пример, как можно изменить разделительные символы нижнего подчеркивания «_» на символ минус «-», при генерации элемента.
Проще всего это сделать посредством файла init.php – создать обработчик события, при добавлении и обновлении элемента.
Код:

AddEventHandler("iblock", "OnBeforeIBlockElementAdd", 'slugTranslit');
AddEventHandler("iblock", "OnBeforeIBlockElementUpdate", 'slugTranslit');

Функция:

function slugTranslit(&$arFields){
	# Если заполнено имя и не заполнен символьный код
    if (strlen($arFields["NAME"]) > 0 && strlen($arFields["CODE"]) <= 0){
        $arParams = array(
            "max_len" => "100", # обрезаем символьный код до 100 символов
            "change_case" => "L", # приводим к нижнему регистру
            "replace_space" => "-", # меняем пробелы на тире
            "replace_other" => "-", # меняем плохие символы на тире
            "delete_repeat_replace" => "true", # удаляем повторяющиеся тире
            "use_google" => "false", # отключаем использование google
        );
        $arFields["CODE"] = Cutil::translit($arFields["NAME"], "ru", $arParams);
    }
}

Попробуйте создать либо открыть на редактирование элемент, после, сохраните изменения, затем проверьте его символьный код. Если разделяющие символы задались в виде знака минус «-», значит всё в порядке.
 
UPD: Как заменить символы принудительно, не ожидая вызова обработчика события?
Недавно потребовалось проделать такую операцию с уже существующим набором элементов и разделов инфоблока. Для этого пришлось написать небольшой скрипт, который запрашивал все разделы и элементы информационных блоков определенного типа, и заменял символы при нахождении символа нижнего подчеркивания на символ минус. Ниже привожу код, обратите внимание, что вызывать этот скрипт нужно залогинившись под учетной записью с правами администратора.

<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/header.php");

define("NEED_AUTH", true);
global $USER;
if (!$USER->IsAdmin()) LocalRedirect("/");

set_time_limit(600);
$IBLOCK_TYPE = 'catalog';


# функция для замены символа "_" на "-"
function repSymCode($code){
	if(strripos($code, '_')!==false){
		$code = str_replace('_','-',$code);
		if(substr($code, -1) == '-')
			$code = substr($code,0,(strlen($code) - 1));
	return $code;
	} else return false;
}

# кнопка старт
if (isset($_REQUEST['start']) && CModule::IncludeModule("iblock")){

#------------------------------
# Обновление кодов секций
#------------------------------
$sectionRes = CIBlockSection::GetList(
		array("SORT"=>"ASC"),
		array('IBLOCK_TYPE' => $IBLOCK_TYPE),
		false,
		array('CODE','ID'),
		false
);
$siCnt=0;
$secObj = new CIBlockSection;
while($arSection = $sectionRes->GetNext()){
	$code = repSymCode($arSection['CODE']);
	if ($code != false){
		$siCnt++;
		$secObj->Update($arSection['ID'], array('CODE' => $code));
	}
}
$arResult['MSG'][] = 'Обновлено разделов: '.$siCnt;
#-------------------------------


#-----------------------------
#	Обновление кодов элементов
#-----------------------------
$elemRes = CIBlockElement::GetList(
	array("SORT"=>"ASC"),
	array('IBLOCK_TYPE' => $IBLOCK_TYPE),
	false,
	false,
	array('ID','CODE')
);

$elObj = new CIBlockElement;
$eiCnt = 0;
while($arElemObj = $elemRes->GetNextElement()){
	$arElemFields = $arElemObj->GetFields();
	$code = repSymCode($arElemFields['CODE']);
	if ($code != false){
		$elObj->Update($arElemFields['ID'], array('CODE' => $code));
		$eiCnt++;
	}
}
$arResult['MSG'][] = 'Обновлено элементов: '.$siCnt;
#----------------------------------------------------

} # end if
?>

<h2>Замена символов в символьных кодах</h2>
<?if (count($arResult['MSG'])>0){
	foreach($arResult['MSG'] as $msgValue){?><p><?=$msgValue?></p><?}
}?>
<form method="post"><input type="submit" name="start" value="Старт"></form>
<?require($_SERVER["DOCUMENT_ROOT"]."/bitrix/footer.php");?>
Опубликован: 09.03.2014 г.

См. также:

«Не удалось установить соединение с сервером. Проверьте …».
Получение Email-адреса покупателя в заказе (Bitrix D7)
Работа с URL-адресами в Bitrix D7
Работа с купонами в Bitrix API
Добавляем пункт меню для списков в админке Битрикс
Диалоговые окна в Bitrix API
Создание инфоблока при установке модуля
Создание копии корзины из заказа на Bitrix D7

Комментарии

  1. Алексей пишет:

    У тебя ошибка!

    if(strripos($code, '_')){ - так работать правильно не будет, так как "-1" при "==" - это не false

    нужно заменить на:
    if(strripos($code, '_')!==false){

    1. htmaker пишет:

      поправил, спасибо)

  2. Константин пишет:

    Здравствуйте! Столкнулся с такой же необходимостью. Думаю ваша статья поможет решить половину проблемы - заменить адреса у элементов инфоблоков. Однако останется другая половина проблемы - можно ли как то организовать редирект со страниц, содержащих символ нижнего подчеркивания на аналогичные страницы, содержащие тире? Дело в том, что сайт рабочий и много страниц уже есть в индексе. Заранее спасибо!

    1. htmaker пишет:

      В компоненте отвечающий за показ элемента заменяйте символ _ на - в коде запроса, (функция str_replace), затем 301 редирект по новому адресу с помощью функции LocalRedirect в битриксе. Думаю такой костылек сгодится пока в поисковике не обновятся URL-адреса на новые.

    2. htmaker пишет:

      Забыл, а перед этим ещё хорошо бы проверять наличие таких символов в коде запроса, чтобы не делать редиректа в холостую, можно с помощью функции strpos

  3. Константин пишет:

    Если кому интересно - решил проблему триггером в /bitrix/php_interface/init.php

    AddEventHandler("main", "OnEpilog", "myUrlCheck");
    function myUrlCheck()
    {
    GLOBAL $APPLICATION;
    $myCurUrl = $APPLICATION->GetCurPageParam();
    if (strpos($myCurUrl, '_'))
    {
    $myNewUrl = str_replace('_', '-', $myCurUrl);
    LocalRedirect($myNewUrl, 0, '301 Moved permanently');
    }
    }

    1. Сергей пишет:

      На работает у меня так=( Можно ли это реализовать через .htaccess?

  4. Иван пишет:

    Добрый день, а можно ли таким же способом решить мою проблему? У меня после выгрузки из 1С название элементов на украинском языке а в свойстве этого элемента есть русское наименование и его нужно поставить в название. Вытащить свойство в каталог не составляет труда, но нужно сделать полную замену везде, как в результатах поиска так и при отправке почтового шаблона. Подскажите пожалуйста.

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

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Комментарии
  • Загрузка...
Друзья сайта