HOWTO: Proper news pagination (with page numbers!)

Do something cool with CMS? Show us ...
This board is for 'Answers', and the discussion of answers... Not for questions.
cyberman

Re: HOWTO: Proper news pagination (with page numbers!)

Post by cyberman »

Daniel15 wrote: So, I decided to try it myself, based on bits and pieces I found on this forum :).
Thanx for that solution ...
I though I should post my solution here (I'll post it to the Wiki eventually ;))
Nice idea  8) ...
Last edited by cyberman on Tue Feb 20, 2007 12:07 pm, edited 1 time in total.
gazoo

Re: HOWTO: Proper news pagination (with page numbers!)

Post by gazoo »

Daniel15, this is an excellent piece of code. Great work!

I recently posted a topic about pagination of news articles on the backend or from within the admin interface.
http://forum.cmsmadesimple.org/index.php/topic,10199.0.html

I've made reference to your post but I was also hoping that with your expertise, you might be able to also come up with a routine or adapt your code to help for pagination of news articles on the backend.

I look forward to your thoughts on this.

Thanks!
Gazoo
brdon

Re: HOWTO: Proper news pagination (with page numbers!)

Post by brdon »

Do you have a site where I can see it in action?  Great work!
mahjong

Re: HOWTO: Proper news pagination (with page numbers!)

Post by mahjong »

There is only one big problem with this otherwise ingenious script. The total count doesn't take into account news categories and expiration dates. For instance, I need to display news of the past for members (tagged with the "member" category) on an archives page.

Code: Select all

{newsindex number='10'}

{cms_module module=CustomContent}
{if $customcontent_loggedin}
  {if $customcontent_memberof_member}
      {cms_module module="news" category="general,member" showarchive="true" number=$news_number start=$news_start}
  {else}
      {cms_module module="news" category="general" showarchive="true" number=$news_number start=$news_start}
{/if}
Vin

Re: HOWTO: Proper news pagination (with page numbers!)

Post by Vin »

It's about time someone posted the solution of the count of news depending on a news category and expiration date. I had in mind to figure the problem out earlier, but didn't have time - until now. So, here is my version of the news pagination UDT:

Code: Select all

global $gCms, $number;

$start = ($_REQUEST['start']) ? $_REQUEST['start'] : $params['start'];
$number = ($_REQUEST['number']) ? $_REQUEST['number'] : $params['number'];

function join_uri($middle)
{ 
  global $gCms, $number;
	return 'index.php?page=' . $gCms->variables['page_name'] . '&start=' . $middle . '&number=' . $number;
} 
$next_uri = join_uri($start + $number);
$prev_uri = join_uri($start - $number);

$smarty->assign('news_start', $start);
$smarty->assign('news_number', $number);
$smarty->assign('news_next_url', $next_uri);
$smarty->assign('news_prev_url', $prev_uri);

$db = &$gCms->db;
$tables=cms_db_prefix().'module_news';
$cond='';
if (isset($params['count_expired'])) {
  switch ($params['count_expired']) {
    case 'true': $cmpr='<';
    	break;
    case 'false': $cmpr='>';
    	break;
  default: return 'Wrong argument in "count_expired"';
  }
	$cond='(end_time '.$cmpr.' NOW() )';
}
if (isset($params['category'])) {
  $tables.=', '.cms_db_prefix().'module_news_categories';
  if ($cond!='') $cond.=" AND ";
  $cond.="(news_category_name
   LIKE '".$params['category']."')
   AND (".cms_db_prefix()."module_news_categories.news_category_id = 
   ".cms_db_prefix()."module_news.news_category_id)";
}
if($cond!='') $cond='WHERE ('.$cond.')';
$query = 'SELECT COUNT(news_id) FROM '.$tables.' '.$cond;
$newscount = &$db->GetOne($query);
$smarty->assign('newscount',$newscount);

$crumbcount=Floor($newscount/$number);
unset($newscrumbs);
for ($i=0;$i<=$crumbcount;$i++ ) {
    $newscrumbs.="<a href=\"".join_uri($i*$number)."\">".($i+1)."</a>";
    if ($i<$crumbcount){
      if (isset($params['delimiter'])) {
      	$newscrumbs.=$params['delimiter'];
      }
    }
  }
$smarty->assign('newscrumbs',$newscrumbs);
Call the UDT {newsindex} with these parametres:
(needed)start(the starting number of the first news; (first is 0))
(needed)number(the maximum of the news showed per page)
(optional)category
(optional)count_expired='true/false' (if not specified, it will count all the news in the scope)
(optional)delimiter (for instance '|')

Then, further in the page:
{if $news_start > '0'}Previous {/if}
shows the link to the previous news (if any);
{if $news_start + $news_numberNext {/if}
the same for the next ones;
{$newscrumbs}
for the news pagination.

Maybe I should rewrite wiki...
taufikp
Forum Members
Forum Members
Posts: 27
Joined: Tue May 01, 2007 2:52 am

Re: HOWTO: Proper news pagination (with page numbers!)

Post by taufikp »

Thanks Daniel15 and Vin! Very useful code!  ;D
cyberman

Re: HOWTO: Proper news pagination (with page numbers!)

Post by cyberman »

From Blog
- News enhancements
- Frontend Pagination for summary articles
harleyquinn
Forum Members
Forum Members
Posts: 36
Joined: Fri Dec 22, 2006 4:29 pm
Location: Philadelphia, PA

Re: HOWTO: Proper news pagination (with page numbers!)

Post by harleyquinn »

Unfortunately, this method doesn't work with News 2.3, and I prefer this version to the pagination built into the current news module.

Did anyone out there get this working with News 2.3? I've been trying to figure this out for the past two days with no luck.
Peciura

Re: HOWTO: Proper news pagination (with page numbers!)

Post by Peciura »

Yet another solution to have lots of numbers on page :).

This solution should work with ugly url only.
This method does not depend on any module, but you need to know :
  a. current page number
  b. page count
  c. pagination url parameter (e.g. 'pagenum')

Originally pagination on Products module looks like
<< < Page 444 of 1000 > >>
Pagination on template looks like

Code: Select all

{if isset($pagecount) && $pagecount gt 1}

{$firstlink} {$prevlink}  {$pagetext} {$curpage} {$oftext} {$pagecount}  {$nextlink} {$lastlink}

{/if}
We can make it look like this (444 is a current page)
1  90  190  290  390  400  410  420  430  440  441  442  443  444 445  446  447  448  458  468  478  488  498  598  698  798  1000
Colors just explains pagination pattern. And here is pagination template

Code: Select all

{if isset($pagecount) && $pagecount gt 1}
	{if $curpage>1}
		{assign var='tmp_link' value=$prevlink}
	{else}
		{assign var='tmp_link' value=$nextlink}
	{/if}

	{pagination link=$tmp_link param='page' max=$pagecount  current=$curpage assign='temp' pattern='4,5,3' extreme='true'}

	
		{foreach from=$temp key='page_nb' item='tmp'}
			{if !empty($tmp)}
				{$page_nb}
			{else}
				{$curpage}
			{/if}
			{' '};
		{/foreach}
	
{/if}
You can see 3 comma separated numbers in pattern. First one corresponds to 4 pages that are next to each other, second - 5 pages that differ by 10 from each other, third - 3 pages that differ by 100 and so on. If parameter extreme is not empty links to the first and the last page will be included if not present.

This is an UDT {pagination} that assigns array of pagination links

Code: Select all

array($page_number => 'http://www ...', ... )
Current page has empty value. Most parameters are from standard pagination.

Code: Select all

/**
* Create array of pagination links
*
* @params   string   $params['link']      Mandatory. Href or complete link (href will be extracted).
* @params   string   $params['current']   Mandatory. Current page number
* @params   string   $params['max']      Mandatory. Max page number
* @params   string   $params['param']   Mandatory. Unique part of url param. e.g. 'pagenumber'
* @params   string   $params['assign']   Mandatory. Name of variable to assign result array($page_number=>'http://www... ', ...)
* @params   string   $params['pattern']   Pagination pattern default '10,10'.
* @params   string   $params['extreme']   Include first and last links
*
*/
$default_pattern = '10,10';

if (!empty($params['link'])      &&
   !empty($params['current'])   &&
   !empty($params['max'])      &&
   !empty($params['param'])   &&
   !empty($params['assign'])){

   $link = preg_replace("/.*href=[\"\' ]*([^\"\']*).*/", '$1', $params['link']);
   $link = html_entity_decode(trim(strip_tags($link)));   //extract href
   $param = trim($params['param']);
   $assign = trim($params['assign']);
   $max = intval($params['max']);
   $current = intval($params['current']);
   $params['pattern'] = (empty($params['pattern']))? $default_pattern : $params['pattern'];
   $pattern = explode(',', trim($params['pattern']));
   $extreme = (empty($params['extreme']))? FALSE : TRUE;

//debug_display($param);
   if(strpos($link, $param.'=')){
      $smarty = cms_utils::get_smarty();
      $links = array();

      $i_min = $i_max = $current;
      foreach($pattern as $exp=>$count){
         for($i = 1; $i <= $count; $i++){
            $delta = pow(10, $exp);
            if($i_min > ($delta + 1)){
               $i_min -= $delta;
               $links[$i_min] = htmlentities(preg_replace( "/$param=\d+/", $param.'='.$i_min, $link));
            }
            if($i_max < ($max - $delta)){
               $i_max += $delta;
               $links[$i_max] = htmlentities(preg_replace(  "/$param=\d+/", $param.'='.$i_max, $link));
            }
         }
         if ($extreme){
            if($current != 1 && !isset($links[1])){
               $links[1] = htmlentities(preg_replace( "/$param=\d+/", $param.'=1', $link));
            }
            if($current != $max && !isset($links[$max])){
               $links[$max] = htmlentities(preg_replace( "/$param=\d+/", $param.'='.$max, $link));
            }
         }
         $links[$current] = '';
      }
      ksort($links);
      $smarty->assign($assign, $links);
   }
}
EDIT: fixed broken UDT. Removed colors from code and template.
Last edited by Peciura on Fri Apr 06, 2012 6:24 am, edited 3 times in total.
Peciura

Re: HOWTO: Proper news pagination (with page numbers!)

Post by Peciura »

OK, here is modified News summary default template (CMSms 1.8.1, News 2.10.6).
Old pagination is green, new - brown. You can also combine both paginations to one.

Here are parameters used by UDT {pagination}:

link - pagination link or link location. For News pagination it can be  {$firstpage}, {$prevpage}, {$nextpage}, {$lastpage}. It is important that this value is not empty.

param - url param name that stores page number. It is not necessary to write complete name but it should be unique in all url (link location) at least. For New module it can be 'pagenumber' it also could look like this 'cntntpagenumber' or even 'md417apagenumber' and so on.

assign - variable name you want to store pagination links in. In example it is 'temp' so variable {$temp} contains all pagination links. It is an array with urls as array members and page numbers as keys. Member with empty key ('') is url to current page.

pattern - it defines how many and what preceding and subsequent pages are in pagination. I you write '5', there will be  five preceding pages, current page and 5 subsequent pages (e.g. '43 44 45 46 47 48 49 50 51 52 53' ). If you write '5,2', there will be added 2 pages from both sides but they will differ by 10 from each other (e.g. '23 33' and  '63 73'). Every number in pattern increases pagination step 10 times for number of pages it carries, it works for both sides of a pagination. I have colored pattern and resulting pagination on previous example.

extreme - default is empty string. If parameter is not empty it will force the first and the last pages in pagination, in other word pagination will always have link '1' (to the first page) and 'X', where X is the very last page.
{* This section shows a clickable list of your News categories. *}

{foreach from=$cats item=node}
{if $node.depth > $node.prevdepth}
{repeat string="" times=$node.depth-$node.prevdepth}
{elseif $node.depth " times=$node.prevdepth-$node.depth}

{elseif $node.index > 0}
{/if}

{if $node.count > 0}
{$node.news_category_name}{else}{$node.news_category_name} {/if}
{/foreach}
{repeat string="" times=$node.depth-1}


{* this displays the category name if you're browsing by category *}
{if $category_name}
{$category_name}
{/if}

{* if you don't want category browsing on your summary page, remove this line and everything above it *}

{if $pagecount > 1}
 
{if $pagenumber > 1}
{$firstpage} {$prevpage} 
{/if}
{$pagetext} {$pagenumber} {$oftext} {$pagecount}
{if $pagenumber
{/if}


{if isset($pagecount) && $pagecount > 1}
  {if $pagenumber>1}
     {assign var='tmp_link' value=$prevpage}
  {else}
     {assign var='tmp_link' value=$nextpage}
  {/if}

  {pagination link=$tmp_link param='pagenumber' max=$pagecount  current=$pagenumber assign='temp' pattern='9' extreme='true'}

 
     {foreach from=$temp key='page_nb' item='tmp'}
        {if !empty($tmp)}
           {$page_nb}
        {else}
           {$pagenumber}
        {/if}
        {'&nbsp'};
     {/foreach}
 
{/if}


{foreach from=$items item=entry}


{if $entry->postdate}

{$entry->postdate|cms_date_format}

{/if}


moreurl}" title="{$entry->title|cms_escape:htmlall}">{$entry->title|cms_escape}



{$category_label} {$entry->category}


{if $entry->author}

{$author_label} {$entry->author}

{/if}

{if $entry->summary}

{eval var=$entry->summary}



[{$entry->morelink}]


{else if $entry->content}


{eval var=$entry->content}

{/if}

{if isset($entry->extra)}
   
       {eval var=$entry->extra}
{* {cms_module module='Uploads' mode='simpleurl' upload_id=$entry->extravalue} *}
   
{/if}
{if isset($entry->fields)}
 {foreach from=$entry->fields item='field'}
   
       {if $field->type == 'file'}
         file_location}/{$field->value}"/>
       {else}
         {$field->name}: {eval var=$field->value}
       {/if}
   
 {/foreach}
{/if}


{/foreach}
Last edited by Peciura on Tue Nov 23, 2010 9:05 am, edited 1 time in total.
brentnl
Power Poster
Power Poster
Posts: 493
Joined: Mon May 11, 2009 4:35 pm

Re: HOWTO: Proper news pagination (with page numbers!)

Post by brentnl »

Peciura wrote:

Code: Select all

* Create array of pagination links
*
* @params	string	$params['link']		Mandatory. Href or complete link (href will be extracted).
* @params	string	$params['current']	Mandatory. Current page number
* @params	string	$params['max']		Mandatory. Max page number
* @params	string	$params['param']	Mandatory. Unique part of url param. e.g. 'pagenumber'
* @params	string	$params['assign']	Mandatory. Name of variable to assign result array($page_number=>'http://www... ', ...)
* @params	string	$params['pattern']	Pagination pattern default '10,10'.
* @params	string	$params['extreme']	Include first and last links
*
*/

$default_pattern = '10,10';

if (!empty($params['link'])		&&
	!empty($params['current'])	&&
	!empty($params['max'])		&&
	!empty($params['param'])	&&
	!empty($params['assign'])){

	$link = preg_replace("/.*href=["\' ]*([^"\']*).*/", '$1', $params['link']);
	$link = html_entity_decode(trim(strip_tags($link)));	//extract href
	$param = trim($params['param']);
	$assign = trim($params['assign']);
	$max = intval($params['max']);
	$current = intval($params['current']);
	$params['pattern'] = (empty($params['pattern']))? $default_pattern : $params['pattern'];
	$pattern = explode(',', trim($params['pattern']));
	$extreme = (empty($params['extreme']))? FALSE : TRUE;

	if(strpos($link, $param.'=')){
		$gCms = cmsms(); [color=grey]//global $gCms;[/color]
		$smarty = $gCms->GetSmarty();
		$links = array();

		$i_min = $i_max = $current;
		foreach($pattern as $exp=>$count){
			for($i = 1; $i  ($delta + 1)){
					$i_min -= $delta;
					$links[$i_min] = htmlentities(preg_replace( "/$param=\d+/", $param.'='.$i_min, $link));
				}
				if($i_max assign($assign, $links);
	}
}
When I try to add the UDT code mentioned above I get an error like this:

Code: Select all

Warning: Unexpected character in input: '\' (ASCII=92) state=1 in /www/p/a/r/domain.nl/public_html/inloggen/edituserplugin.php(108) : eval()'d code on line 9 Parse error: syntax error, unexpected T_CONSTANT_ENCAPSED_STRING in /www/p/a/r/domain.nl/public_html/inloggen/edituserplugin.php(108) : eval()'d code on line 9 
How can I fix this?
jjkowall
New Member
New Member
Posts: 4
Joined: Tue Feb 14, 2012 4:00 pm

Re: HOWTO: Proper news pagination (with page numbers!)

Post by jjkowall »

Hi!

I have another, probably stupid, problem. The same as brentnl. When I try add UDT {pagination} it display error.

I would like have pagination like (with each number is link):
« 1 2 3 4 5 »
instead standard:
<< < Page 2 of 5 > >>
In my website will be only few pages, max 10. I search solution, but any of it dosen't work. I found on German forum: http://forum.cmsmadesimple.de/viewtopic.php?pid=15762, but it's display:
« 0 1 2 3 4 »
0 is inactive, and don't show last page (5).


I have CMSMS 1.10.3 with News Module 2.12.3.

Regards!
Peciura

Re: HOWTO: Proper news pagination (with page numbers!)

Post by Peciura »

Updated pagination UDT that was broken after forum was moved.
swarfega
Forum Members
Forum Members
Posts: 174
Joined: Mon Sep 06, 2010 10:51 am

Re: HOWTO: Proper news pagination (with page numbers!)

Post by swarfega »

Peciura wrote:OK, here is modified News summary default template (CMSms 1.8.1, News 2.10.6).
Old pagination is green, new - brown. You can also combine both paginations to one.

Here are parameters used by UDT {pagination}:

link - pagination link or link location. For News pagination it can be  {$firstpage}, {$prevpage}, {$nextpage}, {$lastpage}. It is important that this value is not empty.

param - url param name that stores page number. It is not necessary to write complete name but it should be unique in all url (link location) at least. For New module it can be 'pagenumber' it also could look like this 'cntntpagenumber' or even 'md417apagenumber' and so on.

assign - variable name you want to store pagination links in. In example it is 'temp' so variable {$temp} contains all pagination links. It is an array with urls as array members and page numbers as keys. Member with empty key ('') is url to current page.

pattern - it defines how many and what preceding and subsequent pages are in pagination. I you write '5', there will be  five preceding pages, current page and 5 subsequent pages (e.g. '43 44 45 46 47 48 49 50 51 52 53' ). If you write '5,2', there will be added 2 pages from both sides but they will differ by 10 from each other (e.g. '23 33' and  '63 73'). Every number in pattern increases pagination step 10 times for number of pages it carries, it works for both sides of a pagination. I have colored pattern and resulting pagination on previous example.

extreme - default is empty string. If parameter is not empty it will force the first and the last pages in pagination, in other word pagination will always have link '1' (to the first page) and 'X', where X is the very last page.
{* This section shows a clickable list of your News categories. *}

{foreach from=$cats item=node}
{if $node.depth > $node.prevdepth}
{repeat string="" times=$node.depth-$node.prevdepth}
{elseif $node.depth " times=$node.prevdepth-$node.depth}

{elseif $node.index > 0}
{/if}

{if $node.count > 0}
{$node.news_category_name}{else}{$node.news_category_name} {/if}
{/foreach}
{repeat string="" times=$node.depth-1}


{* this displays the category name if you're browsing by category *}
{if $category_name}
{$category_name}
{/if}

{* if you don't want category browsing on your summary page, remove this line and everything above it *}

{if $pagecount > 1}
 
{if $pagenumber > 1}
{$firstpage} {$prevpage} 
{/if}
{$pagetext} {$pagenumber} {$oftext} {$pagecount}
{if $pagenumber
{/if}


{if isset($pagecount) && $pagecount > 1}
  {if $pagenumber>1}
     {assign var='tmp_link' value=$prevpage}
  {else}
     {assign var='tmp_link' value=$nextpage}
  {/if}

  {pagination link=$tmp_link param='pagenumber' max=$pagecount  current=$pagenumber assign='temp' pattern='9' extreme='true'}

 
     {foreach from=$temp key='page_nb' item='tmp'}
        {if !empty($tmp)}
           {$page_nb}
        {else}
           {$pagenumber}
        {/if}
        {' '};
     {/foreach}
 
{/if}


{foreach from=$items item=entry}


{if $entry->postdate}

{$entry->postdate|cms_date_format}

{/if}


moreurl}" title="{$entry->title|cms_escape:htmlall}">{$entry->title|cms_escape}



{$category_label} {$entry->category}


{if $entry->author}

{$author_label} {$entry->author}

{/if}

{if $entry->summary}

{eval var=$entry->summary}



[{$entry->morelink}]


{else if $entry->content}


{eval var=$entry->content}

{/if}

{if isset($entry->extra)}
   
       {eval var=$entry->extra}
{* {cms_module module='Uploads' mode='simpleurl' upload_id=$entry->extravalue} *}
   
{/if}
{if isset($entry->fields)}
 {foreach from=$entry->fields item='field'}
   
       {if $field->type == 'file'}
         file_location}/{$field->value}"/>
       {else}
         {$field->name}: {eval var=$field->value}
       {/if}
   
 {/foreach}
{/if}


{/foreach}
I tried to enter this udt but the system reported it was invalid.
Locked

Return to “Tips and Tricks”