之前写过《Typecho 自定义分页样式》主要是介绍typecho默认的分页文档使用方法,但是用了一段时间后发下局限性不少!

具体问题

官方的文档不能够操控翻页按钮的a标签的class导致使用(扒站)时很不方便;二是翻页功能本身不会携带get参数无法适配我之前写的soso插件按分类搜索文章的功能。

代码

重写代码如下,代码不包括如何传递get参数部分(主要因为需要的人不多,而且懂的人应该会都加),将下面代码放入需要重写页面的顶部即可。

class Typecho_Widget_Helper_PageNavigator_Box extends Typecho_Widget_Helper_PageNavigator
{
    /**
     * 输出盒装样式分页栏
     *
     * @access public
     * @param string $prevWord 上一页文字
     * @param string $nextWord 下一页文字
     * @param int $splitPage 分割范围
     * @param string $splitWord 分割字符
     * @param string $currentClass 当前激活元素class
     * @return void
     */
    public function render($prevWord = 'PREV', $nextWord = 'NEXT', $splitPage = 3, $splitWord = '...', array $template = array())
    { 
        if ($this->_total < 1) {
            return;
        }
        $default = array(
            'aClass'  =>  '',
            'itemTag'       =>  'li',
            'textTag'       =>  'span',
            'textClass'       =>  '',
            'currentClass'  =>  'current',
            'prevClass'     =>  'prev',
            'nextClass'     =>  'next'
        );
        $template = array_merge($default, $template);
        extract($template);
        // 定义item
        $itemBegin = empty($itemTag) ? '' : ('<' . $itemTag . '>');
        $itemCurrentBegin = empty($itemTag) ? '' : ('<' . $itemTag 
            . (empty($currentClass) ? '' : ' class="' . $currentClass . '"') . '>');
        $itemPrevBegin = empty($itemTag) ? '' : ('<' . $itemTag 
            . (empty($prevClass) ? '' : ' class="' . $prevClass . '"') . '>');
        $itemNextBegin = empty($itemTag) ? '' : ('<' . $itemTag 
            . (empty($nextClass) ? '' : ' class="' . $nextClass . '"') . '>');
        $itemEnd = empty($itemTag) ? '' : ('</' . $itemTag . '>');
        $textBegin = empty($textTag) ? '' : ('<' . $textTag 
            . (empty($textClass) ? '' : ' class="' . $textClass . '"') . '>');
        $textEnd = empty($textTag) ? '' : ('</' . $textTag . '>');

        $linkBegin = '<a href="%s" '. (empty($aClass) ? '' : ' class="' . $aClass . '"') . '>';
        $linkCurrentBegin = empty($itemTag) ? ('<a href="%s"'
            . (empty($currentClass) ? '' : ' class="' . $currentClass . '"') . '>')
            : $linkBegin;
        $linkPrevBegin = empty($itemTag) ? ('<a href="%s"'
            . (empty($prevClass) ? '' : ' class="' . $prevClass . '"') . '>')
            : $linkBegin;
        $linkNextBegin = empty($itemTag) ? ('<a href="%s"'
            . (empty($nextClass) ? '' : ' class="' . $nextClass . '"') . '>')
            : $linkBegin;
        $linkEnd = '</a>';
        $from = max(1, $this->_currentPage - $splitPage);
        $to = min($this->_totalPage, $this->_currentPage + $splitPage);
        //输出上一页
        if ($this->_currentPage > 1) {
            echo $itemPrevBegin . sprintf($linkPrevBegin,
                str_replace($this->_pageHolder, $this->_currentPage - 1, $this->_pageTemplate) . $this->_anchor)
                . $prevWord . $linkEnd . $itemEnd;
        }
        //输出第一页
        if ($from > 1) {
            echo $itemBegin . sprintf($linkBegin, str_replace($this->_pageHolder, 1, $this->_pageTemplate) . $this->_anchor)
                . '1' . $linkEnd . $itemEnd;
            if ($from > 2) {
                //输出省略号
                echo $itemBegin . $textBegin . $splitWord . $textEnd . $itemEnd;
            }
        }
        //输出中间页
        for ($i = $from; $i <= $to; $i ++) {
            $current = ($i == $this->_currentPage);
            
            echo ($current ? $itemCurrentBegin : $itemBegin) . sprintf(($current ? $linkCurrentBegin : $linkBegin),
                str_replace($this->_pageHolder, $i, $this->_pageTemplate) . $this->_anchor)
                . $i . $linkEnd . $itemEnd;
        }
        //输出最后页
        if ($to < $this->_totalPage) {
            if ($to < $this->_totalPage - 1) {
                echo $itemBegin . $textBegin . $splitWord . $textEnd . $itemEnd;
            }
            
            echo $itemBegin . sprintf($linkBegin, str_replace($this->_pageHolder, $this->_totalPage, $this->_pageTemplate) . $this->_anchor)
                . $this->_totalPage . $linkEnd . $itemEnd;
        }
        //输出下一页
        if ($this->_currentPage < $this->_totalPage) {
            echo $itemNextBegin . sprintf($linkNextBegin,
                str_replace($this->_pageHolder, $this->_currentPage + 1, $this->_pageTemplate) . $this->_anchor)
                . $nextWord . $linkEnd . $itemEnd;
        }
    }
}

使用文档

wrapTag外层包裹标签名,默认ol
wrapClass外层包裹类名,
itemTag内层标签名, 默认li
textTag直接输出文字的标签名【这里文字指的是省略号】
textClass文字的类名【这里文字指的是省略号】
aClass超链接的类名
currentClass当前聚焦类名,
prevClass上一页类名,
nextClass下一页类名。

使用案例

php部分代码

<?php $this->pageNav('<i class="d-block text-md iconfont icon-back-arrow-"></i>', '<i class="d-block text-md iconfont icon-forward-"></i>', 2, '...', array('wrapTag' => 'div', 'wrapClass' => 'nav-links', 'itemTag' => '','aClass' => 'page-numbers','textClass' => 'page-numbers', 'currentClass' => 'page-numbers current', 'prevClass' => 'page-numbers prev', 'nextClass' => 'next page-numbers',)); ?>

html渲染结果

<div class="nav-links"><a href="https://zezeshe.com/themes/1/" class="page-numbers current">1</a><a href="https://zezeshe.com/themes/2/" class="page-numbers">2</a><a href="https://zezeshe.com/themes/3/" class="page-numbers">3</a><span class="page-numbers">...</span><a href="https://zezeshe.com/themes/8/" class="page-numbers">8</a><a href="https://zezeshe.com/themes/2/" class="next page-numbers"><i class="d-block text-md iconfont icon-forward-"></i></a></div>

源码分析

currentClassprevClass,nextClass这三个分别为当前聚焦类名,上一页类名,下一页类名,他们默认是给itemTag服务的,itemTag默认是li标签,就是包裹每一个页码超链接的标签,但是案例中他们却直接给超链接设置class了,原因就是案例中使用了'itemTag' => '',给itemTag设置为空值,这样他就不遵循默认的li标签了,同时源码中又判断,当他为空时currentClassprevClass,nextClass这三个将直接为页码超链接设置class

我写的这个东西可能不适合所有人,但是可以在这个基础上按需修改代码实现自己想要的效果。