Иногда очень хочется (особенно если ты заказчик, а не разработчик), сделать так, чтобы количество записей, выводимых на странице с помощью Views, зависело от номера страницы.
Например: на первой странице - одна запись (чтобы не навязывать их пользователю), а на остальных - по четыре (чтобы не нужно было постоянно жмякать "далее").
Или так: на первой - 3, на второй - 10 (если пользователю интересно, значит покажем еще больше), на остальных по 20 (для фанатов, осиливших больше двух страниц).
Примеров можно придумать много, в зависимости от философии сайта и пифагорских взглядов заказчика. Но беда в том, что навигация Views работает по принципу: на каждой странице одинаковое количество записей с одинаковым сдвигом относительно начала.
Гугление показало странный результат: ни кому это не нужно (а как же я?!). Пришлось изобретать, чем и спешу поделиться:
Идея проста - каждый раз при запросе страницы менять смещение и лимит на количество выводимых записей. Для этого был выбран hook_views_post_build.
При этом информацию о необходимом числе записей для конкретных страниц (limit) хранить в массиве следующего вида:
<?php
$limits["default"] = количество записей по умолчанию;
$limits[номер страницы] = количество записей для этой страницы;
?>
а смещение (offset) рассчитывать как сумму всех записей на предыдущих страницах:
<?php
$offset=0;
for($i = 0; $i<$current_page; $i++)
{
$offset += (isset($limits[$i])) ? $limits[$i] : $limits["default"];
}
?>
Поскольку при этом количество страниц скорее всего будет другим, то в hook_views_post_execute, производить их пересчет:
<?php
$realy_pager_total = 0;
while($total_rows>0){
$realy_pager_total++;
$total_rows -= (isset($limits[$i])) ? $limits[$i] : $limits["default"];
$i++;
}
$pager_total[0] = $realy_pager_total;
?>
Получившийся в результате модуль довольно топорен и не содержит никакой админской составляющей, потому что в тайне надеюсь, что есть более правильное решение, которое мне здесь и подскажут. Но если что, вот он в архиве, а вот наяву:
$limits["default"]= (int) $view->query->pager->options['items_per_page'];
if($view->name=="НАЗВАНИЕ НУЖНОЙ ВЬЮХИ"){
$limits[0]=1;
$limits[1]=2;
$limits[4]=5;
}
return $limits;
}
function dynamic_views_pager_views_post_build(&$view){
$limits = get_limits($view);
if(count($limits)>1){
$current_page = $view->query->pager->current_page;
$offset=0;
for($i = 0; $i<$current_page; $i++)
{
$offset += (isset($limits[$i])) ? $limits[$i] : $limits["default"];
}
$view->query->limit = (isset($limits[$current_page])) ? $limits[$current_page] : $limits["default"];
$view->query->offset = $offset;
}
}
function dynamic_views_pager_views_post_execute(&$view) {
global $pager_total;
$total_rows = $view->total_rows;
$limits = get_limits($view);
$i = 0;
$realy_pager_total = 0;
while($total_rows>0){
$realy_pager_total++;
$total_rows -= (isset($limits[$i])) ? $limits[$i] : $limits["default"];
$i++;
}
$pager_total[0] = $realy_pager_total;
}
Вложение | Размер |
---|---|
dynamic_views_pager.zip | 1.02 КБ |
Комментарии
Отличная штука, спасибо. Переделал немного под 6-ку - и все заработало. То, что искал/
PS Хотя нет, к сожалению проблемы с Selective Exposed Filters - после установки лимита $view->query->limit запрос обрезается, таким образом в фильтре выводятся не все категории, что просто убивает.
Может есть другой способ как-то установить лимит - не через обрез запроса?