Небольшой апгрейд постраничной навигации Drupal-a
Прислано: Stutzer
чт, 29/10/2009 - 19:57
На мой взгляд, у стандартной постраничной навигации Друпала есть несколько недостатков.
Во-первых, ссылка на последнюю страницу стала бы более информативна и занимала бы меньше места, если её заменить на номер последней страницы [28].

Во-вторых, стоит нам перейти на вторую страницу и мы тут же видим две ссылки на первую страницу: [1] и [Первая]

Аналогичную картину мы видим с противоположной стороны навигационной линейки

Итак, привожу наглядный вариант своего решения этих недочетов:

Как вы можете видеть, ссылки на крайние страницы диапазона представлены в виде номеров, а также интегрированы в саму линейку.
Ссылки «Назад» и «Вперед» вынесены наружу и представлены в виде стрелок (но это уже мелочь, сделанная просто путем перевода интерфейса)
Кроме того, я добавил возможность пролистывать страницы с помощью клавиш Ctrl + ← и Ctrl + →
Протестировано в IE6+ FF3.5 Chrome 3.
Все, что нужно — это дописать несколько строк в файл template.php вашей темы оформления (а точнее переопределить функцию
theme_pager()), создать в директории темы папку js, а в ней файл jquery.paginatior.js, после чего обновить реестр тем.
UPD: Кстати, может ли быть на странице более одного пэйджера? Если да, то js-код надо бы немного переделать.
Переопределнный код функции theme_pager()
function YOURTHEMENAME_pager($tags = array(), $limit = 10, $element = 0, $parameters = array(), $quantity = 9) { 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.paginatior.js
if (Drupal.jsEnabled) {
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();
});
}- Stutzer's blog
- Для комментирования войдите или зарегистрируйтесь
Отлично! Но заработало только с function phptemplate_theme_pager(.......
- Для комментирования войдите или зарегистрируйтесь
Отлично! Но заработало только с function phptemplate_theme_pager(.......
Спасибо, исправил. Хотя у меня и так работает.
- Для комментирования войдите или зарегистрируйтесь
Хотя у меня и так работает.
У меня не работает, странно. Спасибо, отличная работа!-)
- Для комментирования войдите или зарегистрируйтесь
а для 5 есть какие-нибудь варианты?
- Для комментирования войдите или зарегистрируйтесь
Можно попробовать предложить и в ядре обновить дефаултного монстра?
Мы пофлешмобим ;) В 7 - думаю можно попытаться красоты добавить...
- Для комментирования войдите или зарегистрируйтесь
Можно попробовать предложить и в ядре обновить дефаултного монстра?
Мы пофлешмобим ;) В 7 - думаю можно попытаться красоты добавить...
Да, я думал насчет этого. Завтра переведу на английский и запощу. Кстати, куда постить то? ))
- Для комментирования войдите или зарегистрируйтесь
а для 5 есть какие-нибудь варианты?
Для пятерки нужно переопределть две функции:
theme_pager() и
theme_pager_list().
- Для комментирования войдите или зарегистрируйтесь
Х.м. не завелось :(
- Для комментирования войдите или зарегистрируйтесь
Х.м. не завелось :(
У меня в данный момент функция определена как themename_pager(), а не phptemplate_theme_pager().
Попробуйте и так и так. У Stan.Ezersky не заработало с themename_pager(), а с phptemplate_theme_pager() заработало.
Ну и реестр тем обновить не забудьте.
- Для комментирования войдите или зарегистрируйтесь
не заработало на 6ке =\
- Для комментирования войдите или зарегистрируйтесь
lopata24, всё прекрасно работает
- Для комментирования войдите или зарегистрируйтесь
заработало, только с theme_pager
Посмотрел, как у меня определено в самом pager`e
Спасибочки ;-)
p.s. в вдогонку вопрос по стилям. Как сделать также, как в Вашем примере? =Р
- Для комментирования войдите или зарегистрируйтесь
в вдогонку вопрос по стилям. Как сделать также, как в Вашем примере? =Р
Я думаю, вы получите больше удовольствия и пользы, если сами попытаетесь ;)
- Для комментирования войдите или зарегистрируйтесь
С темой в имени завелось :) Классное(а главное удобное) решение.
Ещё бы строки в t() оставить как в оригинале...
- Для комментирования войдите или зарегистрируйтесь
не поверите, сам сегодня потратил не один час на это (новичек =) ).
Выжал максимум вот так

к сожалению так и не смог и не понял как сделать
1) стрелки, как у Вас
2) активную страницу в рамке, в отличии от остальных
- Для комментирования войдите или зарегистрируйтесь
к сожалению так и не смог и не понял как сделать
1) стрелки, как у Вас
2) активную страницу в рамке, в отличии от остальных
Стрелки, как у нас, сделаны элементарно переводом интерфейса.
А рамки — это CSS чистой воды.
- Для комментирования войдите или зарегистрируйтесь
p.s. в вдогонку вопрос по стилям. Как сделать также, как в Вашем примере? =Р
Текущая страница: .pager-current span {background: #cecece; padding: 5px 10px; }. Дальше включайте фантазию.
Вот вам пару стрелок: ← (←) и → (→)
- Для комментирования войдите или зарегистрируйтесь
функция определена как themename_pager()
тоже заработало и перестало работать с phptemplate_theme_pager(). Загадочно...
- Для комментирования войдите или зарегистрируйтесь
bellisimo
- Для комментирования войдите или зарегистрируйтесь
волшебно! побежал пробовать)
- Для комментирования войдите или зарегистрируйтесь
по ссылкам "первая" и "последняя" гораздо удобнее попадать чем по номерам, и глядя на номера ещё нужно сообразить что это за числа. есть хорошая статья эту на тему http://www.birzool.com/page-navigation/
- Для комментирования войдите или зарегистрируйтесь
Спасибо. phptemplate_pager - работает. Остальные варианты не пробовал.
- Для комментирования войдите или зарегистрируйтесь
Неплохо, для начала стоит предложить сие в
Custom pagers
А почему бы проосто не переопределить темизацию
theme_pager_first() и соседей?
PS: ссылки у автора ведут не на API, а на страницы модулей - просьба поправить...
- Для комментирования войдите или зарегистрируйтесь
для начала стоит предложить сие в Custom pagers
а почему не замахнутся на Шекспира ядро? Вроде родное ососбо ни на что не влияет, и красивости будет больше в 7...
- Для комментирования войдите или зарегистрируйтесь
А у меня не получилось. В каталоге с темой нет файла template.php, но есть node.tpl.php и page.tpl.php. Попробовал добавлять в оба файла код - изменений не обнаружил. И кстати что значит "обновить реестр тем"? Точнее где и как? =\ Спасибо.
- Для комментирования войдите или зарегистрируйтесь
А у меня не получилось. В каталоге с темой нет файла template.php ... И кстати что значит "обновить реестр тем"? Точнее где и как? =\ Спасибо.
Так создайте его!
Чтобы обновить реестр, надо переустановить тему в соответствующем разделе админки.
- Для комментирования войдите или зарегистрируйтесь
Вот вам пару стрелок: ← (←) и → (→)
коды стрелок, то я знаю, только вот как их вставить?
если так t('←')), то и отображает ←, вместо стрелки (
- Для комментирования войдите или зарегистрируйтесь
к: ← (←) и →
вставьте их в перевод.
Хотя я бы оставил эти строки как в оригинале.
- Для комментирования войдите или зарегистрируйтесь
Где-то с округлением вылезло :(

- Для комментирования войдите или зарегистрируйтесь
спасибо, все ок ;-)
- Для комментирования войдите или зарегистрируйтесь
Неплохо!
Но я просто поставил Paginator 3000 и все мои проблемы остались в прошлом.
Впрочем, осталось понять, как вернуть на место AJAX-возможности страничного контроля.
- Для комментирования войдите или зарегистрируйтесь
Мне больше нравится пейджер яндекса (там ссылки вперед и назад рядом), но ваш тоже оптически привлекателен.
Иссу по юзабилити для 7-рки постят где-то тут: http://drupal.org/project/issues/search/drupal?version[0]=7.x&issue_tags=Usability%2C%20d7ux
Но я думаю, его пока отклонят, предоставив возможность темизаторам самостоятельно определять внешний вид пейджера.
- Для комментирования войдите или зарегистрируйтесь
Красивые текстовые стрелочки: ◄ ► видны всеми ослами ;)
- Для комментирования войдите или зарегистрируйтесь
Красивые текстовые стрелочки: ◄ ► видны всеми ослами ;)
Василий как бэ намекает, что все ослы :)))))
- Для комментирования войдите или зарегистрируйтесь
Мой 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 - знаю только, что теперь это дело сделали в слое базы данных экстендером, а вот на уровне рендера...
- Для комментирования войдите или зарегистрируйтесь
Немного обновлений:
- Пофиксил баг, обнаруженный пользователем
PVasili - Вынес JS-код в отдельный файл и переписал его в виде объекта, поскольку эстеты с Хабра загнобили )
- Для комментирования войдите или зарегистрируйтесь
UPD: Кстати, может ли быть на странице более одного пэйджера? Если да, то js-код надо бы немного переделать.
Да, может - у каждого свой номер, начиная с нуля.
- Для комментирования войдите или зарегистрируйтесь
Очень полезная и нужная вещь. Спасибо.
А как можно уменьшить число возможных страниц для перехода?
То есть, сейчас друпал показывает сразу 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.
- Для комментирования войдите или зарегистрируйтесь
В новой версии периодически вылезает:
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 подгружается здесь:
// Add js code for Ctrl+arrows navigation 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' );
- Для комментирования войдите или зарегистрируйтесь



















Комментарии