Go Back   vb.org Archive > vBulletin Article Depository > Read An Article > vBulletin 4 Articles
FAQ Community Calendar Today's Posts Search

Reply
 
Thread Tools
[HOW TO - vB4] Paginating Results
cellarius's Avatar
cellarius
Join Date: Aug 2005
Posts: 1,987

 

Show Printable Version Email this Page Subscription
cellarius cellarius is offline 08-23-2009, 10:00 PM

Introduction

Not very much has changed regarding how pagination works since vB 3.8, but quite enough to warrant an update of Revan's great tutorial, dating from 2006. Kudos to Revan.

As Revan I assume you know your way around php and can understand at least roughfly what each bit of the code does. There'll be explanations, of course, but this is for coders and mod developers.

The main work for pagination has to be done in the PHP-code, still no surprise there.

Cleaning URL parameters

We start off by cleaning the URL parameters that will tell our paginator how many entries to show per page and on which page of the resultset we're actually on

PHP Code:
 $vbulletin->input->clean_array_gpc('r', array(
    
'perpage'    => TYPE_UINT,
    
'pagenumber' => TYPE_UINT,
)); 
.
Counting results

The next step is to count the number of resuts that our actual database query will return (this query we will meet later on - it's an example that will throw all users with no posts).

PHP Code:
$cel_users $db->query_first("
    SELECT COUNT('userid') AS users_count
    FROM " 
TABLE_PREFIX "user AS user
    WHERE user.posts = '0'
"
); 
.
Settings & sanitizing

Next we're off to do some settings: The first argument is our counting result. The last two arguments are the maximum number of results per page (100) and the default number of results per page (20). Note how the first argument is the result of the count query above. You can replace those with settings from the AdminCP by inserting the corresponding variables obviously.

PHP Code:
sanitize_pageresults($cel_users['users_count'], $pagenumber$perpage10020); 
.
Orientation - where are we?

Now some stuff to determine on which page we're on and which results to show. Note how you have to provide the results of our initial count query:

PHP Code:
if ($vbulletin->GPC['pagenumber'] < 1)
{
    
$vbulletin->GPC['pagenumber'] = 1;
}
else if (
$vbulletin->GPC['pagenumber'] > ceil(($cel_users['users_count'] + 1) / $perpage))
{
    
$vbulletin->GPC['pagenumber'] = ceil(($cel_users['users_count'] + 1) / $perpage);
}
$limitlower = ($vbulletin->GPC['pagenumber'] - 1) * $perpage;
$limitupper = ($vbulletin->GPC['pagenumber']) * $perpage
.
The main query

Now the query that throws all users with no posts - just an example, obviously. Note the LIMIT - this has to be added to the original query to delimit the resultset for the actual page

PHP Code:
$result $db->query_read("
    SELECT user.username, user.userid
    FROM " 
TABLE_PREFIX "user as user
    WHERE user.posts = '0'
    ORDER BY username DESC
    LIMIT 
$limitlower$perpage
"
); 
.
Constructing pagenav

The last (but one) thing to do in the PHP code is to finally call the function to construct the actual page-nav and saving it's output to a variable for passing to the template.
  • Some explanation for the arguments that must/can be passed to this function are in the code.
  • Of course, the name of the file (yourfile.php) needs to be adapted to the file name your using the pagination on.
  • Only the first four arguments are mandatory. You can leave the rest away if not needed, I added them for documentation.
  • The ? that starts the parameters after myfile.php needs to be there, since atm the page parameter always is prefixed with an &. If there are no other parameters present as is the case in this example, the links will look like "yourfile.php?&page=2". This is, of course, wrong, but works; without the ? the link would be "yourfile.php&page=2", which is even more wrong, since it does not work. In vB 3 pagination handled this correctly. I filed this as a bug in vB4 beta 3. Maybe I'm missing something, or this will be resolved - I'll keep you posted.
PHP Code:
$pagenav construct_page_nav(
    
$vbulletin->GPC['pagenumber'],
    
$perpage,
    
$cel_users['users_count'],
    
'yourfile.php?' $vbulletin->session->vars['sessionurl'], // the pagenav-link
    
''// to pass a second portion or the pagenav-link, gets directly appended to above
    
''// to pass an anchor
    
''// SEO-Link for thread, forum, member... pages - make the pagenav-links seo'ed if you use the paginator on one of those
    
''// Array to pass linkinfo for SEO-Link-Method
    
''  // Array to pass additional Info for SEO-Link-Method
); 
.
Registering pagenav for templates

As with all variables in vB4, the newly created $pagenav has to be registered to be used inside the template:

PHP Code:
$templater vB_Template::create('cel_test_pagination');
    
$templater->register_page_templates();
    
$templater->register('navbar'$navbar);
// Need to add for pagenav
    
$templater->register('pagenav'$pagenav);
    
$templater->register('pagenumber'$pagenumber);
    
$templater->register('perpage'$perpage);
    
$templater->register('output'$output);
print_output($templater->render()); 
.
Template code

Now you just have to put the pagenav-code into your template, and we're done. Note that the id of the surrounding div should be changed to "pagination_bottom" or "pagination_top" accordingly.

Code:
<vb:if condition="$pagenav">
     <div id="pagination_top">
          {vb:raw pagenav}
     </div>
</vb:if>
Have fun!


-c
As of now (beta 3), there are still some issues that need to be resolved regarding pagination. They are minor and there should not be substantial changes, but be aware of that. For example, the setting of results shown per page does not work yet - 20 is hardcoded into the sanitizing function.
Reply With Quote
  #12  
Old 01-04-2010, 11:48 PM
S1OPP S1OPP is offline
 
Join Date: Jun 2005
Posts: 25
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

I would really appreciate it if somebody could help me out.

I've built a page that pulls row from a sql db. Now I need to paginate the page as there are too many rows for one page.

I've followed the instructions as far as I can, changing only a few things, such as the sql queries.

The php is now limiting the number of rows to the correct perpage number. I've added the pagenav code to my custom template, but no matter what I do, the pagenav doesn't show.

Any help would be greatly appreciated.
S1OPP
Reply With Quote
  #13  
Old 01-05-2010, 05:07 AM
BBR-APBT's Avatar
BBR-APBT BBR-APBT is offline
 
Join Date: Feb 2009
Location: Maryland
Posts: 946
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Quote:
Originally Posted by S1OPP View Post
I would really appreciate it if somebody could help me out.

I've built a page that pulls row from a sql db. Now I need to paginate the page as there are too many rows for one page.

I've followed the instructions as far as I can, changing only a few things, such as the sql queries.

The php is now limiting the number of rows to the correct perpage number. I've added the pagenav code to my custom template, but no matter what I do, the pagenav doesn't show.


Any help would be greatly appreciated.
S1OPP
First off it would be good to post code when asking for help. If we can't see it and all your saying is it don't work, it makes it very hard to help you. There could be a million reasons why it isn't working for you. I used this tutorial several times and it works every time like a charm.
Reply With Quote
  #14  
Old 01-05-2010, 05:25 AM
cellarius's Avatar
cellarius cellarius is offline
 
Join Date: Aug 2005
Posts: 1,987
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

^^What he said

Quote:
Originally Posted by BBR-APBT View Post
I used this tutorial several times and it works every time like a charm.
Good to know
Reply With Quote
  #15  
Old 01-05-2010, 06:24 AM
S1OPP S1OPP is offline
 
Join Date: Jun 2005
Posts: 25
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

no problem.

sightings.php
PHP Code:
<?php

// ####################### SET PHP ENVIRONMENT ###########################
error_reporting(E_ALL & ~E_NOTICE);

// #################### DEFINE IMPORTANT CONSTANTS #######################

define('THIS_SCRIPT''sightings');
define('CSRF_PROTECTION'true);  
// change this depending on your filename

// ################### PRE-CACHE TEMPLATES AND DATA ######################
// get special phrase groups
$phrasegroups = array();

// get special data templates from the datastore
$specialtemplates = array();

// pre-cache templates used by all actions
$globaltemplates = array('custom_sightings',
);

// pre-cache templates used by specific actions
$actiontemplates = array();

// ######################### REQUIRE BACK-END ############################
// if your page is outside of your normal vb forums directory, you should change directories by uncommenting the next line
// chdir ('/path/to/your/forums');
require_once('./global.php');

// #######################################################################
// ######################## START MAIN SCRIPT ############################
// #######################################################################

$navbits construct_navbits(array('' => 'Sightings'));
$navbar render_navbar_template($navbits);

// ###### YOUR CUSTOM CODE GOES HERE #####
$pagetitle 'Sightings';

$link mysql_connect("xxxxxxxxxxxxx""xxxxxxx""xxxxxxx") or die("Impossible to connect :" mysql_error());



$row_usersightings = array ();

$vbulletin->input->clean_array_gpc('r', array(
    
'perpage'    => TYPE_UINT,
    
'pagenumber' => TYPE_UINT,
));  


mysql_select_db("mothstats") or die(mysql_error());


$cel_users mysql_query("
    SELECT COUNT('id') AS row_count
    FROM sightings
"
);  

sanitize_pageresults($cel_users['row_count'], $pagenumber$perpage10020);  

if (
$vbulletin->GPC['pagenumber'] < 1)
{
     
$vbulletin->GPC['pagenumber'] = 1;
}
else if (
$vbulletin->GPC['pagenumber'] > ceil(($cel_users['row_count'] + 1) / $perpage))
{
    
$vbulletin->GPC['pagenumber'] = ceil(($cel_users['row_count'] + 1) / $perpage);
}
$limitlower = ($vbulletin->GPC['pagenumber'] - 1) * $perpage;
$limitupper = ($vbulletin->GPC['pagenumber']) * $perpage;  


$usersightings mysql_query("SELECT * FROM sightings
                 ORDER BY id DESC
                LIMIT 
$limitlower$perpage");

while (
$row mysql_fetch_assoc($usersightings))
{
    
$row_usersightings[] = $row;
}

$pagenav construct_page_nav(
    
$vbulletin->GPC['pagenumber'],
    
$perpage,
    
$cel_users['row_count'],
    
'sightings.php?' $vbulletin->session->vars['sessionurl'// the pagenav-link
);  


// ###### NOW YOUR TEMPLATE IS BEING RENDERED ######
vB_Template::preRegister('custom_sightings',array('row_usersightings' => $row_usersightings));
$templater vB_Template::create('custom_sightings');
$templater->register_page_templates();
$templater->register('navbar'$navbar);
$templater->register('pagetitle'$pagetitle);
$templater->register('row_usersightings'$row_usersightings);
$templater->register('pagenav'$pagenav);
$templater->register('pagenumber'$pagenumber);
$templater->register('perpage'$perpage);
$templater->register('output'$output);
print_output($templater->render());


?>
Templats : custom_sightings
PHP Code:
{vb:stylevar htmldoctype}
<
html xmlns="http://www.w3.org/1999/xhtml" dir="{vb:stylevar textdirection}" lang="{vb:stylevar languagecode}" id="vbulletin_html">
  <
head>
    <
title>{vb:raw vboptions.bbtitle}</title>
    {
vb:raw headinclude}
  </
head>
  <
body>
    
    {
vb:raw header}
    
    {
vb:raw navbar}
 
<
vb:if condition="$pagenav">
     <
div id="pagination_top">
          {
vb:raw pagenav
     </
div>
</
vb:if> 
    
    <
div id="pagetitle">
      <
h1>{vb:raw pagetitle}</h1>
    </
div>
    
    <
h2 class="blockhead">Title</h2>
    <
div class="blockbody">
      <
div class="blockrow">
        <
div id="container">
<
div style="padding-left: 10px; padding-top:5px;">
  <
a href="sightingssubmit.php"><strong>Submit a sighting </strong></a> | <a href="sightings.php"><strong>Show all sightings   </strong></a>
        </
div>
<
br />
<
table width="95%" border="0" align="center" bgcolor="#FCFCFC">
<
tr>
               <
td bgcolor="#848E7B"><div align="left" class="style1">No.</div></td>
      <
td bgcolor="#848E7B"><div align="left" class="style1">Species</div></td>
      <
td bgcolor="#848E7B"><div align="left" class="style1">Date</div></td>
      <
td bgcolor="#848E7B"><div align="left" class="style1">Location</div></td>
      <
td bgcolor="#848E7B"><div align="left" class="style1">Recorder</div></td>
      <
td bgcolor="#848E7B"><div align="left" class="style1">Details</div></td>
    </
tr>
             
               <
vb:each from="row_usersightings" key="rowid" value="rowinfo">
               <
tr>
                 <
td width="30" valign="top" bgcolor="#FFFff4"><div align="left" class="style131 "> {vb:var rowinfo.id} </div></td>
                 <
td width="150" valign="top" bgcolor="#FFFff4"><div align="left" class="style131"> {vb:var rowinfo.species}</div></td>
                 <
td width="50" valign="top" bgcolor="#FFFff4"><div align="left" class="style131"> {vb:var rowinfo.date}</div></td>
                 <
td width="120" valign="top" bgcolor="#FFFff4"><div align="left" class="style131"> {vb:var rowinfo.location}</div></td>
                 <
td width="100" valign="top" bgcolor="#FFFff4"><div align="left" class="style131"> {vb:var rowinfo.recorder}</div></td>
                 <
td width="350" valign="top" bgcolor="#FFFff4"><div align="left" class="style131"> {vb:var rowinfo.details}</div></td>
               </
tr>
               </
vb:each>
           
</
table>

</
div>

      </
div>
    </
div>  
    {
vb:raw footer}
  </
body>
</
html
Reply With Quote
  #16  
Old 01-06-2010, 08:07 PM
S1OPP S1OPP is offline
 
Join Date: Jun 2005
Posts: 25
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Worked it out now,

thanks.
Reply With Quote
  #17  
Old 01-07-2010, 03:15 AM
cellarius's Avatar
cellarius cellarius is offline
 
Join Date: Aug 2005
Posts: 1,987
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Sorry, didn't come around to look at your code - but you working it out yourself is much better anyway
Reply With Quote
  #18  
Old 01-22-2010, 06:19 AM
MrNase MrNase is offline
 
Join Date: May 2003
Location: Germany
Posts: 670
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Dont forget to use the &amp; like this when passing additional attributes.

PHP Code:
'do=category&amp;id='.$vbulletin->GPC['id'

This one seems to work at first but it does not when using the page number input:
PHP Code:
'do=category&id='.$vbulletin->GPC['id'
Reply With Quote
  #19  
Old 04-11-2010, 01:15 AM
Jaxel Jaxel is offline
 
Join Date: Sep 2005
Posts: 1,160
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

As of VB 4.0.3, I now have errors with page pagination on custom mods...

Example: http://test.8wayrun.com/media/c9-kogarasumaru

With VB 4.0.2, it looked fine, but now the last 3 elements are shifted.
Reply With Quote
  #20  
Old 04-21-2010, 03:33 PM
Jaxel Jaxel is offline
 
Join Date: Sep 2005
Posts: 1,160
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Only happens in Chrome... only with vb4.0.3



This is code...
Code:
<vb:if condition="$pagenav">
	<div id="pagination_top" style="float: right;">
		{vb:raw pagenav}
	</div><br /><br />
</vb:if>
Reply With Quote
  #21  
Old 07-22-2011, 01:11 AM
EquinoxWorld EquinoxWorld is offline
 
Join Date: Nov 2009
Location: Naples
Posts: 354
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
Default

Just wanted to say thank you for this article on pagination, I was finally able to understand it thanks to your post. Here is my example for those who are still trying to understand maybe this helps.

PHP Code:
<?php 
require_once('./global.php');

     
$vbulletin->input->clean_array_gpc('r', array(
    
'perpage'    => TYPE_UINT,
    
'pagenumber' => TYPE_UINT,
));

$cel_users $db->query_first("
    SELECT COUNT('edition') AS users_count
    FROM oftw_hall_of_fame 
"
);

sanitize_pageresults($cel_users['users_count'], $pagenumber$perpage505);

if (
$vbulletin->GPC['pagenumber'] < 1)
{
    
$vbulletin->GPC['pagenumber'] = 1;
}
else if (
$vbulletin->GPC['pagenumber'] > ceil(($cel_users['users_count'] + 1) / $perpage))
{
    
$vbulletin->GPC['pagenumber'] = ceil(($cel_users['users_count'] + 1) / $perpage);
}
$limitlower = ($vbulletin->GPC['pagenumber'] - 1) * $perpage;
$limitupper = ($vbulletin->GPC['pagenumber']) * $perpage

$pagenav construct_page_nav(
    
$vbulletin->GPC['pagenumber'],
    
$perpage,
    
$cel_users['users_count'],
    
'oftw_hall_of_fame.php?' $vbulletin->session->vars['sessionurl'], // the pagenav-link
    
''// to pass a second portion or the pagenav-link, gets directly appended to above
    
''// to pass an anchor
    
''// SEO-Link for thread, forum, member... pages - make the pagenav-links seo'ed if you use the paginator on one of those
    
''// Array to pass linkinfo for SEO-Link-Method
    
''  // Array to pass additional Info for SEO-Link-Method
);

$result $db->query_read("SELECT * FROM oftw_hall_of_fame LIMIT $limitlower$perpage");

if (
mysql_num_rows($result) > 0) { 
    
// yes 
    // print them one after another 
    
echo "<center><table>"
    while(
$row mysql_fetch_row($result)) { 
        echo 
"<tr>"
        echo 
"<td><center><u style=color:#417394;font-size:20px;><b style=color:#417394;>Signature Of The Week Edition #&nbsp;".$row[7]."&nbsp;</b></u></center>";
        echo 
"<center>Won With&nbsp;".$row[2]."&nbsp;Votes</center>";
        echo 
"<center>Nominated&nbsp;By:&nbsp;<b style=color:#3B81B7;><a href=http://development.aniworlds.net/member.php?".$row[6]."-".$row[4].">".$row[4]."&nbsp;</a></b></center>";
        echo 
"<center>Added:&nbsp;".date("F j, Y g:i a"strtotime($row[3]))."</center>";
        echo 
"<center>Created By:&nbsp;".$row[5]."</center></td>";
        echo 
"<td><center><img src =".$row[1]." style=padding-bottom:5px></center></td>";
        echo 
"</tr>"
    } 
    echo 
"</table></center>"

else { 
    
// no 
    // print status message 
    
echo "No Contests Have Been Started."



?>
This php file was then included as a variable (vb:raw) into a template of my choosing (pagination included!).
Reply With Quote
Благодарность от:
cellarius
Reply


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT. The time now is 09:19 AM.


Powered by vBulletin® Version 3.8.12 by vBS
Copyright ©2000 - 2024, vBulletin Solutions Inc.
X vBulletin 3.8.12 by vBS Debug Information
  • Page Generation 0.04837 seconds
  • Memory Usage 2,456KB
  • Queries Executed 25 (?)
More Information
Template Usage:
  • (1)SHOWTHREAD
  • (1)ad_footer_end
  • (1)ad_footer_start
  • (1)ad_header_end
  • (1)ad_header_logo
  • (1)ad_navbar_below
  • (1)ad_showthread_beforeqr
  • (2)bbcode_code
  • (12)bbcode_php
  • (2)bbcode_quote
  • (1)footer
  • (1)forumjump
  • (1)forumrules
  • (1)gobutton
  • (1)header
  • (1)headinclude
  • (1)modsystem_article
  • (1)navbar
  • (4)navbar_link
  • (120)option
  • (1)pagenav
  • (1)pagenav_curpage
  • (3)pagenav_pagelink
  • (11)post_thanks_box
  • (4)post_thanks_box_bit
  • (11)post_thanks_button
  • (1)post_thanks_javascript
  • (1)post_thanks_navbar_search
  • (2)post_thanks_postbit
  • (11)post_thanks_postbit_info
  • (10)postbit
  • (11)postbit_onlinestatus
  • (11)postbit_wrapper
  • (1)spacer_close
  • (1)spacer_open
  • (1)tagbit_wrapper 

Phrase Groups Available:
  • global
  • inlinemod
  • postbit
  • posting
  • reputationlevel
  • showthread
Included Files:
  • ./showthread.php
  • ./global.php
  • ./includes/init.php
  • ./includes/class_core.php
  • ./includes/config.php
  • ./includes/functions.php
  • ./includes/class_hook.php
  • ./includes/modsystem_functions.php
  • ./includes/functions_bigthree.php
  • ./includes/class_postbit.php
  • ./includes/class_bbcode.php
  • ./includes/functions_reputation.php
  • ./includes/functions_post_thanks.php 

Hooks Called:
  • init_startup
  • init_startup_session_setup_start
  • init_startup_session_setup_complete
  • cache_permissions
  • fetch_threadinfo_query
  • fetch_threadinfo
  • fetch_foruminfo
  • style_fetch
  • cache_templates
  • global_start
  • parse_templates
  • global_setup_complete
  • showthread_start
  • showthread_getinfo
  • forumjump
  • showthread_post_start
  • showthread_query_postids
  • showthread_query
  • bbcode_fetch_tags
  • bbcode_create
  • showthread_postbit_create
  • postbit_factory
  • postbit_display_start
  • post_thanks_function_post_thanks_off_start
  • post_thanks_function_post_thanks_off_end
  • post_thanks_function_fetch_thanks_start
  • fetch_musername
  • post_thanks_function_fetch_thanks_end
  • post_thanks_function_thanked_already_start
  • post_thanks_function_thanked_already_end
  • post_thanks_function_fetch_thanks_bit_start
  • post_thanks_function_show_thanks_date_start
  • post_thanks_function_show_thanks_date_end
  • post_thanks_function_fetch_thanks_bit_end
  • post_thanks_function_fetch_post_thanks_template_start
  • post_thanks_function_fetch_post_thanks_template_end
  • postbit_imicons
  • bbcode_parse_start
  • bbcode_parse_complete_precache
  • bbcode_parse_complete
  • postbit_display_complete
  • post_thanks_function_can_thank_this_post_start
  • pagenav_page
  • pagenav_complete
  • tag_fetchbit_complete
  • forumrules
  • navbits
  • navbits_complete
  • showthread_complete