Smarty Forum Index Smarty
WARNING: All discussion is moving to https://reddit.com/r/smarty, please go there! This forum will be closing soon.

How to paginate {section/}
Goto page 1, 2  Next
 
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks
View previous topic :: View next topic  
Author Message
mphare
Smarty n00b


Joined: 18 May 2003
Posts: 1

PostPosted: Tue May 20, 2003 9:13 pm    Post subject: How to paginate {section/} Reply with quote

Hi,
I've looked at {section} and see good things like 'start' and 'max' parameters. Seems like it should be possible to limit {section} to display, say 30 things, then have a button or link to get the next or previous 30 things.

But I don't see how to do it. Smarty is a bit of black-magic to me as I have only been using it for about 6 hours now.

Anyone have a cool tip or trick to do pagination with {selection} loops?

Thanks,

Mike
Back to top
View user's profile Send private message
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Tue May 20, 2003 9:26 pm    Post subject: Reply with quote

Hmmm. Pagination usually entails that you want to show just a portion of the available data. That means that prior to calling Smarty, you have already sliced your data into its spoon sized bites. If at all possible, this means that you only queried your back-end for as much data as you are going to show.

The key is not to get Smarty to paginate for you, but instead, to get your PHP application to only send the paginated result set to Smarty. Otherwise you are wasting a lot of bandwidth and processor cycles (and processor IO) just to throw a bunch of results away. For even moderately sized data sets that is untenable.
Back to top
View user's profile Send private message
kasper
Smarty n00b


Joined: 24 Apr 2003
Posts: 4

PostPosted: Tue May 27, 2003 8:44 pm    Post subject: Reply with quote

Hey,

I understand what to do with PHP and what to do with Smarty but i still have a question about pagination.
I have to display a table of, say, 32 items. The table must have 4 columns, one item per column. The resulting table is 4 columns & 8 rows.
Is there an elegant way to do this with the {section} or {foreach} tag ?
I'm thinking using template variables and do some little coding here. But i feel it not to be really smart.

Any piece of advice would be appreciated.

-----------
EDIT : i think i found what i need :
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=217
Back to top
View user's profile Send private message
Justin
Smarty Regular


Joined: 07 May 2003
Posts: 38
Location: Vilnius, Lithuania

PostPosted: Wed May 28, 2003 5:03 am    Post subject: Reply with quote

kasper wrote:
Hey,

I understand what to do with PHP and what to do with Smarty but i still have a question about pagination.
I have to display a table of, say, 32 items. The table must have 4 columns, one item per column. The resulting table is 4 columns & 8 rows.
Is there an elegant way to do this with the {section} or {foreach} tag ?
I'm thinking using template variables and do some little coding here. But i feel it not to be really smart.

Any piece of advice would be appreciated.

-----------
EDIT : i think i found what i need :
http://www.phpinsider.com/smarty-forum/viewtopic.php?t=217


also look at http://www.mapledesign.co.uk/coding/smarty_table.php, maybe it would help
_________________
http://www.baubas.net
Back to top
View user's profile Send private message Visit poster's website
sitemod
Smarty n00b


Joined: 29 May 2003
Posts: 1
Location: Buffalo, NY

PostPosted: Thu May 29, 2003 1:05 pm    Post subject: Reply with quote

Why would you want to paginate with smarty? That's not what's smarty if for!

You supply the elements to the smarty section tag, therefor you paginate them before displaying them with smarty!
_________________
Eric Coleman - ZaireWeb Solutions / Netsighting Digital Solutions
http://www.netsighting.com
eric.coleman@sitemod.net
Back to top
View user's profile Send private message Send e-mail Visit poster's website AIM Address MSN Messenger
kasper
Smarty n00b


Joined: 24 Apr 2003
Posts: 4

PostPosted: Wed Jun 11, 2003 7:34 am    Post subject: Reply with quote

Justin wrote:
also look at http://www.mapledesign.co.uk/coding/smarty_table.php, maybe it would help
cannot use that, my hosting does not have PEAR (i know i know Wink).

sitemod wrote:
Why would you want to paginate with smarty? That's not what's smarty if for!

You supply the elements to the smarty section tag, therefor you paginate them before displaying them with smarty!
don't know if i understood what you were thinking about exactly
Back to top
View user's profile Send private message
kasper
Smarty n00b


Joined: 24 Apr 2003
Posts: 4

PostPosted: Wed Jun 11, 2003 7:57 am    Post subject: Reply with quote

ok, assigning array of arrays with the wanted layout for tables works well
that's smart enough for me
Back to top
View user's profile Send private message
excelsior
Smarty n00b


Joined: 16 Jul 2003
Posts: 1

PostPosted: Wed Jul 16, 2003 6:46 pm    Post subject: Reply with quote

For me too Wink
Back to top
View user's profile Send private message Visit poster's website
cablehead
Smarty Rookie


Joined: 09 Jul 2003
Posts: 23

PostPosted: Mon Sep 22, 2003 3:02 am    Post subject: Reply with quote

Sorting and paging really fall into logical grey areas.

The client requests a bunch of stuff. The order and the chomp sizes of the bunch of stuff is just there to make the bunch of stuff more presentable to the client. The only reason I can see for not doing it in the template is the logic starts to get a bit hairy and as boots pointed out - performance.

I'm been thinking of creating the following smarty paging function:

Code:

{assign var=arrPager
  value={createPager data=$arrUsers|@sortby:strLastName,strFirstName
                     currPage=$intCurrPage
                     pageSize=20}}

<table>
<tr>
<td>Name</td>
<td>Gender</td>
<td>Age</td>
</tr>

{foreach from=$arrPager.arrCurrPageItems item=$arrUser}
<tr>
<td>{$arrUser.strLastName}, {$arrUser.strFirstName}</td>
<td>{$arrUser.ysnMale|asEither:male:female}</td>
<td>{$arrUser.intAge}</td>
</tr>
{/foreach}
</table>

<table>
<tr>
<td>
  {if $arrPager.ysnAtFirstPage}
    nbsp;
  {else}
    <a href=fred.php?intCurrPage={$arrPager.intPrevPage}>Prev Page</a>
  {/if}
</td>

<td>
  Page {$arrPager.intCurrPage} of {$arrPager.intNumPages}
</td>

<td>
  {if $arrPager.ysnAtLastPage}
    nbsp;
  {else}
    <a href=fred.php?intCurrPage={$arrPager.intNextPage}>Next Page</a>
  {/if}
</td>
</tr>
</table>


What do people think? Any feedback is greatly appreciated. Is assign able to do:

Code:

{assign var=arrPager
  value={createPager data=$arrUsers|@sortby:strLastName,strFirstName
                     currPage=$intCurrPage
                     pageSize=20}}


??

Andy.
Back to top
View user's profile Send private message Send e-mail
boots
Administrator


Joined: 16 Apr 2003
Posts: 5611
Location: Toronto, Canada

PostPosted: Mon Sep 22, 2003 3:51 am    Post subject: Reply with quote

Hi cablehead. Your pager looks like it doesn't get around the performance issue. Smile

Smarty uses a sort of data "push" metaphor where the application assigned results (the "push") are supposed to be the results that are intended for the template (and no more). The tempation is to see the template as the focal point for the application logic -- "this template should show a page of information at a time, therefore I will simply split the incoming data into 'pages' within the template". I suggest not following this type of thinking too much. It means your application retrieves too much data, you copy too much data into the template (remember PHP4 assigns via copy) and then you have to process and slice that data within the template. All this simply because the logic to recognize and deal with the pagination is at the wrong layer. If your application code was made to understand the requirements, it could send a query to the db such that only exactly the rows required are returned (perhaps even in the proper sort order). I'll bet real money that the database manager is better at sorting and splitting data than PHP code, let alone Smarty code.

For those bent on doing this in-template, this is one of those situations where it might be better to assign_by_ref an object instead of an array where the object has a method to retrieve the required rows/subset from the object. This brings up another approach, (I'll call it the "pull" methodology) that you can use with Smarty, though it requires custom plugins or at least custom objects. Here your template requests data from your application objects/custom plugins. In this case, your don't assign base data to the templates but instead assign control parameters which the template uses to call custom functions which return data structures to be used by the template. Alternatively, you can assign interface objects that contain methods to return data as I mentioned earlier. I'm not advocating this method over the standard "push" type approach nor am I trying to indicate it is "better" or "worse" necessarily--it is simply another approach which can be useful in some regards. [EDIT: there is yet another approach using php_include, but I won't even begin to advocate that approach Smile]

Personally, I favour the "push" style because I don't think Smarty does enough (on its own) to treat templates as components which I think the "pull" method attempts to characterize. In other words, I think you need to build a decent framework around Smarty and your application to justify the "pull" methodology. [ASIDE: I also think there is a slight disconnect in Smarty which you can see at these "boundary" cases. We do want designers to say how much data should be viewable for a given section but we want this "late" decision to be factored into the "early" code that actually generates the data sets. There is no great, uniform way of dealing with this in Smarty that I am aware of.]

Since you patiently read my ramblings, I will finally answer your question regarding syntax: the syntax you show does not work because you are trying to nest braces, which is not permited in Smarty. You may want to consider adding a "var" or "assign" parameter to your createPager function which would then assign the var with the results of your function before returning. That would then obviate the need for the {assign}.

Cheers!


Last edited by boots on Mon Sep 22, 2003 4:19 am; edited 2 times in total
Back to top
View user's profile Send private message
cablehead
Smarty Rookie


Joined: 09 Jul 2003
Posts: 23

PostPosted: Mon Sep 22, 2003 4:15 am    Post subject: Reply with quote

boots thanks for your reply ...

Yeah - I'm not addressing performance at all in the above approach Smile. I usually suck it and see with performance. Until its a problem - its not a problem Smile

Still you wouldn't be writing a google front end with my strategy..

google - search gurgle - Results 1 - 10 of about 68,700.

I've been umming and arring about objects in templates for a couple of weeks. I drawn up a personal rule of no objects in templates; mainly for template simplicity and for security. So I'll take your former suggestion as well.

Thank you for the assign tip - that's just what I was looking for!

Andy.
Back to top
View user's profile Send private message Send e-mail
cablehead
Smarty Rookie


Joined: 09 Jul 2003
Posts: 23

PostPosted: Mon Sep 22, 2003 4:45 am    Post subject: Reply with quote

a quick but not comprehensive performance fix to the above paging in template proposal is to just cache the db hit.

userlist.php
Code:

$arrUser = $_SESSION["arrUser"];
if(!$arrUser) {
  $arrUsers = $db>getAll( "somesql", DB_FETCHMODE_ASSOC  );
  $_SESSION["arrUser"] = $arrUsers;
}

$smarty->assign("arrUsers", $arrUsers);


Designer has complete flexability -> programmer (me) get's to the pub very early Smile
Back to top
View user's profile Send private message Send e-mail
cablehead
Smarty Rookie


Joined: 09 Jul 2003
Posts: 23

PostPosted: Tue Sep 23, 2003 1:59 am    Post subject: Reply with quote

Damn .. started running into performance problems already with queries that only return 2000 rows .. Sad

* listen to boots ! * Smile

----
If your application code was made to understand the requirements, it could send a query to the db such that only exactly the rows required are returned (perhaps even in the proper sort order).
----

boots - I was hoping you might suggest how to slice the data with the query?

ie

instead of

$data = $db->getAll( "select * from fred order by $sortCritera" );
$page = array_slice( $data, $currPage*$pageSize, $pageSize );

something like

$data = $db->just get the required rows

Sorry for getting way of smarty chat ...

Any advice is greatly appreciated ...

Andy.
Back to top
View user's profile Send private message Send e-mail
purephase
Smarty Rookie


Joined: 29 Sep 2003
Posts: 8

PostPosted: Mon Sep 29, 2003 3:32 pm    Post subject: Reply with quote

cablehead wrote:
boots - I was hoping you might suggest how to slice the data with the query?

$data = $db->getAll( "select * from fred order by $sortCritera" );
$page = array_slice( $data, $currPage*$pageSize, $pageSize );


Check out MySQL for information on how to use the select statement in SQL.

The option to pay attention to is the LIMIT option. This allows you to select only specific subsets of rows determined by the query.

ie (to use your example above).

$data = $db->getAll( "select * from fred LIMIT 5,10 order by $sortCritera" );

The above would only return rows 6-10 in your query. From here I'm pretty sure you can see how to paginate easily. It has nothing to do with Smarty, just limit your SQL query to your desidered row count per page and increment/decrement by a specific value for each page a user moves to.

Hope that helps.

p.
Back to top
View user's profile Send private message
cablehead
Smarty Rookie


Joined: 09 Jul 2003
Posts: 23

PostPosted: Tue Sep 30, 2003 12:14 am    Post subject: Reply with quote

Thanks for your reply purephase and sorry everyone for staying off smarty topic Smile

This solution looks ideal - but I don't think all databases support mysql's limit syntax Sad

Pear DB offers DB_Common::limitQuery() which looks promising - but doesn't look like it can be used with powerful shortcuts like getAll etc ..

Are there any experienced ADODB users about?

I'm just using my own hacked together db abstraction for the moment which looks very peardbish but allows you to pass first and last records into all of the methods. It uses 'seek' to quickly jump to the first record. Works well for the moment but I'm only working with 3000 records so far .. so time will tell Smile
Back to top
View user's profile Send private message Send e-mail
Display posts from previous:   
This forum is locked: you cannot post, reply to, or edit topics.   This topic is locked: you cannot edit posts or make replies.    Smarty Forum Index -> Tips and Tricks All times are GMT
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group
Protected by Anti-Spam ACP