Welcome Guest, Not a member yet? Register   Sign In
Pagination: Auto split Article/Post into multiple pages
#1

[eluser]PhireGuys[/eluser]
I'm old to EE but new to CI but so far I'm loving it. I needed to create a pagination but for articles that are over a certain length. For example, if an article was more than 12,000 characters, I wanted to split it into multiple pages. Since the site had a backlog of articles, we didn't want to insert an identifier in the actual articles to say where to break the page, so I needed CI to do it for me.

I came up with this solution, hopefully it will inspire others to further develop this if needed. It just goes to show you can do anything you want if you spend some time on it (took me a day and a half).

Here is my code:

Pagination.php

I used a modified version of Pagination.php (http://codeigniter.com/wiki/Pagination_Mod/) library to fulfill my needs. You should use this modified version, and note that I added a function that lets me know if the current page is the last one. Just paste it into the above paginate version:

Code:
// --------------------------------------------------------------------

/**
* Returns if this is the last page or not
*
* @access    public
* @return    boolean
*/    
function last_page()
{
    $CI =& get_instance();
    if ($CI->uri->segment($this->uri_segment) != 0)
    {
        $cur_page = $CI->uri->segment($this->uri_segment);
        
        // Prep the current page - no funny business!
        $cur_page = (int) $cur_page;
    }
    else
        $cur_page = 1;
        
    $num_pages = ceil($this->total_rows / $this->per_page);
    

    if ($cur_page == $num_pages)
        return true;
    else
        return false;
}

Controller Functions

I needed some custom functions in my controller to take care of knowing when to split an article and to make sure I'm not destroying the HTML or readability.

This function takes care of cutting the string with HTML and paragraph awareness. It looks at where you want to cut, then finds the nearest <p> tag after that and then cuts from there. This way, you won't cut in the middle of a paragraph.

Code:
/**
* word-sensitive substring function with html tags awareness
* @param text The text to cut
* @param len The maximum length of the cut string
* @param start Where to begin cutting in the string
* @returns string
**/
function substrws( $text, $len, $start )
{
    
    $raw_text_length = strlen($text);
            
    //remaining text is less then max length
    if ($raw_text_length < $len + $start)
        $len = $raw_text_length;
        
        
    //check if white space before
    if ($start - $len >= 0 || $len == $raw_text_length)
        $prev_whitespace_pos = strpos($text,"<p>", $start);
    else
        $prev_whitespace_pos = 0;
    
    //check if white space after
    if ($len + $start > $raw_text_length)
        $next_whitespace_pos = $raw_text_length;
    else
        $next_whitespace_pos = strpos($text, "<p>", $len + $start);
    if ($next_whitespace_pos === FALSE)
        $next_whitespace_pos = $len + $start;
    
    
    $text = substr($text, $prev_whitespace_pos, $next_whitespace_pos - $prev_whitespace_pos);
    

    // close unclosed html tags
    if (preg_match_all("|<([a-zA-Z]+)>|",$text,$aBuffer))
    {
        if (!empty($aBuffer[1]))
        {
            preg_match_all("|</([a-zA-Z]+)>|",$text,$aBuffer2);

            if (count($aBuffer[1]) != count($aBuffer2[1]))
            {
                foreach ($aBuffer[1] as $index => $tag)
                {
                    if( empty($aBuffer2[1][$index]) || $aBuffer2[1][$index] != $tag)
                        $text .= '</'.$tag.'>';
                }
            }
        }
    }
    return $text;
}

This next function takes care of giving me a remainder, it's needed to determine how long I want my pages to be.

Code:
function getremainder($x, $y)
{
    $value = ($x / $y);
    return $value - intval($value);
}

The Controller

Lastly, I had to actually put my code into the controller to activate the paginate and all that good stuff.

Code:
//setup paginate for long articles
$this->load->library('pagination');
if (strlen($data['post']->article) > 12000)
{
    $config['base_url'] = site_url('articles/'.$data['category_title_url'].'/'.$data['post']->title_url);
    $config['total_rows'] = strlen($data['post']->article);
    $config['num_links'] = 14;
    $config['uri_segment'] = 4;
    $config['full_tag_open'] = '<div class="pagination">Multipage Article:&nbsp;&nbsp;&nbsp;';
    $config['full_tag_close'] = '</div>';
    
    //do some math to stop tiny leftover pages
    if ($this->getremainder(strlen($data['post']->article), 8000) >= .2)
        $config['per_page'] = '8000';
    else if ($this->getremainder(strlen($data['post']->article), 7000) >= .2)
        $config['per_page'] = '7000';
    else
        $config['per_page'] = '10000';
    
    
    $this->pagination->initialize($config);
    
    //pagination: modify data output for paginate
    if ($this->uri->segment(4) == '')
    {
        $data['post']->article = $this->substrws($data['post']->article, $config['per_page'], 0);
    }
    else
    {
        $range = ($this->uri->segment(4)-1) * $config['per_page'];    //gets the offset
        $data['post']->article = $this->substrws($data['post']->article, $config['per_page'], $range);
    }
    
    //add ... continued on next page
    if (!$this->pagination->last_page())
        $data['post']->article.= '<p><strong>Continue reading on next page...</strong></p>';

}

Now, please note I have some custom stuff still in there. So if a variable is being called without you knowing what the value is, it is because I defined it earlier but didn't post it here. But $data['post']->article held my article, that is what is most important to know.


Messages In This Thread
Pagination: Auto split Article/Post into multiple pages - by El Forum - 07-09-2010, 08:23 AM
Pagination: Auto split Article/Post into multiple pages - by El Forum - 07-09-2010, 08:25 AM
Pagination: Auto split Article/Post into multiple pages - by El Forum - 07-12-2010, 04:52 AM
Pagination: Auto split Article/Post into multiple pages - by El Forum - 07-12-2010, 07:22 AM



Theme © iAndrew 2016 - Forum software by © MyBB