The Paginate class is a helper class for generating paginated navigation and paginated context awareness such as current page and total pages.

Lets look at an example, in this example we will show a controller using a model to fetch events from the database and create a Paginate class based on the results, we will then load the results and the Paginate class into a Twig template.

The Paginate class is also what is returned when you use the {% page %} tag provided by Disco (see the Templating docs for more info).

You can also use the Router method paginate to easily define routes to a controller which sets a route up for use with pagination (see the Router docs for more info).

By default paginated slugs that are generated using the Paginate class use the format /page/{page} in addition to the base URI of the paginated route (it will not add the format twice, and it will also appropriately keep any GET variables at the end of the URI) . The {page} is what is replaced by the current page number. You can configure this format by setting the config key paginate in your application congratulation file.

    //***************
    // In our Controller
    //***************
    public function getEvents($page){
    
        $limit = 10;
    
        $events = (new \App\model\Events)
            ->select('id,name,description,held_on_date')
            ->order('held_on_date DESC')
            ->limit($page,$limit)
            ->asArray();
    
        $total = (new \App\model\Events)
            ->select('COUNT(*) AS total')
            ->first()['total'];
    
        // First argument is the current page number
        // Second argument is the total number of results
        // Third argument is the limit used/per page 
        $Paginate = new \Disco\classes\Paginate( $page , $total , $limit );
    
        \Template::with('events', [
            'page' => $Paginate,
            'events' => $events,
        ]);
    
    }//getProducts
    
    
    
    //*************************
    // In our Template (events.html)
    //*************************
    
        <div>Viewing events {{ page.first }} - {{ page.last }} of {{ page.total }}</div>
    
        {% for event in events %}
    
             <div class='event-feed-item'>
    
                 <h2>{{ event.name }}</h2>
                <div>{{ event.held_on_date }}</div>
    
                 {{ event.description }}
    
             </div>
    
        {% endfor %}
    
    
        <ul class='pagination'>
    
            {% if page.prevUrl %}
    
                <li class='pagination-previous'><a href='{{ page.prevUrl }}'>prev</a></li>
    
            {% endif %}
    
    
            {% set pages = page.getPrevUrls(5) %}
    
            {% for i,page in pages %}
    
                <li><a href='{{ page }}'>{{ i }}</a></li>
    
            {% endfor %}
    
    
            <li class='current'><a href='{{ page.currentUrl }}'>{{ page.currentPage }}</a></li>
    
    
            {% set pages = page.getNextUrls(5) %}
    
            {% for i,page in pages %}
    
                <li><a href='{{ page }}'>{{ i }}</a></li>
    
            {% endfor %}
    
    
            {% if page.nextUrl %}
    
                <li class='pagination-next'><a href='{{ page.nextUrl }}'>next</a></li>
    
            {% endif %}
    
        </ul>
    
    
    {% endpage %}

    Properties:

    • currentPage - The current page being paginated.
    • total - The total number of results/items available for pagination..
    • first - The position of the first item in the paginated result set, ex: if you have 5 pages of 10 items each, and your on page 3, first will be 31.
    • last- The position of the last item in the paginated result set, ex: if you have 5 pages of 10 items each, and your on page 5, last will be 60. If there were less items than the limit, then last will be that number, ex: your on page 5 but there are only 58 items, last will be 58 and not 60.
    • perPage - The number of results displayed per page.
    • totalDisplayed - The number of results being displayed on the current page.
    • totalPages - The total number of pages for the paginated results.
    • prevUrl - The url to the previous page in the paginated results.
    • currentUrl - The url to the current page in the paginated results.
    • nextUrl - The url to the next page in the paginated results.
    • firstUrl - The url to the first page in the paginated results.
    • lastUrl - The url to the last page in the paginated results.

    Methods:

    • getPageUrl(integer) - Get the url for a specified page number.
    • getPrevUrls(null | integer) - Get an array of paginated urls that come before the current page. If an integer is passed only return up to that number of previous urls.
    • getNextUrls(null | integer) - Get an array of paginated urls that come after the current page. If an integer is passed only return up to that number of next urls.
    • getAllUrls - Get an array of all paginated urls.
    • getRangeUrls(integer, integer) - Get an array of paginated urls between the first integer argument and the second integer argument.
    • getEasyMarkup - Get basic easy pagination markup (as shown in the example above).

    Meta Tags

    To aid in SEO efforts some meta information is added to the head of the page to help out search engines as indicated by Google here.

    • <link ref="prev" href="{link to previous page}"/> - A ref prev link tag is added to point to the previous page if it exists.
    • <link ref="next" href="{link to next page}"/> - A ref next link tag is added to point to the next page if it exists.
    • <link rel="canonical" href="{link to first page}"/> - When on the first page of results and the current request URI does not contain your configured pagination slug a canonical link tag is added to point to the first page of results. This is done because typically when paginating results the template/URI that starts the pagination will not contain the page slug.

    Paginate The Disco Way #

    Lets look at an example now that uses all the pieces of the framework that lend themselves to making awesome and easy pagination.

    //************************************
    // The router defined to handle the pagination
    //************************************
    
    // The routers paginate method will automatically use the 
    // default pagination format or your configured pagination format 
    // to build and resolve the appropriate URIs
    Router::paginate('/events/{type}', function($type, $page){
    
        // notice we don't call any methods  which would execute the models query
        // we will let the page tag handle that in the template
        $events = (new \App\model\Events)
            ->select('id,name,description,type,held_on_date')
            ->where('type=?', $type)
            ->order('held_on_date DESC')
            ->limit(10);
    
        \Template::with('events', [
            'eventsModel' => $events
        ]);
    
    })->where('type', '(music|catering|wedding)');
    
    
    
    //*************************
    // Now our events.html template
    //*************************
    
    {% page eventsModel as events %}
    
        // We assign the output of the model to the variable `events` using the `as` keyword
        {% for event in events %}
            // Where we output our markup for each event
        {% endfor %}
    
        // The page tag automatically injects a Paginate class instance named `page` with 
        // the appropriate data passed to the constructor based on the model
        {{ page.getEasyMarkup() }}
    
    {% endpage %}