вторник, 12 мая 2015 г.

Как добавить слеш в конце URL в 1С-Битрикс.

     Проблема эта возникает не только в Битрикс, но в любых CMS или фреймворках. Главная неприятность - поисковики не могут найти и проиндексировать страницу вида http://page, которая должна отсылаться на страницу вида http://page/ - то есть со слешем на конце. Для большинства сайтов задача решается довольно просто, и решение это не раз приводилось в Интернет - например, вот здесь. С той же самой проблемой я столкнулся и на сайтах, которые у меня на техподдержке - http://casinojet.ru , http://casinojet.net и http://english-yes.ru . Но со своими особенностями - я обнаружил, что в Битрикс страницы при добавлении слеша известными методами ведут себя не так, как обычно.
     Самое интересное - на первом уровне вложенности, как правило, Битрикс слеши добавляет. Где это спрятано в системе - я искать не стал, имхо Битрикс очень большой, искать замучаешься. Добавляет их, как правило, и на большем числе уровней вложенности, если каталоги и страницы созданы вручную через административный или публичный интерфейс - ну то есть страницы вида http://catalog1/catalog2/page вполне нормально перекидываются на такую же страничку, но со слешем в конце. А вот если некоторое количество секций созданы комплексным компонентом Битрикс, неважно каким - каталогом, торговым каталогом, новостями и т.п. - то ни страницы секций, ни детальные страницы слеш не добавляют. Следовательно, при автоматическом формировании страниц встроенный механизм не работает, и нужно добавлять слеши вручную.
     Итак, тестируем приведенное выше решение из интернета, пытаемся добавить слеши вручную.
     Способ 1 - изменить файл .htaccess таким образом:
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_URI} !(.*)/$
RewriteRule ^(.*[^/])$ $1/ [L,R=301]

категорически мне не понравился. Работает тоже только на первом уровне вложенности, хотя, конечно, можно добавить подобное правило и для других значений RewriteBase, но тогда черт ногу сломит в правилах .htaccess и все время нужно следить, чтобы нужные правила не взаимодействовали как-нибудь криво с другими правилами оттуда же. У меня, например, при добавлении этого правила, в самой админке Битрикса (о ужас!) произошли изменения - остались видны верхнее и левое меню, а в рабочей области на всех пунктах меню, куда ни перейди, появлялась волшебная надпись "сорри, такой ресурс не обнаружен". Вот вам и .htaccess. Убрал это правило на...
     Способ 2 - добавить слеш программно интуитивно показался мне тем, что надо. Ведь можно же тогда прикрутить к нему какие угодно pHp условия и использовать его очень гибко, подумал я. Но все оказалось еще проще. Автор вышеприведенной статьи предложил сделать это вот так:
// Получаем URI для проверки
$uri = preg_replace("/\?.*/i",'', $_SERVER['REQUEST_URI']);
 
if (strlen($uri)>1) {// если не главная страница...
  if (rtrim($uri,'/')."/"!=$uri) {
    header("HTTP/1.1 301 Moved Permanently");
    header('Location: http://'.$_SERVER['SERVER_NAME'].str_replace($uri, $uri.'/', $_SERVER['REQUEST_URI']));
    exit();    
  }
}

Замечательно. Ставим - работает. Но - опять же только на первом уровне вложенности или на вручную созданных секция, подсекциях и так далее. На автоматически формируемых компонентах - категорически не хочет. Ясно - у Битрикса собственный алгоритм формирования не только страниц, но и адресов их - в зависимости от того, компонент их формирует или сделаны они вручную. Искать смысла нет, где и как это сделано, проще перезаписать все это там, где Битрикс позволяет кастомизацию, и сделать это как можно проще и техничнее. Кроме того, мне не понравилась вторая строка с функцией header - почему так сложно? И я упростил ее, так что решение у меня стало выглядеть вот так:
<?
// Программное добавление слеша к адресам. Получаем URI для проверки
$uri = preg_replace("/\?.*/i",'', $_SERVER['REQUEST_URI']);
 
if (strlen($uri)>1) {
  if (rtrim($uri,'/')."/"!=$uri) {
    header("HTTP/1.1 301 Moved Permanently");
    header('Location: http://'.$_SERVER['SERVER_NAME'].$uri.'/');
    exit();    
  }
}
?>

Далее, я добавил его в шаблон (там где и в Битриксе слеши почему-то не добавлялись - кто знает, кто и когда и с какими настройками ставил разные версии Битрикса на всех нужных мне сайтах, - они стали добавляться на первом уровне вложенности). А далее - я зашел на каждую страницу, где были компоненты, обнаружил, что они создают собственные индексные страницы вида http://section/index.php и добавил эту конструкцию в самый верх каждой независимой индексной страницы. После чего слеши стали добавляться автоматически и редирект срабатывал уже на любом количестве уровней вложенности, например, и на страницах вида http://section/subsection/.../page, сколько бы уровней ни генерировал автоматически данный комплексный компонент.