Разбивка на страницы

Публикую свою функцию разбивки на страницы, её преимущество перед другими методами в том, что список страниц занимает ровно требуемое количество пунктов. Код не ахти какой, но работает отлично.

На выходе получим:

<paginator count="99" page="4" size="10">
    <page>1</page>
    <page>..</page>
    <page>3</page>
    <page>4</page>
    <page>5</page>
    <page>..</page>
    <page>99</page>
</paginator>

Пример шаблона на XSLT:

<xsl:template match="paginator">
    <xsl:if test="@count &gt; 1">
        <p class="paginator">
            <xsl:if test="@page &gt; 1"><a href="?page={@page - 1}">&lt;&lt; Назад</a></xsl:if>
            <xsl:apply-templates select="page"/>
            <xsl:if test="@page &lt; @count"><a href="?page={@page + 1}">Далее &gt;&gt;</a></xsl:if>
        </p>
    </xsl:if>
</xsl:template>

<xsl:template match="page">
    <a href="?page={.}" class="page">
        <xsl:if test=". = ../@page"><xsl:attribute name="class">sel</xsl:attribute></xsl:if>
        <xsl:value-of select="."/>
    </a>
</xsl:template>

PHP функция разбивки на страницы:

Параметры:
$node - узел SimpleXml
$page - текущая страница ($_GET['page'])
$count - количество записей на странице
$records - всего записей, которые разбиваем на страницы
$max - количество выводимых пунктов (включая ..)

function paginator($node, $page = 1, $count = 10, $records = 1, $max = 7) { // [1]..[3][4][5]..[99]
    if ($max < 5) $max = 5;
    $paginator = $node->addChild('paginator');
    $count_pages = ceil($records / $count);
    $paginator->addAttribute('count', $count_pages);
    $paginator->addAttribute('page', $page);
    $paginator->addAttribute('size', $count);
    if ($count_pages > $max and $page == 0) {
        for($i = 1; $i <= floor($max / 2 - 0) ; $i ++) {
            $paginator->addChild('page', $i);
        }
        $paginator->addChild('page', '..');
        for($i = ($count_pages - ceil($max / 2 - 2)); $i <= $count_pages; $i ++) {
            $paginator->addChild('page', $i);
        }
    } else if ($count_pages > $max and $page < ($max - 2)) {
        for($i = 1; $i <= ($max - 2); $i ++) {
            $paginator->addChild('page', $i);
        }
        $paginator->addChild('page', '..');
        $paginator->addChild('page', $count_pages);
    } else if ($count_pages > $max and $page > ($count_pages - ($max - 3))) {
        $paginator->addChild('page', 1);
        $paginator->addChild('page', '..');
        for($i = ($count_pages - ($max - 3)); $i <= $count_pages ; $i ++) {
            $paginator->addChild('page', $i);
        }
    } else if ($count_pages > ($max + 1) and $page > ($max - 3) and $page < ($count_pages - ($max - 4))) {
        $paginator->addChild('page', 1);
        $paginator->addChild('page', '..');
        for($i = ($page - ceil($max / 2 - 3)); $i <= ($page + floor($max / 2 - 2)); $i ++) {
            $paginator->addChild('page', $i);
        }
        $paginator->addChild('page', '..');
        $paginator->addChild('page', $count_pages);
    } else {
        for($i = 1; $i <= $count_pages; $i ++) {
            $paginator->addChild('page', $i);
        }
    }
}
05 сентября 2012