Наверняка молодые люди не раз попадали в следующую неприятную ситуацию: на некотором сайте новости выводятся по убыванию даты, при этом нумерация страниц ведётся по возрастанию начиная с 1, и Google посчитал страницу архива (пример) релевантнее страницы контента (пример), соответственно, поместив в выдачу её. Разумеется, между временем последней индексации и текущим моментом прошло какое-то количество времени, и на, предположим, второй странице находятся уже не те новости, что были на момент её посещения роботом-пауком. Недоумевающему пользователю приходится обращаться к гуглокэшу... а если его нет? Скорее всего, на сайт пользователь забьёт и перейдёт к следующему. Очень плохо, не правда ли?
Решение проблемы очевидно — нумеровать страницы с конца. Беда в том, что если делать это «в лоб»:
SELECT * FROM t ORDER BY id DESC LIMIT ((PAGE — 1) * PER_PAGE), PER_PAGE
как это реализуют в большинстве случаев, результат будет немногим лучше вышеописанного. Например, было у нас семь новостей, по три на страницу:
добавили восьмую:
и в результате всё равно всё уехало.
Вы догадались к чему я клоню? Квадратики в ванночках нужно выравнивать по правому краю:
тогда при добавлении новости останутся на своих местах:
Именно такая система используется на зелогине. Реализация выглядит немного непонятной, но, тем не менее, прекрасно работает:
// Correction for statically placing items on pages when ordering them both // descending. Just remove it and people will use google cache to discover // what exactly search engine found on your slice action pages. $applyCorrection = false; if ($order == Order_DESC) { $limitStart = ($totalPages - $currentPage) * $perPage; $applyCorrection = true; } else { $limitStart = ($currentPage - 1) * $perPage; } $limitEnd = $perPage; // AND HERE OUR UNUNDERSTANDABLE CODE GOES ]:-> if ($applyCorrection) { // For statically placing, last page (number 1, heh) must contain $perPage // items. So, let's do a shift; $correction = $totalRows % $perPage; if ($correction == 0) { $correction = $perPage; } $limitStart -= ($perPage - $correction); // This should happen on first page and it happened. We've decreased too // much :( if ($limitStart < 0) { $limitEnd = $limitEnd + $limitStart; $limitStart = 0; } } // LIMIT {$limitStart}, {$limitEnd}
Но это ещё не всё. В большинстве случаев нам также требуется страница (в дальнейшем условимся считать её главной), на которой выводятся последние $perPage новостей (пример). Страница с максимальным номером ($totalItems / $perPage + 1) не подойдёт — в большинстве случаев она содержит меньшее число записей:
Поэтому отделим главную страницу от остальных:
Реализация становится ненамного больше:
const PageNumber_Max = -1; $currentPage = isset($_REQUEST['page']) && is_numeric($_REQUEST['page']) && $_REQUEST['page'] > 0 ? intval($_REQUEST['page']) : PageNumber_Max; // Correction for statically placing items on pages when ordering them both // descending. Just remove it and people will use google cache to discover // what exactly search engine found on your slice action pages. $applyCorrection = false; if ($currentPage == PageNumber_Max) { // First N items $currentPage = $totalPages; } elseif ($order == Order_DESC) { // Else we should apply a correction $applyCorrection = true; } if ($order == Order_DESC) { // As usual... $limitStart = ($totalPages - $currentPage) * $perPage; } else { $limitStart = ($currentPage - 1) * $perPage; } $limitEnd = $perPage; // AND HERE OUR UNUNDERSTANDABLE CODE GOES ]:-> if ($applyCorrection) { // For statically placing, last page (number 1, heh) must contain $perPage // items. So, let's do a shift; $correction = $totalRows % $perPage; if ($correction == 0) { $correction = $perPage; } $limitStart -= ($perPage - $correction); // This should happen on first page and it happened. We've decreased too // much :( if ($limitStart < 0) { $limitEnd = $limitEnd + $limitStart; $limitStart = 0; } }
Теперь, казалось бы, всё замечательно. Вообразим, однако, такую ситуацию: наш постоянный читатель отдыхал в Египте, и, вернувшись, первым делом полез посмотреть чокаво там Вован написал. Он заходит на главную страницу, листает вниз до конца, тыкает на номер предыдущей и... видит те же самые записи:
Наиболее приемлемым решением мне видится вставка какой-нибудь «линии отреза» перед записями, которые повторятся на предыдущей номерной странице (собственно, сегодня таковая на зелогине и появилась):
К нашей реализации необходимо добавить что-то типа:
$this->localView->assign("index", $currentPage == PageNumber_Max); $this->localView->assign("correction", $totalRows % $perPage); $this->localView->assign("nextPageLink", $this->_pageLink(max($totalRows / $perPage, 1)));
И уже в шаблоне вывести линию:
{foreach from=$news key=i item=item}
{if $index and $correction and ($i eq $correction)}
<div class="cutline" title="Все посты после этой линии будут повторены на следующей странице, так что если вы хотите продолжать чтение, советую перейти на неё прямо сейчас, щёлкнув мышью здесь." onclick="document.location = '{$nextPageLink}';"></div>
{/if}
<!-- HTML-код новости -->
{/foreach}
По-моему, получается неплохо. А вы как считаете?
// This should happen of first page and it happened. We decreases too
// much 

отдыхал в ЕгиптеА как же Турция?!

А как же Турция?!Ну поскольку первого сентября у вас опять будет день трезвости, и дозволять мне вести себя до безобразия отвратительно никто не будет, спрошу тут: „А чё, пацаны, чтобы пидором ваще нармана в Турцию нахуй или в Египет?“
Доступные тэги: <b>, <i>, <s>, <u>, <a href="">, <img src="" /> (загрузить), <pre>, <quote>
- themylogin › Самое дорогое в жизни Вчера, 02:19
- ramwoolf › Am I not always be wanting this? (x8) 16 мая, 23:08
- anonymous › Написание «не» с различными частями речи 16 мая, 16:06
- anonymous › A Tragedy in the Air 15 мая, 18:24
- themylogin › Итоги 2011 15 мая, 12:10
- themylogin › На гелике езжу 13 мая, 16:24
- anonymous › Waking up at ten 13 мая, 13:16
- themylogin › Жук 12 мая, 11:55
- themylogin › Давайте шутки из твиттера продолжим развивать здесь 7 мая, 11:03
- anonymous › Шевченко лох 6 мая, 14:02









