• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Paginated Thread: Control Number Of Pages Displayed At Once

TheBigK

Well-known member
#1
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
#3
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
#5
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
#6
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
#7
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

Active member
#8
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;
            }
        }