Универсальная красивая постраничка на Битрикс, фикс и улучшение
Антон Долганин7 Августа 2015 13:5627693
Два года назад я сделал универсальное решение для создания какой-душе-угодно постранички (например, /catalog/pagen2/). Вот этот пост. Все было хорошо, но в Битрикс 15.5 это сломалось по определенным причинам. Детали под катом.
Ломалась постраничка в том случае, если вы натравливали ее на компонент, лежащий внутри комплексного. Причиной был вот этот метод, в котором $requestURL передавался равный false, и определялся он уже по методу D7. И грязный хак с REQUEST_URI шел мимо.
Писал я в техподдержку Битрикс с поиском общего решения, посоветовали только одно - внедряться непосредственно до исполнения Битрикс. Самый правильный способ это сделать, это использовать auto_prepend_file, определив ее в корневом .htaccess.
Если вы внедряете с нуля технологию, делайте все как в раннем посте, кроме обработчика, его делать не надо, и потом переходите к описанию фикса.
Если вы уже внедряли ее раньше и пришли за фиксом:
1. Удаляете обработчик.
2. Создаете файл /bitrix/pagen.php вот такого содержания:
http://bxapi.ru/code/j2xQ0LHjrzwGrnf/ Обратите внимание, код регулярного выражения вам надо поправить согласно вашего правила формирования URL, если он отличается от рассматриваемого здесь варианта (pagen1/).
3. В файл /.htaccess вписываете такую директиву:
php_value auto_prepend_file "***/bitrix/pagen.php"
Где вместо трех звездочек ставите ваш док.рут, узнать который можно хотя бы выполнив такой код в php-консоли: echo $_SERVER["DOCUMENT_ROOT"];
Файл правьте только посредством ssh/ftp, и обязательно удалите строчку, если сайт оказался нерабочим.
По идее все должно работать.
Теперь что насчет улучшения. $newUrl я получаю немного другим способом, так как боты частенько атаковывали сайт и подмешивали в постраничку различный мусор.
Вариант первый, это то, что я исправил в прилагаемом файле. Получаем в лоб путь до основной директории постранички из SCRIPT_NAME. Вариант второй, если финт не прокатит по причине динамического URL категории (например, /catalog/tv/, где tv динамика). Тут вам уже самим надо доработать в зависимости от специфики проекта.
Ну а если боты не атакуют, то и вовсе оставить первый вариант шаблона.
Спасибо за фикс! Только вот есть одна проблемка. В .htaccess уже вписано подключение файла для сканирования Веб-антивирусом до начала буферизации (см. здесь). Поэтому вариант с auto_prepend_file не получается использовать без потерь. Есть обходные пути еще?
1. Инклудить в htaccess один общий файл (не знаю, /bitrix/prepend.php), внутри которого заинклудить нужные вам файлы (в частности проактивки и из поста).
2. Воткнуть в /bitrix/header.php до подключения файла Битрикс файл из поста. Битрикс его никогда не трогает при обновлениях, и он не считается файлом ядра (так что всякие правила вы тоже не нарушите).
Здравствуйте. Попробовал сделать постраничку по Вашему методу. Для списка новстей вообще шикарно:)
Но когда пробую подключить для комплексного компонента - получаю "элемент не найден". Подскажите, в чем можеть быть проблема? Все делал по фиксу.
Виктор, возможно, виной был п.2 в посте, я его поправил (выделил красным), плюс изменил код /bitrix/pagen.php). Имеет смысл перелить этот файл и еще раз проверить.
На моем сайте постраничная навигация находится на динамической странице, к примеру, возьмем раздел /catalog/mezhkomnatnye_dveri/
Я все сделал по инструкции и у меня сформировались ссылки на страницы, вот такого типа: /catalog/pagen2/
которые не листают раздел
Как же быть? У меня /catalog/ это папка каталога товаров, /mezhkomnatnye_dveri/ - динамическая страница раздела, который надо листать.
Ссылки "/catalog/mezhkomnatnye_dveri/pagen2/" - заработали.
но перестала работать ссылка для отображения сразу всех элементов "/catalog/mezhkomnatnye_dveri/?SHOWALL_1=1"
Как же ее починить?
Сделал все по Вашему шаблону, по второму, но теперь постранички ссылаются обратно на каталог. Брал первый шаблон, постранички ссылаются на первую страницу, а если второй шаблон, то вовсе на каталог. Делал все по инструкции, не могу понять в чем проблема(
Всё работало в первом уровне раздела, например /news/page2/, а вот в /news/section/page2/ уже нет (не комплексный компонент).
Всё же добавил pagen.php.
А нет ли в htaceess авто-определения DOCUMENT_ROOT, что бы не писать его явно?
Да, pagen.php как раз и спас.
Про константу htaccess еще погуглил - оказывается там и правда её не может быть из-за особенностей работы самого файла. А хотелось как-то универсально написать
Здравствуйте!. Я использую ваш метод. Все отлично работает в каталоге. Там везде PAGEN_1=xxx. Но в при переходе на страницу поиска там идет нумерация с PAGEN_2=xxx Страница при клике меняет товары, а вот сама пагинация не листается. Как заставить работать с парамером PAGEN_2=xxx. Файлы прилагаю в архиве. Вот из init.php
//пагинатор с ЧПУ
AddEventHandler('main', 'OnPageStart', array('CMainhandlers', 'OnPageStartHandler'));
class CMainhandlers {
public static function OnPageStartHandler() {
if (isset($_GET['page'] && intval($_GET['page']>0) {
$GLOBALS['PAGEN_1'] = $_REQUEST['PAGEN_1'] = $_GET['PAGEN_1'] = $_GET['page'];
unset($_GET['page'], $_REQUEST['page'], $GLOBALS['page'];
}
$GLOBALS['APPLICATION']->reinitPath();
}
К сожалению, скрипт работает только с PAGEN_1. Вы можете обратиться к разработчику, чтобы он доплил и до PAGEN_2. По идее, это просто дополнительные условия в коде.
Универсально не сделать.
Антон, может мне подскажите.
1) Создал файл pagen.php в корне папки bitrix, прописал в нем ваш код.
2) вставляю в .htaccess код по редиректу и файлу pagen.php
3) Применил код шаблона из первой статьи (со второй статьи ссылки формируются неверно). Ссылки формируются верного вида pagen1, pagen2...
Проблема в том, что не переходит по ссылкам. Т.е. перезагрузка страницы происходит, урл в адресной строке меняется, но контент тот же что на первой странице и в пагинации выделена страница 1.
Видел писали об этом люди, но никто не поделился решением этой проблемы. На каком этапе ее искать? Подскажите пожалуйста.
Антон здраствуйте.
Не могу разобратся с одной ситуацией. Пагинация работает но частично. Получается что для такого типа URL работает: http://mysite.net/catalog/pagen2/ а вот для http://mysite.net/catalog/mobile/pagen2/ нет. Но не выскакивает ошыбка, а просто не перелистывает страницу и все время находится в 1 разделе. Вчем может быть причина.
Версия битрикс 16.0.9 Бизнес
Спасибо за помощь.
Антон, здравствуйте!
Все сделали как описано выше с фиксом. Работает везде.
Но есть нюанс, задваивание страниц, то есть работает и по старому:
domen/news/?PAGEN_1=2
и по новому
domen/news/pagen2/
Все бы ничего, но поисковики откуда то берут эти старые ссылки, хотя на сайте их нет.
Все сделали еще в мае месяце, а в поисковиках и дальше появляются ссылки вида ?PAGEN_1=2
Что сделать с этими задвоенными ссылками? Подскажите, пожалуйста!
Добрый день, а вы не подскажете как сделать 301 редирект из ?PAGEN_1=* на страницы /pagen*/
Когда я делаю редирект, ложится сайт( Есть какие то у Вас идеи?
* это нумерация страницы:)
Здравствуйте,
после добавления строки php_value auto_prepend_file "../bitrix/pagen.php" в .htaccess перестает работать авторизация в административной части, то есть после попытки залогинитьтся страница просто перегружается без полей для ввода, если страницу обновить - то опять форма авторизации. Убирая php_value auto_prepend_file "../bitrix/pagen.php" - авторизация начинает работать нормально(
Сделал все как написано, но у меня почему-то получается ссылка вида:
http://доменсайта/pagen3/
А должна получиться:
http://доменсайта/kedrovye-bochky-fytobochky/pagen3/
Разобрался с сылкой. Теперь она формируется корректно. Но не получается по ней перейти. 404-ю ошибку выдает. Я, кажется, понимаю что проблема в регулярном выражении. Но может подскажите, как его переделать, чтобы можно было попасть, например, по этому пути: http://доменсайта/kedrovye-bochky-fytobochky/pagen3/
Блин Тяжело разбираться, если с правилами перенаправления не знаком толком. В общем я все же сделал, что у меня формируется ссылка правильно и перенаправление идет. Вот только какую бы страницу пагинации я не набирал - все равно отображается первая страница.
еще пришлось убрать правило RewriteRule ^(.*)/page([\d]+)/ /$1/?PAGEN_1=$2 [L,QSA] из .htaccess так как из-за него при нажатии на пагинацию, если находишься не на первой странице, создавался дубль /pageN/ в конце адресной строки. Т. е. получалось так /сайт/фитобочки/page1/page4/
Помогите теперь решить вопрос с отображением нужной страницы пагинации, а не всегда первой.
Всем привет, столкнулся с проблемой на хостинге рэг.ру, что по правилу
RewriteRule ^(.*)/(\d+) /$1/?PAGEN_1=$2 [QSA,L]
картинки по пути сайт/upload/iblock/534/file.png открываются с 403 ошибкой, пришлось выкрутиться, добавив фильтрацию по файлам, итого работающее правило:
Почему-то в блоге на сайте битрикса не добавляется комментарий. Поэтому задам тут.
А разве команда
RewriteRule ^(.*)/pagen([\d]+)/ /$1/?PAGEN_1=$2 [L,QSA]
не прибьет все остальные GET параметры, например, фильтры?
Я $_GET['PAGEN_1'] прописал сразу в файле pagen.php, вроде работает нормально.
Здравствуйте. Спасибо за отличное решение! Оно помогло во многих проектах. Может вы сталкивались или адаптировали свое решение под ajax элементы? У меня ajax каталог с ajax фильтрацией, несколько ajax новостных лент. Компоненты стандартные. Сама пагинация генерируется с нужными ссылками вида
catalog/page-n/
При переходе через ссылку с помощью ajax подгрузки в адресной строке возвращается старое PAGEN_1=2. Работают оба варианта ссылок, что для сео очень плохо, нет возможности прикрутить к страницам пагинации назначение правильных метатегов и директив яндекса(но это уже не к пагинации вопрос).
По аякс не подскажу, к сожалению. Обычно запрашивали данные по аякс-каналу какому-нибудь, который наглухо запрещали к индексации (или даже недоступности кроме как по аякс-запросу).
Дело в том что для битрикса ссылка /page-2/ не видна. Поэтому композит и отдает страницу с кешем страницы без пагинации. Это конечно печально. Но можете в настройках композита указать параметр PAGEN_1 - при этом композит срабатывать не будет. Но это конечно не решение.
Не получилось на 20 версии, все сделал по инструкции, и по несколько раз, в шаблоне ссылки заменились, но после перехода на страницу пишет элемент не найден
Тут два варианта:
1. Инклудить в htaccess один общий файл (не знаю, /bitrix/prepend.php), внутри которого заинклудить нужные вам файлы (в частности проактивки и из поста).
2. Воткнуть в /bitrix/header.php до подключения файла Битрикс файл из поста. Битрикс его никогда не трогает при обновлениях, и он не считается файлом ядра (так что всякие правила вы тоже не нарушите).
Но когда пробую подключить для комплексного компонента - получаю "элемент не найден". Подскажите, в чем можеть быть проблема? Все делал по фиксу.
К примеру у меня такой
/content/news/5/38121/
Пробовал оставлять pagen2 - тоже на элемент хочет уходить.
У меня работает:
На моем сайте постраничная навигация находится на динамической странице, к примеру, возьмем раздел /catalog/mezhkomnatnye_dveri/
Я все сделал по инструкции и у меня сформировались ссылки на страницы, вот такого типа: /catalog/pagen2/
которые не листают раздел
Как же быть? У меня /catalog/ это папка каталога товаров, /mezhkomnatnye_dveri/ - динамическая страница раздела, который надо листать.
Вы файл шаблона из первого поста скачали или из данного? По идее вам подойдет предыдущий вариант.
Взял из данного поста, сейчас попробую взять из первого и отпишусь.
Ссылки "/catalog/mezhkomnatnye_dveri/pagen2/" - заработали.
но перестала работать ссылка для отображения сразу всех элементов "/catalog/mezhkomnatnye_dveri/?SHOWALL_1=1"
Как же ее починить?
И кнопка "Все" при это сломалась
Сделал все по Вашему шаблону, по второму, но теперь постранички ссылаются обратно на каталог. Брал первый шаблон, постранички ссылаются на первую страницу, а если второй шаблон, то вовсе на каталог. Делал все по инструкции, не могу понять в чем проблема(
Всё работает, версия 15.5.9.
Всё же добавил pagen.php.
А нет ли в htaceess авто-определения DOCUMENT_ROOT, что бы не писать его явно?
Про константу htaccess еще погуглил - оказывается там и правда её не может быть из-за особенностей работы самого файла. А хотелось как-то универсально написать
//пагинатор с ЧПУ
AddEventHandler('main', 'OnPageStart', array('CMainhandlers', 'OnPageStartHandler'));
class CMainhandlers {
public static function OnPageStartHandler() {
if (isset($_GET['page'] && intval($_GET['page']>0) {
$GLOBALS['PAGEN_1'] = $_REQUEST['PAGEN_1'] = $_GET['PAGEN_1'] = $_GET['page'];
unset($_GET['page'], $_REQUEST['page'], $GLOBALS['page'];
}
$GLOBALS['APPLICATION']->reinitPath();
}
}
Заранее благодарен за ответ!
К сожалению, скрипт работает только с PAGEN_1. Вы можете обратиться к разработчику, чтобы он доплил и до PAGEN_2. По идее, это просто дополнительные условия в коде.
Универсально не сделать.
1) Создал файл pagen.php в корне папки bitrix, прописал в нем ваш код.
2) вставляю в .htaccess код по редиректу и файлу pagen.php
3) Применил код шаблона из первой статьи (со второй статьи ссылки формируются неверно). Ссылки формируются верного вида pagen1, pagen2...
Проблема в том, что не переходит по ссылкам. Т.е. перезагрузка страницы происходит, урл в адресной строке меняется, но контент тот же что на первой странице и в пагинации выделена страница 1.
Видел писали об этом люди, но никто не поделился решением этой проблемы. На каком этапе ее искать? Подскажите пожалуйста.
Не могу разобратся с одной ситуацией. Пагинация работает но частично. Получается что для такого типа URL работает:
Версия битрикс 16.0.9 Бизнес
Спасибо за помощь.
Спасибо за ваш скрипт.
Подскажите и где поправить что бы получилось /?pagen2
Заранее спасибо за ответ.
RewriteRule ^(.*)/?pagen([\d]+) /$1/?PAGEN_1=$2 [L,QSA]
template
$newUrl .= '?pagen'.intval($v);
Так не срабатывает.
Все сделали как описано выше с фиксом. Работает везде.
Но есть нюанс, задваивание страниц, то есть работает и по старому:
domen/news/?PAGEN_1=2
и по новому
domen/news/pagen2/
Все бы ничего, но поисковики откуда то берут эти старые ссылки, хотя на сайте их нет.
Все сделали еще в мае месяце, а в поисковиках и дальше появляются ссылки вида ?PAGEN_1=2
Что сделать с этими задвоенными ссылками? Подскажите, пожалуйста!
Антон, подскажите, как вернуть путь к текущей странице с пагинацией, чтобы использовать страницы типа domen/news/pagen2/ в canonical?
Разве этот метод не подходит?
$APPLICATION->GetCurPage();
На странице: domen/news/pagen2/ и domen/news/pagen3/ и т.д.
$APPLICATION->GetCurPage(); выводит domen/news/
$APPLICATION->GetCurPage();
выводит просто /news/
без домена и без самих страниц
Когда я делаю редирект, ложится сайт( Есть какие то у Вас идеи?
* это нумерация страницы:)
А у вас какой редирект точно записан? (правило)
после добавления строки php_value auto_prepend_file "../bitrix/pagen.php" в .htaccess перестает работать авторизация в административной части, то есть после попытки залогинитьтся страница просто перегружается без полей для ввода, если страницу обновить - то опять форма авторизации. Убирая php_value auto_prepend_file "../bitrix/pagen.php" - авторизация начинает работать нормально(
Идей нет. Поможет только отладка. Но с этим не смогу помочь, к сожалению.
http://доменсайта/pagen3/
А должна получиться:
http://доменсайта/kedrovye-bochky-fytobochky/pagen3/
Подскажите, пожалуйста, почему так?
еще пришлось убрать правило RewriteRule ^(.*)/page([\d]+)/ /$1/?PAGEN_1=$2 [L,QSA] из .htaccess так как из-за него при нажатии на пагинацию, если находишься не на первой странице, создавался дубль /pageN/ в конце адресной строки. Т. е. получалось так /сайт/фитобочки/page1/page4/
Помогите теперь решить вопрос с отображением нужной страницы пагинации, а не всегда первой.
Кстати такая же проблема. Ссылка формируется а вот куда не кликни все равно показывает первую.
А разве команда
RewriteRule ^(.*)/pagen([\d]+)/ /$1/?PAGEN_1=$2 [L,QSA]
не прибьет все остальные GET параметры, например, фильтры?
Я $_GET['PAGEN_1'] прописал сразу в файле pagen.php, вроде работает нормально.
Код файла pagen.php
Если у вас подобных готовых решений нет, то может подскажите в какую сторону копать? Заранее спасибо
По аякс не подскажу, к сожалению. Обычно запрашивали данные по аякс-каналу какому-нибудь, который наглухо запрещали к индексации (или даже недоступности кроме как по аякс-запросу).
Может есть таки возможность адаптировать под композит?