Views - разное количество записей в зависимости от номера страницы

Аватар пользователя g78knl6cvxf0 g78knl6cvxf0 4 мая 2013 в 15:17

Иногда очень хочется (особенно если ты заказчик, а не разработчик), сделать так, чтобы количество записей, выводимых на странице с помощью 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;
?>

Получившийся в результате модуль довольно топорен и не содержит никакой админской составляющей, потому что в тайне надеюсь, что есть более правильное решение, которое мне здесь и подскажут. Но если что, вот он в архиве, а вот наяву:

function get_limits($view){

  $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.zip1.02 КБ
0 Thanks

Комментарии

Аватар пользователя remmor remmor 1 ноября 2013 в 2:55

Отличная штука, спасибо. Переделал немного под 6-ку - и все заработало. То, что искал/
PS Хотя нет, к сожалению проблемы с Selective Exposed Filters - после установки лимита $view->query->limit запрос обрезается, таким образом в фильтре выводятся не все категории, что просто убивает.
Может есть другой способ как-то установить лимит - не через обрез запроса?