Пытался настроить на днях стандартный инфоблок новостей из поставки демосайта на ЧПУ вида (ниже настройки компонента bitrix:news):
[spoiler]
Добавил правило в обработку адресов, все настройки инфоблока и компонента произвел. Открываю главную страницу - все ок. Открываю страницу новости - все ок.
Открываю страницу секции - @#$ там. "Элемент не найден", видите ли.
Перепроверил. На других сайтах, которые я делал, работает, а тут - нет.
Полез дебажить код компонента.
Оказалось, что при заходе в секцию вот этот кусок возвращает false:
Что ж, уже интереснее, ядро косячит. Лезу в ядро.
А в методе CComponentEngine::ParseComponentPath я вижу...
Что бы вы подумали? Волшебный кролик.
Нет, в методе я вижу следующий код:
Без меня меня женили называется, я запросил например /news/somesection/, а Битрикс будет считать, что я запросил /news/somesection/index.php.
Получается, что мое объявление константы BX_DISABLE_INDEX_PAGE было фикцией - в методе эта константа работать не будет.
Ну да ладно, смотрим дальше.
А дальше нерабочий код применительно к моей ситуации.
Метод, значится, проверяет соответствие запрошенного урла шаблонам, которые я понаписал в настройках компонента. Не забываем, что не того урла, который я на самом деле запросил, а того, который Битрикс думает что я запросил. То есть с index.php на конце.
Запросил я /news/somesection/, и Битрикс смотрит по порядку (порядок кстати тоже странный, сначала rss проверяется, потом rss_section, потом detail, и только потом section).
И ожидаемо ловит, что я якобы запросил элемент /news/somesection/index.php (напоминаю, $currentPageUrl по мнению Битрикса /news/somesection/index.php). А элемента-то такого нема.
До проверки секции не добрался дружок.
Теперь возникает другой вопрос - а как же работает ЧПУ на тысячах других проектов?
Ответ легко находится, достаточно посмотреть на настройки любого типового проекта.
Там для детальной страницы урл имеет вид #SECTION_CODE#/#ELEMENT_CODE#/, на конце слэш, а не .php.
Изменил настройки компонента - и все заработало.
Но осадочек остался. Не дал мне битрикс сделать такое ЧПУ, какое я хотел (и какое кстати более правильное с семантической точки зрения, ведь детальная страница новости - это страница, а не директория, как ее все любят оформлять в ЧПУ. Вообще не пойму откуда пошла эта сео-мода все на слэш заканчивать, видимо многие сеошники - латентные слэшеры).
Вот и думаю, написать что ли в ТП, чтобы поставили программистам задачку по доработке этого класса в трекер...
"SEF_URL_TEMPLATES" => Array( "section" => "#SECTION_CODE#/", "detail" => "#SECTION_CODE#/#ELEMENT_CODE#.php", "rss" => "rss/", "rss_section" => "#SECTION_CODE#/rss/" ), |
Добавил правило в обработку адресов, все настройки инфоблока и компонента произвел. Открываю главную страницу - все ок. Открываю страницу новости - все ок.
Открываю страницу секции - @#$ там. "Элемент не найден", видите ли.
Перепроверил. На других сайтах, которые я делал, работает, а тут - нет.
Полез дебажить код компонента.
Оказалось, что при заходе в секцию вот этот кусок возвращает false:
$componentPage = CComponentEngine::ParseComponentPath( $arParams["SEF_FOLDER"], $arUrlTemplates, $arVariables ); |
Что ж, уже интереснее, ядро косячит. Лезу в ядро.
А в методе CComponentEngine::ParseComponentPath я вижу...
Что бы вы подумали? Волшебный кролик.
Нет, в методе я вижу следующий код:
function ParseComponentPath($folder404, $arUrlTemplates, &$arVariables, $requestURL = False) { global $APPLICATION; if (!isset($arVariables) || !is_array($arVariables)) $arVariables = array(); if ($requestURL === False) $requestURL = $APPLICATION->GetCurPage(true); |
Без меня меня женили называется, я запросил например /news/somesection/, а Битрикс будет считать, что я запросил /news/somesection/index.php.
Получается, что мое объявление константы BX_DISABLE_INDEX_PAGE было фикцией - в методе эта константа работать не будет.
Ну да ладно, смотрим дальше.
А дальше нерабочий код применительно к моей ситуации.
function __CheckPath4Template($pageTemplate, $currentPageUrl, &$arVariables) { $pageTemplateReg = preg_replace("'#[^#]+?#'", "([^/]+?)", $pageTemplate); if (substr($pageTemplateReg, -1, 1) == "/") $pageTemplateReg .= "index\\.php"; $arValues = array(); if (preg_match("'^".$pageTemplateReg."$'", $currentPageUrl, $arValues)) { $arMatches = array(); if (preg_match_all("'#([^#]+?)#'", $pageTemplate, $arMatches)) { for ($i = 0, $cnt = count($arMatches[1]); $i < $cnt; $i++) $arVariables[$arMatches[1][$i]] = $arValues[$i + 1]; } return True; } return False; } |
Метод, значится, проверяет соответствие запрошенного урла шаблонам, которые я понаписал в настройках компонента. Не забываем, что не того урла, который я на самом деле запросил, а того, который Битрикс думает что я запросил. То есть с index.php на конце.
Запросил я /news/somesection/, и Битрикс смотрит по порядку (порядок кстати тоже странный, сначала rss проверяется, потом rss_section, потом detail, и только потом section).
И ожидаемо ловит, что я якобы запросил элемент /news/somesection/index.php (напоминаю, $currentPageUrl по мнению Битрикса /news/somesection/index.php). А элемента-то такого нема.
До проверки секции не добрался дружок.
Теперь возникает другой вопрос - а как же работает ЧПУ на тысячах других проектов?
Ответ легко находится, достаточно посмотреть на настройки любого типового проекта.
Там для детальной страницы урл имеет вид #SECTION_CODE#/#ELEMENT_CODE#/, на конце слэш, а не .php.
Изменил настройки компонента - и все заработало.
Но осадочек остался. Не дал мне битрикс сделать такое ЧПУ, какое я хотел (и какое кстати более правильное с семантической точки зрения, ведь детальная страница новости - это страница, а не директория, как ее все любят оформлять в ЧПУ. Вообще не пойму откуда пошла эта сео-мода все на слэш заканчивать, видимо многие сеошники - латентные слэшеры).
Вот и думаю, написать что ли в ТП, чтобы поставили программистам задачку по доработке этого класса в трекер...