Нынешняя проблема характерна для актуальной 25.600.0 версии главного модуля для компонентов bitrix:system.pagenavigation в bitrix:news.list в ЧПУ настроенном вручную. Что может пойти не так в компонентах, которым по 20 лет, и которые должны быть отлажены?
Для bitrix:system.pagenavigation в bitrix:catalog.section такой проблемы нет
Пожалуйста посмотрите статью
bitrix:system.pagenavigation тоже формирует параметры из $_GET. Очень трудно использовать этот компонент с ЧПУ через urlerewrite. В постраничной навигации на странице /catalog/tires/ будут ссылки вида /catalog/tires/?SECTION_CODE=tires&PAGEN_1=2
Причина в компоненте bitrix:system.pagenavigation, где такой код:
$arResult["NavQueryString"] = htmlspecialcharsbx(DeleteParam($delParam)); |
Сначала DeleteParam прибавляет все параметры из $_GET а потом удаляет некоторые
function DeleteParam($ParamNames) { if (empty($_GET)) { return ''; } $aParams = $_GET; foreach (array_keys($aParams) as $key) { foreach ($ParamNames as $param) { if (strcasecmp($param, $key) == 0) { unset($aParams[$key]); break; } } } return http_build_query($aParams, "", "&"); } |
Причём эта проблема есть в bitrix:news.list, в bitrix:catalog.section её нет
Обратите внимание - поведение компонента зависит исключительно от наличия $arParams["BASE_LINK"]. bitrix:catalog.section передаёт параметр, а news.list не передаёт
if(($arParams["BASE_LINK"] ?? '') <> '') { if(($pos = mb_strpos($arParams["BASE_LINK"], "?")) !== false) { $arResult["sUrlPath"] = mb_substr($arParams["BASE_LINK"], 0, $pos); $arResult["NavQueryString"] = mb_substr($arParams["BASE_LINK"], $pos + 1); } else { $arResult["sUrlPath"] = $arParams["BASE_LINK"]; $arResult["NavQueryString"] = ""; } } else { $arResult["sUrlPath"] = GetPagePath(false, false); $delParam = array_merge( array( "PAGEN_".$dbresult->NavNum, "SIZEN_".$dbresult->NavNum, "SHOWALL_".$dbresult->NavNum, "PHPSESSID", ), \Bitrix\Main\HttpRequest::getSystemParameters() ); $arResult["NavQueryString"] = htmlspecialcharsbx(DeleteParam($delParam)); } $arResult['sUrlPathParams'] = $arResult['sUrlPath'].'?'.($arResult['NavQueryString'] <> ''? $arResult['NavQueryString'].'&' : ''); |
Конечно, Битрикс должен исправить свой компонент навигации. Нельзя прибавлять параметры из $_GET.
Но пока есть 2 варианта исправить
1. Исправление в параметрах news.list - рекомендуемый Битриксом, но не совсем хороший способ
Сейчас мы можем посчитать за Битрикс страницу, относительно которой строить навигацию.
"PAGER_BASE_LINK_ENABLE" => "Y",
"PAGER_BASE_LINK" => $url,
Это надо делать на всех страницах, где есть компонент списка новостей.
Можно явно, если все параметры убрать - такой способ решит большинство проблем (кроме задач с фильтрами)
$url = "/news/"; |
Но если есть фильтр, то надо повозиться. Можно все параметры убирать, кроме нужных. Можно убирать только служебные.
Один из примеров - убрать все служебные параметры: это работает в нашем примере для PAGEN_1.
<? $arDeleteParams = [ "PHPSESSID", "PAGEN_1", "SIZEN_1", "SHOWALL_1", //"PAGEN_2", "SIZEN_2", "SHOWALL_2", ]; $arDeleteSystemParams = \Bitrix\Main\HttpRequest::getSystemParameters(); $arDeleteParams = array_merge( $arDeleteParams, $arDeleteSystemParams); // https://dev.1c-bitrix.ru/community/webdev/user/25773/blog/45676/ // можно $url = getCurPageParamD7( [],$arDeleteParams ); $request = \Bitrix\Main\Application::getInstance()->getContext()->getRequest(); $uriString = $request->getRequestUri(); $uri = new \Bitrix\Main\Web\Uri($uriString); $uri->deleteParams($arDeleteParams); // ничего не добавляем $uri->addParams($arAddParams); $url = $uri->getUri(); ?> |
Вызов компонента
<?$APPLICATION->IncludeComponent( "bitrix:news.list", ".default", [ *** "PAGER_BASE_LINK_ENABLE" => "Y", "PAGER_BASE_LINK" => $url, "PAGER_PARAMS_NAME" => "arrPager" ], false );?> |
2. Исправление в шаблоне system.pagenavigation - хороший способ, если надо сохранить параметры url, кроме системных
Надо в шаблоне сделать свой result_modifier.php и посчитать в нём заново url. Этот код пишем в одном месте и используем во всех компонентах свой шаблон навигации.
Этот способ универсальный. Он знает свой номер PAGEN_
<?php if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED!==true)die(); //echo $arParams["BASE_LINK"] // Askaron заново вычисляем путь, потому что стандартный компонент берёт url из $_GET и не работает нормально с ЧПУ // Мы хотим убрать SECTION_CODEиз ссылок // Вместо /catalog/tires/?SECTION_CODE=tires&PAGEN_1=2 сделать /catalog/tires/?PAGEN_1=2 // Если было $arResult["NavQueryString"] = htmlspecialcharsbx(DeleteParam($delParam)); $delParam = array_merge( array( "PAGEN_".$arResult["NavNum"], "SIZEN_".$arResult["NavNum"], "SHOWALL_".$arResult["NavNum"], "PHPSESSID", ), \Bitrix\Main\HttpRequest::getSystemParameters() ); $path = ""; $request = \Bitrix\Main\Application::getInstance()->getContext()->getRequest(); $uriString = $request->getRequestUri(); $uri = new \Bitrix\Main\Web\Uri($uriString); $uri->deleteParams($delParam); //$arResult[ "sUrlPathParamsNoPagen" ] = $uri->getUri(); $arResult[ "sUrlPath" ] = $uri->getPath(); $arResult[ "NavQueryString" ] = $uri->getQuery(); $arResult[ "sUrlPathParams_no_last_amp" ] = $uri->getUri(); $arResult[ "sUrlPathParams" ] = $arResult[ "sUrlPathParams_no_last_amp" ]; if ( mb_strlen( $uri->getQuery() ) > 0 ) { $arResult[ "sUrlPathParams" ] .= "&"; } else { $arResult[ "sUrlPathParams" ] .= "?"; } // Если хотим, чтобы не было ошибок валидатора: //$arResult[ "~NavQueryString" ] = $arResult[ "NavQueryString" ]; //$arResult[ "~sUrlPathParams" ] = $arResult[ "sUrlPathParams" ]; //$arResult[ "NavQueryString" ] = htmlspecialcharsbx($arResult[ "~NavQueryString" ]); //$arResult[ "sUrlPathParams" ] = htmlspecialcharsbx($arResult[ "~sUrlPathParams" ]); |