Article pagination with OOP (split article into pages)

David Carr

9 min read - 6th May, 2011

When you have a long article you may want to split the article into pages. This is easy to do on a static page but what if you have a dynamic page if would be better to let php split the article into pages every time you have a certain tag like say [more].

This is something I needed to do and on looking around all the tutorials I could find were based on pagination with records not a single article. In the end I wrote an OOP class that can convert an article into multiple pages very easily. This class can easily be reused again and again. This tutorial will explain how to build this class and how to use it.

Still not sure what is meant by split article into pages? 

Demo: https://demos.dcblog.dev/paginatearticle

First create a new class by using the command class followed by the name of the class, it's a good practice to start your class name with a capital

class Pagebreak {

Next declare all the properties of the class, we don't want of of these properties to be available outside the class so we'll make them private by putting private before the property name. This ensure only the class can access these properties. 

private $page; //page number

private $numPages; //number of total pages

private $textarray = array(); // array of contents

private $pageCont; //current page content

Next we'll create a constructor which will run as soon as the class is called this allows us to set some option before anything is run. A constructor is almost the same as a normal method the only difference is it has a special name of __construct.

In the constructor we will check if a page number has been request if not then we'll set $this->page at 0.

public function __construct(){

        $this->page = $_GET['page'];

        if (!isset($_GET['page'])) {

        $this->page = 0;

        }

    }

Note all methods are available to be called outside the script by default inless there set as private or protected, to better illustrate the point give each method a state of public so you'll know they are available. 

Next create a method called splitText which will split the article into array chunks. The method expects to receive some text I've names it $pageCont. To split the article we will need to specify where to split it from I've chosen to use [more] as our page splitter identifier every time [more] is detected the article will be split into array chunks and stored in an array for use later on.

How this works is with the function spliti we pass the identifier to check against the story separated by a comma: spliti('[more]', $pageCont). We will need to know how many pages in total there are to find this out we count the elements in the array (inside $this->textarray) and add the value to the property $this->numPages.

public function splitText($pageCont){

$this->textarray = spliti('[more]', $pageCont);

$this->numPages = count($this->textarray);

}

The next method set's the page number in the array by calling $this->textarray then passing the requested array index by using $_GET['page'] -1 We put -1 to decrement the value by 1 since arrays start at 0.

public function setPage(){

$this->pageCont = $this->textarray[$_GET['page'] -1];

}

The method getContent checks if were on the first page if so then load the first array index from the content otherwise load the requested array index.

public function getContent(){

        if($this->page != 0){

        echo $this->pageCont;

        } else {

        echo $this->textarray[0];

        }

    }

So far our class can split an article into pages every time it find [more] and can navigate the requested pages but there are no user links to enable them to navigate easily so the next part will be to create the links.

This links in this method will b stored in a paragraph tag to make it easy to style. 

public function getPageLinks(){

The previous page link only wants to be displayed when the user is not on the first page, so a check if done to make sure page is more then 1 then a link is shown but the page number is decremented by 1 with each click.

echo "<p>n";

        //prev page

        //if page number is more then 1 show previous link

        if ($this->page > 1) {

            $prevpage = $this->page - 1;

            echo "<a href="?page=$prevpage">". 'Previous Page</a> ';

        }

The next part displayed the page numbers and to make it clear what page the user is on the current page will not be linked. The links are generated by using a for loop that loops for as many chucks that exist in $this->numPages.

//page numbers

        for($i = 1; $i <= $this->numPages ; $i++){

            if($this->numPages > 1){ // if more then 1 page show links

                if(($this->page) == $i){ //if page number is equal page number in loop don't link it

                    echo "$in ";

                    } else {

                            if($this->page == 0){ //if no page numbers have been clicked don't link first page link

                                if($i == 1){

                                    echo "$in ";

                                } else { // link the rest

                                    echo "<a href="?page=$i">$i</a>n ";

                                }

                           } else { // link pages

                                echo "<a href="?page=$i">$i</a>n ";

                            }

                    }

            }

        }

Finally create the next page link, this is essentially the same as the preivous link, this time we make sure if we are on the last page then don't show next page link. 

//next page

        //if page number is less then the total number of pages show next link

        if ($this->page <= $this->numPages - 1) {

            if($this->page == 0){ //if no page numbers have been clicked minus 2 from the next page link

                $nextpage = $this->page + 2;

            } else {

                $nextpage = $this->page + 1;

                }

                echo "<a href="?page=$nextpage">". 'Next Page</a>';

        }



        echo "</p>n";

Once the paragraph is closed the method is closed then the class. Thats the class created it can now be used. First we'll need some content to test with here's some sample text that will suit our needs all contained within a single variable, this could easily come from a database.

$storyCont = "<p><strong>The UK has suffered its coldest night of the winter so far with temperatures plummeting to -22.3C (-8.1F) in a village in Sutherland in the Highlands.</strong></p>

<p>Overnight temperatures of -10C (14F) were widespread, leaving commuters again battling icy roads and pavements amid &amp;quot;stretched&amp;quot; road salt supplies.</p>

[more]

<p>Many schools remain shut, with rail and air travel again hit by delays. Fresh snow is falling in eastern England. </p>

<p>The weekend could be colder, as another week of Arctic conditions is forecast. </p>

[more]

<p>Up to 4,000 homes are without water after a main burst outside the Royal Berkshire Hospital in Reading. The hospital was largely unaffected. </p>

<p>Thousands of schools remain shut, with warnings that some exam candidates could have to wait five months to sit GCSE and A-level modules in England, Wales and Northern Ireland if weather prevents them taking them next week. </p>

<p>Exams watchdog Ofqual said in cases where candidates would not have a second chance to sit papers in the summer, applications could be made for &amp;quot;special consideration&amp;quot;. </p>

[more]

<p>This involves pupils disadvantaged by circumstances being awarded up to an extra 5% of the maximum marks. </p>

<p>Milk deliveries have also been disrupted, with tankers struggling to reach dairy farms. </p>

<p>Some farmers have had to dump supplies as few have storage facilities to hold more than a day's stock.</p>

<!-- Inline Embbeded Media -->

<!-- This is the embedded player component -->

<!-- end of the embedded player component -->

<!-- END of Inline Embedded Media -->

<p>Easyjet has cancelled about 30 flights at airports including Gatwick, Liverpool, Belfast and Stansted, while Norwich Airport has been closed. </p>

<p>British Airways said passengers should check the status of their flight before leaving for the airport. </p>

<p>Overnight it had asked passengers on some flights arriving at Heathrow's Terminal 5 to leave without their luggage, with bags being sent on to them later. </p>

[more]

<p>Train companies operating revised timetables include East Coast, ScotRail, First Great Western, South West Trains, Southern and Southeastern. </p>

<p>The breakdown of a train travelling from Brussels to London in the Channel Tunnel on Thursday has affected Eurostar services. </p>

<p>Supplies of road grit are close to running out in some areas, and many councils are restricting gritting to major roads. </p>

<p>Thieves using a lorry with heavy lifting-gear have stolen a grit bin with two tonnes of salt intended for streets and footpaths from a road in Newton Mearns outside Glasgow. </p>

<p>The Local Government Association admitted reserves were &amp;quot;stretched&amp;quot;, while the government is helping suppliers prioritise areas most in need.</p>";

Now we have some content to work with before using the class we have to instantiate it this is done by creating a varible passing the new keyword followed by the class name note the class name is case sensitive.

$paginate = new Pagebreak();

Now the class has been instantiated we pass the content.

$paginate->splitText($storyCont);

Now set the page number.

$paginate->setPage();

All is ready now all that's needed it the content to be displayed this is done by calling the method getContent, which prints the converted content to the screen.

$paginate->getContent();

To enable users to access the pages of the article we call the getPageLinks with displayed the navigation menu.

$paginate->getPageLinks();

Here's the full class:

class Pagebreak {

    private $page; //page number

    private $numPages; //number of total pages

    private $textarray = array(); // array of conents

    private $pageCont; //current page content


    public function __construct(){

        $this->page = $_GET['page'];

        if (!isset($_GET['page'])) {

        $this->page = 0;

        }
    }


    public function splitText($pageCont){

        $this->textarray = spliti('[more]', $pageCont);

        $this->numPages = count($this->textarray);

    }


    public function setPage(){

        $this->pageCont = $this->textarray[$_GET['page'] -1];

    }


    public function getContent(){

        if($this->page != 0){

        echo $this->pageCont;

        } else {

        echo $this->textarray[0];

        }

    }


    public function getPageLinks(){

        echo "<p>n";

        //prev page

        //if page number is more then 1 show previous link

        if ($this->page > 1) {

            $prevpage = $this->page - 1;

            echo "<a href="?page=$prevpage">". 'Previous Page</a> ';

        }

        //page numbers

        for($i = 1; $i <= $this->numPages ; $i++){

            if($this->numPages > 1){ // if more then 1 page show links

                if(($this->page) == $i){ //if page number is equal page number in loop don't link it

                    echo "$in ";

                    } else {

                            if($this->page == 0){ //if no page numbers have been clicked don't link first page link

                                if($i == 1){

                                    echo "$in ";

                                } else { // link the rest

                                    echo "<a href="?page=$i">$i</a>n ";

                                }

                           } else { // link pages

                                echo "<a href="?page=$i">$i</a>n ";

                            }

                    }

            }

        }

        //next page

        //if page number is less then the total number of pages show next link

        if ($this->page <= $this->numPages - 1) {

            if($this->page == 0){ //if no page numbers have been clicked minus 2 from the next page link

                $nextpage = $this->page + 2;

            } else {

                $nextpage = $this->page + 1;

                }

                echo "<a href="?page=$nextpage">". 'Next Page</a>';

        }

        echo "</p>n";

    }

}

Here's a usage example:

$paginate = new Pagebreak(); $paginate->splitText($storyCont); $paginate->setPage(); $paginate->getContent(); $paginate->getPageLinks(); ```

 

0 comments
Add a comment

Copyright © 2024 DC Blog - All rights reserved.