Page 1 of 3

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

Posted: Tue Feb 20, 2007 12:00 pm
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) ...

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

Posted: Tue Feb 20, 2007 4:26 pm
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

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

Posted: Thu Feb 22, 2007 2:19 am
by brdon
Do you have a site where I can see it in action?  Great work!

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

Posted: Fri Feb 23, 2007 4:56 am
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}

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

Posted: Sat Mar 31, 2007 3:34 pm
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...

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

Posted: Sun Apr 08, 2007 6:27 am
by Vin

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

Posted: Wed Jun 06, 2007 3:47 am
by taufikp
Thanks Daniel15 and Vin! Very useful code!  ;D

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

Posted: Wed Jun 06, 2007 10:39 am
by cyberman
From Blog
- News enhancements
- Frontend Pagination for summary articles

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

Posted: Thu Jul 05, 2007 3:51 pm
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.

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

Posted: Thu Aug 26, 2010 7:11 pm
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.

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

Posted: Wed Sep 29, 2010 8:45 am
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}

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

Posted: Wed Apr 13, 2011 3:14 pm
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?

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

Posted: Mon Feb 20, 2012 11:48 am
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!

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

Posted: Tue Mar 13, 2012 11:17 am
by Peciura
Updated pagination UDT that was broken after forum was moved.

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

Posted: Thu Aug 23, 2012 8:38 am
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.