Тестовый дизайн новой версии сайта IGD.BY         RU   |   EN
Несколько полезных советов по внедрению и обработке ЧПУ в 1С-Битрикс. Получение разделов и элементов инфоблоков через символьные
Автор: Кристофер

В последнее время большинство заказчиков требует создание интернет сайтов с внедренными ЧПУ (устоявшийся русскоязычный жаргонизм от "человеко-понятные URL"). По-английски то же самое называется SEF URL (Search Engines Friendly URL — ссылки дружественные поисковым системам). По существу, мы говорим о ссылках внутри сайта, которые записываются не цифробуквенным кодом, а обычными словами. В рамках русскоязычного сегмента Интернета эти слова являются транслитерированнными, то есть, записанные латиницей. Следует отметить, что для английского языка такое нововведение является действительно дружественным для поисковых систем, потому как в самом адресе хранятся ключевые слова для поиска, что касается русского языка с транслитерацией, дружественность ЧПУ для поисковых систем является довольно спорным моментом, хотя и имеет свои определенные плюсы, а именно, ссылки становятся понятными, их можно запомнить, продиктовать по телефону и так далее. То есть, в нашем случае они более дружественны к человеку.  

На самом деле при программировании ЧПУ нет ничего сложного, нужно просто понимать суть происходящего. Именно с этого мы и начнем нашу публикацию.

 

Суть решения

 

Начнем с примера. Самая стандартная ссылка с GET запросом выглядит так: http://имя_сайта/index.php?view=category&id=1 (показать страницу category с отображением категории, id которой равно 1). В ней мы сообщаем два параметра для переменных $_GET['view'] и $_GET['id'], а именно, "category" и "1". Обработка этих параметров и соотвествующее перенаправление производится в файле index.php, и в данном случае его лучше всего назвать триггером (т.е. переключателем).  

Отдельно стоит отметить, что файлы с названием index.php (или index.html) в рамках сайтов являются автоматическими точками входа для указанного адреса. И сейчас практически у всех серверов есть настройки переадресации в файлах .htaccess с тем, чтобы файлы index.php не указывались в адресных строках. Речь идет о строчках наподобие:

 

RewriteEngine On

RewriteRule ^index.php$ / [QSA,R]

 

Это сделано и для того, чтобы у загрузочной страницы не было двух адресов (например, http://имя_сайта/ и http://имя_сайта/index.php), что плохо сказывается на индексанции в поисковых системах. Учитывая вышесказанное, мы можем наш адрес с GET-запросом смело заменять на http://имя_сайта/?view=category&id=1, что идентично http://имя_сайта/index.php?view=category&id=1.

 

Физические и символические адресные ссылки

 

Такая же автоматическая переадресация затрагивает не только корневую директорию сайта, но и любые другие. Например, если вы создадите папку category, и в ней свой файл index.php, то при открытии в браузере адреса http://имя_сайта/category/ по умолчанию будет выдаваться уже его содержимое. Данная ссылка будет указывать на папку, которая физически присутствует на сайте, то есть, сама ссылка физическая. Если такой папки нет, то при отсутствии введенных дополнительных условий будет выдаваться ошибка 404, "указанная страница не найдена".  

Но можно ли сделать так, чтобы ссылки были символическими, то есть, не были привязаны к дереву директорий сайта. Конечно. Для этого нам нужно сделать две вещи, а именно, разрешить обработку адресной строки в .htaccess и указать файл-триггер, в котором будут обрабатываться URL. Для этого, вписываем в файл .htaccess (если он отсутствует в корневой директории сайта, то создаем его) следующие строки:

 

<IfModule mod_rewrite.c>

RewriteEngine on

RewriteBase /

RewriteCond %{REQUEST_FILENAME} !-f

RewriteCond %{REQUEST_FILENAME} !-d

RewriteRule . /index.php [L]

</IfModule>

 

В данном случае файлом-триггером является точка входа, то есть index.php. Теперь нам остается только внести условия обработки URL в самом файле index.php. Делается это довольно просто, путем парсинга (расшифровки адресной строки) и загрузки ее элементов в массив:

 

<?

$url_path = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);

// Разбиваем виртуальный URL по символу "/"

$arURL = explode('/', trim($url_path, ' /'));

//выводим элементы массива

print_r($arURL);

?>

 

0-м элементом массива $arURL будет первый адрес после имени сайта, например, в адресе http://имя_сайта/category/ $arURL[0] будет содержать значение "category". Ветвление может идти и дальше. Если в данном случае мы начнем программировать дальше, то нам понадобится база данных с таблицами, в которых есть поля с символьными кодами элементов, по которым мы можем производить поиск и загружать нужный контент.

 

1С-Битрикс

 

Адресные ссылки в 1C-Битрикс строятся по такой же методе, только по умолчанию, в URL включаются id инфоблоков, секций и элементов. Также там могут использоваться как физичиеские ссылки, так и символические, а чаще всего смешанные. 

При создании инфоблока вам требуется отредактировать или оставить по умолчанию поля правил формирования трех адресных ссылок: URL страницы информационного блока, URL страницы раздела и URL страницы детального просмотра. Также предлагается ввести символьный код для названия самого инфоблока.

Давайте для примера создадим инфоблок типа catalog. Если вы берете стандартную комплектацию одного из семейства редакций "Битрикс. Управление сайтом" и загрузили шаблонный магазин, то этот инфоблок у вас уже есть, его свойства можно посмотреть через панель администратора Контент->Инфоблоки. По умолчанию, при создании инфоблока предлагаются стандартные ссылки с GET-запросами и указанием физического адреса директории в которой находятся файлы-триггеры для указанного инфоблока. Например, строка URL страницы детального просмотра #SITE_DIR#/catalog/detail.php?ID=#ELEMENT_ID# говорит о том, что при детальном просмотре страницы вызывается файл-триггер detail.php из директории catalog, которому сообщается ID элемента. Обратите внимание, что для всех трех предлагаемых ссылок передаются id, то есть, это переменные IBLOCK_ID, SECTION_ID и ELEMENT_ID. Чтобы перейти на символьные коды, необходимо заменить эти переменные на, соотвественно, IBLOCK_CODE, SECTION_CODE и ELEMENT_CODE. 

И, как вы понимаете, основным условием того, чтобы у нас были ЧПУ, является, естественно, наличие у каждого элемента своего уникального символьного кода. Это же касается и самих инфблоков, и разделов, если мы собираемся их названия использовать в адресной строке. Поэтому для создаваемого в рамках нашего примера инфоблока, нужно зайти во вкладку Поля, и сделать активным пункт Символьный код и ему починенные.

После этого, при добавлении элемента инфоблока символьный код будет создаваться автоматически. 

Для полноценной реализации ЧПУ можно пойти несколькими путями.

1. Первый и наиболее часто используемый — это введение правил обработки адресов. Суть этого метода состоит в том, что ссылка обрабатывается и превращается в стандартную по определенным правилам. Настройки -> Обработка адресов -> Правила обработки. Там мы вводим условие формирования строки, компонент, для которого это распространяется, файл, который получает данные и правило. Пример такого покажем ниже:

Правило: #^/catalog/(.*)/(.*)/(?[a-zA-Z0-1_-=]){0,1}# 
Компонент: bitrix:catalog 
Файл:/catalog/index.php 
Правило:SECTION_CODE=$1&ELEMENT_CODE=$2

В данном случае, ссылка типа (приведем пример) http://имя_сайта/catalog/notebooks/z10-ultrabook подразумевает вызов файла /catalog/index.php, которому сообщается символьный код раздела — "notebooks" и символьный код товара — "z10-ultrabook". Соответственно в настройках самого инфоблока для URL страницы детального просмотра указываем правило #SITE_DIR#/catalog/#SECTION_CODE#/#ELEMENT_CODE#.
После внесения правил обработки адресов они записываются в файл urlrewrite.php, который находится в корневой директории сайта.

2. Второй путь очень близок и даже подобен первому, и применителен ко многим комплексным компонентам. В данном случае нам нужно перейти в публичную часть сайта, включить режим правки и отредактировать параметры нужного нам компонента, а именно, в закладке Управление адресами страниц включить поддержку ЧПУ,и указать каталог и настройки адресов. 

Затем нужно зайти в настройки самого инфоблока и поменять соотвествующим образом три URL.

3. Первые два варианта отлично подходят для большинства несложных сайтов. В нашей практике таких, на самом деле не очень много, потому как мы работали с крупными проектами и нестандартными решениями для каталогов. Например, случаи, когда каталог состоит из различных групп товаров, у которых абсолютно свои списки пользовательских свойств. Также, через URL могут передаваться не только конкретные секции, но и другие параметры вывода, например, товары по назначению. В данном случае действия повторяют стандартные методы работы с символическими URL, примерно так, как это было описано во втором подразделе этой публикации. Но, у Битрикса есть свои особенности, которые довольно удобно использовать.
Итак, опишем более-менее стандартный пример и при создании инфоблока каталога в разделе URL мы прописываем следующие прафила формирования адресов:

URL страницы информационного блока: #SITE_DIR#/catalog/#IBLOCK_CODE#
URL страницы раздела: #SITE_DIR#/catalog/#IBLOCK_CODE#/#SECTION_CODE#
URL страницы детального просмотра: #SITE_DIR#/catalog/#IBLOCK_CODE#/#SECTION_CODE#/#ELEMENT_CODE#

Как вы можете понять, файлом-триггером в данном случае является /catalog/index.php. Парсинг URL в данном случае производится так:

 

<?

//парсим URL

$URL = $APPLICATION->GetCurPage();

$arURL = array_values(array_filter(explode('/',$URL)));

?>

 

В данном случае мы понимаем, что в $arURL[0] будет храниться слово "catalog", в $arURL[1] — IBLOCK_CODE, в $arURL[2] — SECTION_CODE, в $arURL[3] — ELEMENT_CODE.
При анализе адресов будет понятно, что если в данном массиве есть элементы с 0-го по 2-й, но отсутствует 3-й, то должен отображаться раздел. И так далее. В целом все удобно и довольно трививально в плане программирования. 


Получение разделов и элементов инфоблока


Итак, мы можем узнать, где находимся (в корне инфоблока, в разделе или на детальной странице товара), анализируя только адресную строку по количеству адресных элементов в ней. 
Дальнейшее извлечение — дело техники, хотя опишем несколько не совсем стандартных, но довольно часто встречающихся конструкций.

Для извлечения структуры разделов, у которых помимо всего прочего заданы собственные пользовательские свойства (которые мы указали с префиксом "UF_"), используем следующую конструкцию:

 

<?$res = CIBlockSection::GetList(

            Array("LEFT_MARGIN"=>"ASC"),

            Array("IBLOCK_ID"=>$block_id, "ACTIVE"=>"Y", "GLOBAL_ACTIVE"=>"Y"), 

            true,

            Array("UF_*")

  );

  while($arSection = $res->GetNext())

                {

                    //код вывода

                    }

  ?>

 

Отдельно стоит сказать, что использование в фильтре IBLOCK_ID, а не IBLOCK_CODE, в данном случае обязательно. Иначе пользовательские свойства выводиться не будут (см. документацию, Примечание №1). "UF_*" в данном случае обозначает, что мы забираем все пользовательские свойства для разделов. 

Поскольку мы работаем с символьными кодами из адресной строки, то id инфоблока нам неизвестен. IBLOCK_ID по символьному коду можно найти с помощью метода CIBlock::GetList. Любо же, если инфблоков не много, можно сделать отдельный php-файл, который будет подключаться обычным include и содержать switch-case символьных колов и соответсвующих им IBLOCK_ID.

Для получения элементов раздела инфоблока правомерна следующая конструкция с использованием CIBlockElement::GetList:

 

<?

$arFilter = array( 

        'IBLOCK_ID'=>$iblock_id,

        'SECTION_CODE'=>$arURL[2]

); 

$res = CIBlockElement::GetList(Array("ID"=>"ASC"), $arFilter, false, false, $arSelect); 

 while($ob = $res->GetNextElement()){

   //получаем основные параметры

     $arFields = $ob->GetFields();

     //получаем все свойства   

     $arProps = $ob->GetProperties();

 

?><pre> <?print_r($arFields);?></pre><?

?><pre> <?print_r($arProps);?></pre><?

     }

?>

 

В рамках метода CIBlockElement::GetList для инфоблоков 1.0 в качестве 'IBLOCK_ID' можно указать массив сразу с несколькими значениями, таким образом, обработать одновременно несколько инфоблоков, для 2.0 при указании массива идентификаторов не будут выводиться свойства.