Опубликовано 29 августа 2009, 20:04 под Dead Poetic - In Coma

Наверняка молодые люди не раз попадали в следующую неприятную ситуацию: на некотором сайте новости выводятся по убыванию даты, при этом нумерация страниц ведётся по возрастанию начиная с 1, и Google посчитал страницу архива (пример) релевантнее страницы контента (пример), соответственно, поместив в выдачу её. Разумеется, между временем последней индексации и текущим моментом прошло какое-то количество времени, и на, предположим, второй странице находятся уже не те новости, что были на момент её посещения роботом-пауком. Недоумевающему пользователю приходится обращаться к гуглокэшу... а если его нет? Скорее всего, на сайт пользователь забьёт и перейдёт к следующему. Очень плохо, не правда ли?

Решение проблемы очевидно — нумеровать страницы с конца. Беда в том, что если делать это «в лоб»:

SELECT *
FROM t
ORDER BY id DESC
LIMIT ((PAGE  1) * PER_PAGE), PER_PAGE

как это реализуют в большинстве случаев, результат будет немногим лучше вышеописанного. Например, было у нас семь новостей, по три на страницу:

Рисунок 1

добавили восьмую:

Рисунок 2

и в результате всё равно всё уехало.

Вы догадались к чему я клоню? Квадратики в ванночках нужно выравнивать по правому краю:

Рисунок 3

тогда при добавлении новости останутся на своих местах:

Рисунок 4

Именно такая система используется на зелогине. Реализация выглядит немного непонятной, но, тем не менее, прекрасно работает:

// 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) не подойдёт — в большинстве случаев она содержит меньшее число записей:

Рисунок 4

Поэтому отделим главную страницу от остальных:

Рисунок 5

Реализация становится ненамного больше:

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;
    }
}

Теперь, казалось бы, всё замечательно. Вообразим, однако, такую ситуацию: наш постоянный читатель отдыхал в Египте, и, вернувшись, первым делом полез посмотреть чокаво там Вован написал. Он заходит на главную страницу, листает вниз до конца, тыкает на номер предыдущей и... видит те же самые записи:

Рисунок 6

Наиболее приемлемым решением мне видится вставка какой-нибудь «линии отреза» перед записями, которые повторятся на предыдущей номерной странице (собственно, сегодня таковая на зелогине и появилась):

Рисунок 7

К нашей реализации необходимо добавить что-то типа:

$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}

По-моему, получается неплохо. А вы как считаете?

Комментарии (4)
ramwoolf
29 августа 2009, 22:37
S Q #1
Неплохо и актуально.... во всяком случае немало где видел что информация находящаяся на границах страниц повторяется...
Неплохо и актуально.... во всяком случае немало где видел что информация находящаяся на границах страниц повторяется...
themylogin
29 августа 2009, 22:44
S Q #2
    // This should happen of first page and it happened. We decreases too
    // much 
<source> // This should happen of first page and it happened. We decreases too // much :(</source>:-\
s_mordvinov
30 августа 2009, 00:16
S Q #3
отдыхал в Египте
А как же Турция?!
<quote>отдыхал в Египте</quote> А как же Турция?! :'(
themylogin
30 августа 2009, 00:40
S Q #4
А как же Турция?!
Ну поскольку первого сентября у вас опять будет день трезвости, и дозволять мне вести себя до безобразия отвратительно никто не будет, спрошу тут: „А чё, пацаны, чтобы пидором ваще нармана в Турцию нахуй или в Египет?“
<quote>А как же Турция?!</quote>Ну поскольку первого сентября у вас опять будет день трезвости, и дозволять мне вести себя до безобразия отвратительно никто не будет, спрошу тут: „А чё, пацаны, чтобы пидором ваще нармана в Турцию нахуй или в Египет?“
Добавить комментарий
Войдите через  Доступные тэги: <b>, <i>, <s>, <u>, <a href="">, <img src="" /> (загрузить), <pre>, <quote>
Теги
1nsk Alternative E-Business Embedded GNU/GPL-софт HTML/CSS ICQ KDE last.fm Linux Linuxnsk Live Lyceum game Microsoft Motivator MySQL New Age P2P Party Photoshop PHP Python Qt4/C++ SEO Sibnet thelogin.ru Timelapse Web 2.0 Webdev Webstream Windows Wireless А я говорил! Авто Админ Алексеев Аниме Атмосфера Безобразие Бесплатный Wi-Fi Блоги Большой бизнес Боты Бред Бухать Бытовуха Велосипед Весна Вечер Взлом Винил Винтаж Вконтакте Вода Воспоминания Гетто Гламур Гопота Горский Графити Грузовик Дача Двор Девушки Девченки!!! Деньги Дизайн Дом Домофоны Драка Драки Еда Железо Животные Заведения общественного отдыха Задроты Затулинка Зима Игрушки Игры Идея Интересно Интернет Исследование История Казань Карикатура Квартира Класс Компьютеры Коромшук Коты КПК Кран Красиво Криминал Крыша Курение Лето Литература Лицей Лицей НГТУ Лохи Магнитофоны Маркса Мат Математика Машинный перевод Мегафон Менты Метро Мечты Мифы Мне стыдно Мобайл Можга МТС Музыка Мультикасса Мультики Мы помним Надписи Наука НГТУ Недвижимость Непоняятно Новосибирск Носители Ноутбуки Ночь Обидно Обман Образование Общественный транспорт Омск Опечатки Орфография Осень Парк Периферия Пиратство Плохо Погода Поезд Помойка Праздники Презрение Природа Провайдеры Программирование Протест Радиотехника Растения Реклама Религия и вера Ретро Рисунок Руины Рэп Салют Сервер Серверы Сервис Сериалы Скринкаст Скриншоты Смешно СМИ Снег Собаки Совет Софт Спам Спасём Россию Спецтранспорт Стоп-ляп Стройка Студяга Танцы ТВ Типа страх Трамваи Транс Транспорт Уважаю Ужас Умный дом Утро Филдрепорты Философия Форум ФПМИ Хикки Хостинг Цитатник Школа Школа 208 ЭГ Эксперимент Юго-Западный
Twitter 29-08-2009
Lorem Ipsum
Умение везде видеть хуй.
Lorem Ipsum
ΔΣΛτχ Μεταλ.
Lorem Ipsum
Converting Vegetarians & playing GTA1.
Lorem Ipsum
курсовик.
Lorem Ipsum
BREATHIN&BREATHOUT,HANDSUP&HANDSDOWN,BACKUP-BACKUP,TELLMEWUTYAGONNADONOW!!!
Lorem Ipsum
В бердск провели интернет.
Lorem Ipsum
ВСЕ ЕБАНУЛИСЬ.
Lorem Ipsum
Морское оборудование.
Lorem Ipsum
Надо заготовить смешных аватаров и скриптом раз в 2 дня менять!