На мой взгляд, у стандартной постраничной навигации Друпала есть несколько недостатков.
Во-первых, ссылка на последнюю страницу стала бы более информативна и занимала бы меньше места, если её заменить на номер последней страницы [28].
Во-вторых, стоит нам перейти на вторую страницу и мы тут же видим две ссылки на первую страницу: [1] и [Первая]
Аналогичную картину мы видим с противоположной стороны навигационной линейки
Итак, привожу наглядный вариант своего решения этих недочетов:
Как вы можете видеть, ссылки на крайние страницы диапазона представлены в виде номеров, а также интегрированы в саму линейку.
Ссылки «Назад» и «Вперед» вынесены наружу и представлены в виде стрелок (но это уже мелочь, сделанная просто путем перевода интерфейса)
Кроме того, я добавил возможность пролистывать страницы с помощью клавиш Ctrl + ← и Ctrl + →
Протестировано в IE6+ FF3.5 Chrome 3.
Все, что нужно — это дописать несколько строк в файл template.php вашей темы оформления (а точнее переопределить функцию [ru-api=theme_pager]theme_pager()[/ru-api]), создать в директории темы папку js, а в ней файл jquery.paginatior.js, после чего обновить реестр тем.
UPD: Кстати, может ли быть на странице более одного пэйджера? Если да, то js-код надо бы немного переделать.
Переопределнный код функции theme_pager()
global $pager_page_array, $pager_total, $theme;
// Add js code for Ctrl+arrows navigation
drupal_add_js( drupal_get_path('theme', $theme) .'/js/jquery.paginator.js' );
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
// current is the page we are currently paged to
$pager_current = $pager_page_array[$element] + 1;
// first is the first page listed by this pager piece (re quantity)
$pager_first = $pager_current - $pager_middle + 1;
// last is the last page listed by this pager piece (re quantity)
$pager_last = $pager_current + $quantity - $pager_middle;
// max is the maximum page number
$pager_max = $pager_total[$element];
// End of marker calculations.
// Prepare for generation loop.
$i = $pager_first;
if ($pager_last > $pager_max) {
// Adjust "center" if at end of query.
$i = $i + ($pager_max - $pager_last);
$pager_last = $pager_max;
}
if ($i <= 0) {
// Adjust "center" if at start of query.
$pager_last = $pager_last + (1 - $i);
$i = 1;
}
// End of generation loop preparation.
$li_previous = theme('pager_previous', (isset($tags[1]) ? $tags[1] : t('previous page')), $limit, $element, 1, $parameters);
$li_next = theme('pager_next', (isset($tags[3]) ? $tags[3] : t('next page')), $limit, $element, 1, $parameters);
$li_first = theme('pager_first', 1, $limit, $element, $parameters);
$li_last = theme('pager_last', $pager_max, $limit, $element, $parameters);
// First-page link display condition
$show_first = ( $i > 1 ) ? true : false ;
if ($pager_total[$element] > 1) {
if ( $li_previous ) $items[] = array( 'class' => 'pager-previous', 'data' => $li_previous );
if ( $show_first && $li_first ) $items[] = array( 'class' => 'pager-first', 'data' => $li_first );
// When there is more than one page, create the pager list.
if ($i != $pager_max) {
if ($i > 2) $items[] = array( 'class' => 'pager-ellipsis', 'data' => '<span>...</span>' );
// Now generate the actual pager piece.
for (; $i <= $pager_last && $i <= $pager_max; $i++) {
if ($i < $pager_current ) $items[] = array( 'class' => 'pager-item', 'data' => theme('pager_previous', $i, $limit, $element, ($pager_current - $i), $parameters) );
if ($i == $pager_current) $items[] = array( 'class' => 'pager-current', 'data' => '<span>' . $i . '</span>' );
if ($i > $pager_current) $items[] = array( 'class' => 'pager-item', 'data' => theme('pager_next', $i, $limit, $element, ($i - $pager_current), $parameters) );
}
if ($i < $pager_max) $items[] = array( 'class' => 'pager-ellipsis', 'data' => '<span>...</span>' );
}
// Last-page link display condition
$show_last = ( $pager_max > ($i-1) ) ? true : false ;
// End generation.
if ( $show_last && $li_last) $items[] = array( 'class' => 'pager-last', 'data' => $li_last );
if ( $li_next) $items[] = array( 'class' => 'pager-next', 'data' => $li_next );
return theme('item_list', $items, NULL, 'ul', array('class' => 'pager'));
}
}
Код файла jquery.paginator.js
paginator = function () {
/**
* Private properties
*/
var linkNext = null;
var linkPrev = null;
/**
* Private methods
*/
var setLinks = function () {
linkPrev = $("ul.pager li.pager-previous a").attr("href");
linkNext = $("ul.pager li.pager-next a").attr("href");
}
var navigate = function (event) {
var href = null;
if ( event.ctrlKey && event.keyCode == 37 ) href = linkPrev;
if ( event.ctrlKey && event.keyCode == 39 ) href = linkNext;
if ( href ) document.location = href;
}
/**
* Public methods
*/
this.__init = function () {
// Get next/prev hrefs
setLinks();
// Ctrl + arrow event handle
$(document).keydown( function(event) {
navigate(event);
});
}
}
$(document).ready(function(){
var pageNavigation = new paginator();
pageNavigation.__init();
});
}
Комментарии
Отлично! Но заработало только с function phptemplate_theme_pager(.......
Спасибо, исправил. Хотя у меня и так работает.
У меня не работает, странно. Спасибо, отличная работа!-)
а для 5 есть какие-нибудь варианты?
Для пятерки нужно переопределть две функции: theme_pager() и theme_pager_list().
Можно попробовать предложить и в ядре обновить дефаултного монстра?
Мы пофлешмобим В 7 - думаю можно попытаться красоты добавить...
Да, я думал насчет этого. Завтра переведу на английский и запощу. Кстати, куда постить то? ))
Х.м. не завелось
У меня в данный момент функция определена как themename_pager(), а не phptemplate_theme_pager().
Попробуйте и так и так. У Stan.Ezersky не заработало с themename_pager(), а с phptemplate_theme_pager() заработало.
Ну и реестр тем обновить не забудьте.
не заработало на 6ке =\
lopata24, всё прекрасно работает
заработало, только с theme_pager
Посмотрел, как у меня определено в самом pager`e
Спасибочки
p.s. в вдогонку вопрос по стилям. Как сделать также, как в Вашем примере? =Р
Я думаю, вы получите больше удовольствия и пользы, если сами попытаетесь
С темой в имени завелось Классное(а главное удобное) решение.
Ещё бы строки в t() оставить как в оригинале...
не поверите, сам сегодня потратил не один час на это (новичек ).
Выжал максимум вот так
к сожалению так и не смог и не понял как сделать
1) стрелки, как у Вас
2) активную страницу в рамке, в отличии от остальных
Стрелки, как у нас, сделаны элементарно переводом интерфейса.
А рамки — это CSS чистой воды.
.pager-current span {background: #cecece; padding: 5px 10px; }
. Дальше включайте фантазию.Вот вам пару стрелок:
← (←) и → (→)
bellisimo
волшебно! побежал пробовать)
по ссылкам "первая" и "последняя" гораздо удобнее попадать чем по номерам, и глядя на номера ещё нужно сообразить что это за числа. есть хорошая статья эту на тему http://www.birzool.com/page-navigation/
Спасибо. phptemplate_pager - работает. Остальные варианты не пробовал.
Неплохо, для начала стоит предложить сие в Custom pagers
А почему бы проосто не переопределить темизацию [ru-api=theme_pager_first]theme_pager_first()[/ru-api] и соседей?
PS: ссылки у автора ведут не на API, а на страницы модулей - просьба поправить...
Шекспираядро? Вроде родное ососбо ни на что не влияет, и красивости будет больше в 7...А у меня не получилось. В каталоге с темой нет файла template.php, но есть node.tpl.php и page.tpl.php. Попробовал добавлять в оба файла код - изменений не обнаружил. И кстати что значит "обновить реестр тем"? Точнее где и как? =\ Спасибо.
Так создайте его!
Чтобы обновить реестр, надо переустановить тему в соответствующем разделе админки.
коды стрелок, то я знаю, только вот как их вставить?
если так t('
←
')), то и отображает←
, вместо стрелки (Хотя я бы оставил эти строки как в оригинале.
Где-то с округлением вылезло
Спасибо за найденный баг — пофиксим )
Немного обновлений:
спасибо, все ок
Неплохо!
Но я просто поставил Paginator 3000 и все мои проблемы остались в прошлом.
Впрочем, осталось понять, как вернуть на место AJAX-возможности страничного контроля.
Мне больше нравится пейджер яндекса (там ссылки вперед и назад рядом), но ваш тоже оптически привлекателен.
Иссу по юзабилити для 7-рки постят где-то тут: http://drupal.org/project/issues/search/drupal?version[0]=7.x&issue_tags...
Но я думаю, его пока отклонят, предоставив возможность темизаторам самостоятельно определять внешний вид пейджера.
Красивые текстовые стрелочки: ◄ ► видны всеми ослами
Василий как бэ намекает, что все ослы
Мой 6-ой осел пустые квадратики показывает.
//об этих символах: я для своих сайтов специально пытался избавиться от этого бага, указывал конкретно шрифт Courier New, но гад иногда все равно что-то свое выведет. Поэтому в конечном итоге решил в графику перегнать.
Насчет 7ки - еще весной была поднята тема http://www.angrydonuts.com/modernizing-the-drupal-pager-system
Нашел только http://drupal.org/node/33809 и http://drupal.org/node/173037
Походу так ни у кого и не дошли руки... а вот на www.d7ux.org вообще как-то не обсуждалось
Может пофлешмобим активно>
Было бы чем я как-то пропустил, что там с pager - знаю только, что теперь это дело сделали в слое базы данных экстендером, а вот на уровне рендера...
Да, может - у каждого свой номер, начиная с нуля.
Очень полезная и нужная вещь. Спасибо.
А как можно уменьшить число возможных страниц для перехода?
То есть, сейчас друпал показывает сразу 9 возможных страниц, а нужно всего три.
За это отвечает параметр $quantity. Можете его явно задать непосредственно в функции, в самом начале.
Благодарю.
Всё работает как часы.
В D7 произошли изменения с выводом постраничности - теперь перед списком выводится заголовком второго уровня h2 - Pages
Может модернизировать под обратный пейджинг? добавить константу: направление отсчёта.
Спасибо за решение работает замечательно!
спасибо, заработало.
В новой версии периодически вылезает:
warning: file_get_contents(sites/all/themes/.../js/jquery.paginator.js) [function.file-get-contents]: failed to open stream: No such file or directory in /.../includes/common.inc on line 2403.
Эм... Честно говоря идей нет.
А при каких именно действиях вылетает?
JS подгружается здесь:
drupal_add_js( drupal_get_path('theme', 'YOURTHEMENAME') .'/js/jquery.paginator.js' );
Соответственно, это может произойти при смене темы, например.
UPD: Заменил
drupal_add_js( drupal_get_path('theme', 'YOURTHEMENAME') .'/js/jquery.paginator.js' );
на
drupal_add_js( drupal_get_path('theme', $theme) .'/js/jquery.paginator.js' );
Аналогичная проблема.
Если отключить оптимизацию js, вылезает 404 sites/all/themes/.../js/jquery.paginator.js
У меня это вылазит и без доработок.
Вылезает периодически. Путь к JS корректно указывает. Тема не меняется. В самом JS вроде нечему...
Может из-за 2 пейджеров?
А как с обратной нумерацией?
Из-за двух пэйджеров на одной странице? Вполне возможно. В такой случае JS следует подключать в page.tpl.php например
С обратной никак пока — некогда.
Странно, у меня такой проблемы нет
Думал, думал над этим пейджером, решил оставить стандартный, заменив надписи на символы и поджав все css-ом.
хм... у меня при всех сделанных изменениях, все равно страницы дублируется иногда, как заскриншотено на прошлой странице...
=\
Хотелост бы больше информации, поскольку у меня никаких глюков не замечено.
Скрины приветствуются.
Нашел баг. На страницах где расположен проапгрейженый пейджер не работает theme developer модуля devel. Не смертельно, можно переключится на стандартную тему, но неудобно. Видимо js скрипты плохо дружат.
Нужно ли установить какой-нибудь jquery_ui или что-то подобное?
Да нет, вроде. Стандартный друпаловский jQuery 1.2.6 используется.
как там в 7-ке с этим делом?
А что если постраничная навигация будет висеть внизу "экрана", недвижимо или например она бы показывалась при наведении курсором вниз сайта (экрана), а не внизу страницы, когда нужно опускаться вниз и только потом уже доступна постраничная навигация, или мжб такое уже сделали?
CSS в руки и вперёд.
Как это сделать для Drupal 7?
Да неплохо было бы увидеть подобное решение для 7 ветки. Пытался своими силами, но пока безрезультатно...
Код файла jquery.paginatior.js для D7
window.paginator = function() {
var linkNext = null;
var linkPrev = null;
var setLinks = function () {
linkPrev = $("ul.pager li.pager-previous a").attr("href");
linkNext = $("ul.pager li.pager-next a").attr("href");
}
var navigate = function (event) {
var href = null;
if ( event.ctrlKey && event.keyCode == 37 ) href = linkPrev;
if ( event.ctrlKey && event.keyCode == 39 ) href = linkNext;
if ( href ) document.location = href;
}
this.__init = function () {
setLinks();
$(document).keydown( function(event) {
navigate(event);
});
}
};
$(document).ready(function() {
var pageNavigation = new paginator();
pageNavigation.__init();
});
})(jQuery);
Если бы еще подсказали как выделить ссылки Следущая и Предыдущая в отдельный див, было бы вообще замечательно:
<a>Предыдущая</a>
<a>Следущая</a>
</div>
Как говориться сам вопрос задал, сам же на него и ответил:
в function YOURTHEMENAME_pager ссылки на $li_previous и $li_next добавляем в новый массив к примеру $items_link[] и в вывод добавляем новый массив:
<?phpreturn '<h2 class="element-invisible">' . t('Pages') . '</h2>' .
theme('item_list', array(
'items' => $items_link,
'attributes' => array('class' => array('link_pager')),
)) .
theme('item_list', array(
'items' => $items,
'attributes' => array('class' => array('pager')),
));?>
плюс немного css и получаем
допоможіть рішити цей баг, у мене стоїть D7.13 сторінки зовсім не переключаються. пробував знайти файл що за це відповідає не получається, мені здається його немає правда таке не можливо бути:((((((
Коллеги, а как сделать навигатор на аяксе (как в контакте)?
Как на вьюсе это реализовать я знаю, на это модуль есть)
А как превратить стандартный пейджер без использования вьюхи
в такое вот show more?)
При клике на ссылку страницы - подгружать её аяксом и заменять текщий контент новым.
Как пример реализации - infinity scroll. Немного другая тема, но принцип тот же.
Спасибо за намёк - попробую)
Уважаемый автор, обратите внимание на ошибку в тексте, она очень важна:
«Код файла jquery.paginatior.js»
Не jquery.paginatior.js а jquery.paginator.js
А то я название скопировал, файл создал, сделал всё как надо а не работает) Очень хитрая ошибка, при условии, что большинство копирует текст ваш а не называет файл ручками
а для 7рочки есть порт? а то уж оч нравиться эта поделка.
Попробуй эту идею реверсивной пагинации http://help.blox.ru/latest/?part_backward . Главное - там решается проблема поисковой оптимизации. Нужно только перенести эту идею на Drupal.
я зделал постраничну навигацию с помощю плагина views. попробуйте может камуто подойдет
Подскажите, как реализоваться многоточие в Drupal 7, так же как здесь, чтобы оно было через цифру?
Для Drupal 7.
Добавил 4 строки в общем.
Добавил цифры
$li_last = theme('pager_last', array('text'=>$pager_max), $element, $parameters);
Добавил условие для вывода в начале и конце
$show_last = ( $pager_max > ($i-1) ) ? true : false ;
Весь код ниже
$tags = $variables['tags'];
$element = $variables['element'];
$parameters = $variables['parameters'];
$quantity = $variables['quantity'];
global $pager_page_array, $pager_total;
// Calculate various markers within this pager piece:
// Middle is used to "center" pages around the current page.
$pager_middle = ceil($quantity / 2);
// current is the page we are currently paged to
$pager_current = $pager_page_array[$element] + 1;
// first is the first page listed by this pager piece (re quantity)
$pager_first = $pager_current - $pager_middle + 1;
// last is the last page listed by this pager piece (re quantity)
$pager_last = $pager_current + $quantity - $pager_middle;
// max is the maximum page number
$pager_max = $pager_total[$element];
// End of marker calculations.
// Prepare for generation loop.
$i = $pager_first;
if ($pager_last > $pager_max) {
// Adjust "center" if at end of query.
$i = $i + ($pager_max - $pager_last);
$pager_last = $pager_max;
}
if ($i <= 0) {
// Adjust "center" if at start of query.
$pager_last = $pager_last + (1 - $i);
$i = 1;
}
// End of generation loop preparation.
$li_previous = theme('pager_previous', array('text' => (isset($tags[1]) ? $tags[1] : t('‹ previous')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
$li_next = theme('pager_next', array('text' => (isset($tags[3]) ? $tags[3] : t('next ›')), 'element' => $element, 'interval' => 1, 'parameters' => $parameters));
//$li_first = theme('pager_first', array('text' => (isset($tags[0]) ? $tags[0] : t('« first')), 'element' => $element, 'parameters' => $parameters));
//$li_last = theme('pager_last', array('text' => (isset($tags[4]) ? $tags[4] : t('last »')), 'element' => $element, 'parameters' => $parameters));
$li_first = theme('pager_first', array('text'=>1),$element, $parameters);
$li_last = theme('pager_last', array('text'=>$pager_max), $element, $parameters);
if ($li_previous) {
$items[] = array(
'class' => array('pager-previous'),
'data' => $li_previous,
);
}
if ($pager_total[$element] > 1) {
$show_first = ( $i > 1 ) ? true : false ;
if ($show_first && $li_first) {
$items[] = array(
'class' => array('pager-first'),
'data' => $li_first,
);
}
// When there is more than one page, create the pager list.
if ($i != $pager_max) {
if ($i > 1) {
$items[] = array(
'class' => array('pager-ellipsis'),
'data' => '…',
);
}
// Now generate the actual pager piece.
for (; $i <= $pager_last && $i <= $pager_max; $i++) {
if ($i < $pager_current) {
$items[] = array(
'class' => array('pager-item'),
'data' => theme('pager_previous', array('text' => $i, 'element' => $element, 'interval' => ($pager_current - $i), 'parameters' => $parameters)),
);
}
if ($i == $pager_current) {
$items[] = array(
'class' => array('pager-current'),
'data' => '<span>'.$i.'</span>',
);
}
if ($i > $pager_current) {
$items[] = array(
'class' => array('pager-item'),
'data' => theme('pager_next', array('text' => $i, 'element' => $element, 'interval' => ($i - $pager_current), 'parameters' => $parameters)),
);
}
}
if ($i < $pager_max) {
$items[] = array(
'class' => array('pager-ellipsis'),
'data' => '…',
);
}
}
// End generation.
$show_last = ( $pager_max > ($i-1) ) ? true : false ;
if ($show_last && $li_last) {
$end = $pager_max;
$items[] = array(
'class' => array('pager-last'),
'data' => $li_last,
);
}
if ($li_next) {
$items[] = array(
'class' => array('pager-next'),
'data' => $li_next,
);
}
return '<h2 class="element-invisible">' . t('Pages') . '</h2>' . theme('item_list', array(
'items' => $items,
'attributes' => array('class' => array('pager')),
));
}
}
Как сделать что бы комментарии тоже подцепляли этот вывод страниц??? А то только на вьюхи распространяется.
Для варианта 6 друпала там и на комменты распространялось.