Paginated Thread: Control Number Of Pages Displayed At Once

TheBigK

Well-known member
On a thread spanning several pages, how do I control the number of pages displayed in the list?

A picture is worth 1000 words: -

pages-xenforo.jpg

By default, 5 pages are shown at a time. I want to display just 3. So it should display

[33] [34] [35] , instead of [31] [32] [33] [34] [35] [36].
 

MattW

Well-known member
I think it's controlled by this function in /library/XenForo/Template/Helper/Core.php

PHP:
        /**
        * Helper to get page navigation (all pages, for scrolling pagenav version).
        *
        * @param string $templateClass Name of the template class to instantiate
        * @param string $linkFunction Name of the linking function to call (in this class)
        * @param integer $perPage Items to display per page
        * @param integer $totalItems Total number of items
        * @param integer $currentPage Current page number
        * @param string $linkType Type of link to create
        * @param mixed $linkData Data for the link
        * @param array $linkParams List of key value params for the link; page will be set as needed
        * @param array $options Options to control the building
        *
        * @return string|XenForo_Template_Abstract
        */
        protected static function _getPageNav($templateClass, $linkFunction, $perPage, $totalItems, $currentPage,
                $linkType, $linkData = null, array $linkParams = array(), array $options = array()
        )
        {
                // abort if there are insufficient items to make multiple pages
                if ($totalItems < 1 || $perPage < 1)
                {
                        return '';
                }
 
                $options = array_merge(
                        array(
                                'unreadLink' => '',
                                'template' => 'page_nav',
                                'displayRange' => 2 //TODO: make this come from an option?
                        ),
                        $options
                );
                $unreadLinkHtml = htmlspecialchars($options['unreadLink'], ENT_COMPAT, 'iso-8859-1', false);
 
                $pageTotal = ceil($totalItems / $perPage);
 
                // abort if there is only one page
                if ($pageTotal <= 1)
                {
                        if (!empty($options['unreadLink']))
                        {
                                return new $templateClass($options['template'], array(
                                        'unreadLinkHtml' => $unreadLinkHtml,
                                        'pageTotal' => $pageTotal
                                ));
                        }
 
                        return '';
                }             
               
                $currentPage = min(max($currentPage, 1), $pageTotal);
 
                // number of pages either side of the current page
                $range = $options['displayRange'];
                $scrollSize = 1 + 2 * $range;
                $scrollThreshold = $scrollSize + 2;
 
                if ($pageTotal >$scrollThreshold)
                {
                        $startPage = max(2, $currentPage - $range);
                        $endPage = min($pageTotal, $startPage + $scrollSize);
 
                        $extraPages = $scrollSize - ($endPage - $startPage);
                        if ($extraPages > 0)
                        {
                                $startPage -= $extraPages;
                        }
                }
                else
                {
                        $startPage = 2;
                        $endPage = $pageTotal;
                }
 
                if ($endPage > $startPage)
                {
                        $endPage--;
                        $pages = range($startPage, $endPage);
                }
                else
                {
                        $pages = array();
                }
 
                if (isset($linkParams['_params']) && is_array($linkParams['_params']))
                {
                        $tempParams = $linkParams['_params'];
                        unset($linkParams['_params']);
                        $linkParams = array_merge($tempParams, $linkParams);
                }
 
                $templateVariables = array(
                        'pageTotal' => intval($pageTotal),
                        'currentPage' => $currentPage,
 
                        'pages' => $pages,
                        'range' => $range,
                        'scrollThreshold' => $scrollThreshold,
 
                        'startPage' => $startPage,
                        'endPage' => $endPage,
 
                        'prevPage' => ($currentPage > 1 ? ($currentPage - 1) : false),
                        'nextPage' => ($currentPage < $pageTotal ? ($currentPage + 1) : false),
 
                        'pageNumberSentinel' => XenForo_Application::$integerSentinel,
 
                        'linkType' => $linkType,
                        'linkData' => $linkData,
                        'linkParams' => $linkParams,
 
                        'maxDigits' => strlen($pageTotal),
 
                        'unreadLinkHtml' => $unreadLinkHtml
                );
 
                $template = new $templateClass($options['template'], $templateVariables);
 
                return $template;
        }
 

Chris D

XenForo developer
Staff member
I'm not sure that was the reason at the time. A year ago XenForo didn't have responsive design so it would have looked no better or worse on mobile.
 

1BJK903

Active member
I'm not sure that was the reason at the time. A year ago XenForo didn't have responsive design so it would have looked no better or worse on mobile.

Hmm, might be, but personally, I find it better if it were 3 instead of 5. Can you tell me btw how I can make that happen? I am looking at the code, but I can't see where it outputs 5 instead of another number?
 

Chris D

XenForo developer
Staff member
In that code. Change:
PHP:
$range = $options['displayRange'];

To:

PHP:
$range = 1;

That will then leave you with a gap like this:

upload_2014-2-16_11-25-45.png

To close that gap, you need to add this to EXTRA.css:

Code:
.PageNav .scrollable
{
    width: 70px;
}

Note, on a custom style you may need to adjust the width accordingly as it depends on the width and margin of the other elements.

The end result should be:

upload_2014-2-16_11-28-13.png

upload_2014-2-16_11-28-28.png
 

king8084

Well-known member
Hi,

I have been using these helpful posts to edit the range shown of the 'scrollable' pages, editing Core.php. I can see the changes happening but I'm not sure if there's a way to just show 2 pages between the < and >, rather than 3 in the example above. I've tried several combinations of numbers, successfully gotten it to show 2, but when I click the > arrow it just moves 1 page at a time, rather than 2.

So ideally it would be:
1 < 5 6 > 100
then after clicking the right scrollable arrow:
1 < 7 8 > 100

Right now it's currently doing this after clicking the arrow:
1 < 6 7 > 100

Here's my current code for this function. The only 2 things I've changed currently are the things commented "old setting" and "new setting"

I set the range to 0 because I want the current page to be the first one shown in the 'scrollable' section.
Code:
$currentPage = min(max($currentPage, 1), $pageTotal);

        // number of pages either side of the current page
        //$range = $options['displayRange']; // old setting
        $range = 0; // new setting

        //$scrollSize = 1 + 2 * $range; //old setting
        $scrollSize = 2; // new setting

        $scrollThreshold = $scrollSize + 2;

        if ($pageTotal > $scrollThreshold)
        {
            $startPage = max(2, $currentPage - $range); 
            $endPage = min($pageTotal, $startPage + $scrollSize); 

            $extraPages = $scrollSize - ($endPage - $startPage);
            if ($extraPages > 0)
            {
                $startPage -= $extraPages;
            }
        }
 
Top