View previous topic :: View next topic |
Author |
Message |
mphare Smarty n00b
Joined: 18 May 2003 Posts: 1
|
Posted: Tue May 20, 2003 9:13 pm Post subject: How to paginate {section/} |
|
|
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 |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Tue May 20, 2003 9:26 pm Post subject: |
|
|
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 |
|
kasper Smarty n00b
Joined: 24 Apr 2003 Posts: 4
|
Posted: Tue May 27, 2003 8:44 pm Post subject: |
|
|
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 |
|
Justin Smarty Regular
Joined: 07 May 2003 Posts: 38 Location: Vilnius, Lithuania
|
Posted: Wed May 28, 2003 5:03 am Post subject: |
|
|
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 |
|
sitemod Smarty n00b
Joined: 29 May 2003 Posts: 1 Location: Buffalo, NY
|
Posted: Thu May 29, 2003 1:05 pm Post subject: |
|
|
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 |
|
kasper Smarty n00b
Joined: 24 Apr 2003 Posts: 4
|
Posted: Wed Jun 11, 2003 7:34 am Post subject: |
|
|
cannot use that, my hosting does not have PEAR (i know i know ).
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 |
|
kasper Smarty n00b
Joined: 24 Apr 2003 Posts: 4
|
Posted: Wed Jun 11, 2003 7:57 am Post subject: |
|
|
ok, assigning array of arrays with the wanted layout for tables works well
that's smart enough for me |
|
Back to top |
|
excelsior Smarty n00b
Joined: 16 Jul 2003 Posts: 1
|
Posted: Wed Jul 16, 2003 6:46 pm Post subject: |
|
|
For me too |
|
Back to top |
|
cablehead Smarty Rookie
Joined: 09 Jul 2003 Posts: 23
|
Posted: Mon Sep 22, 2003 3:02 am Post subject: |
|
|
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 |
|
boots Administrator
Joined: 16 Apr 2003 Posts: 5611 Location: Toronto, Canada
|
Posted: Mon Sep 22, 2003 3:51 am Post subject: |
|
|
Hi cablehead. Your pager looks like it doesn't get around the performance issue.
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 ]
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 |
|
cablehead Smarty Rookie
Joined: 09 Jul 2003 Posts: 23
|
Posted: Mon Sep 22, 2003 4:15 am Post subject: |
|
|
boots thanks for your reply ...
Yeah - I'm not addressing performance at all in the above approach . I usually suck it and see with performance. Until its a problem - its not a problem
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 |
|
cablehead Smarty Rookie
Joined: 09 Jul 2003 Posts: 23
|
Posted: Mon Sep 22, 2003 4:45 am Post subject: |
|
|
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 |
|
Back to top |
|
cablehead Smarty Rookie
Joined: 09 Jul 2003 Posts: 23
|
Posted: Tue Sep 23, 2003 1:59 am Post subject: |
|
|
Damn .. started running into performance problems already with queries that only return 2000 rows ..
* listen to boots ! *
----
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 |
|
purephase Smarty Rookie
Joined: 29 Sep 2003 Posts: 8
|
Posted: Mon Sep 29, 2003 3:32 pm Post subject: |
|
|
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 |
|
cablehead Smarty Rookie
Joined: 09 Jul 2003 Posts: 23
|
Posted: Tue Sep 30, 2003 12:14 am Post subject: |
|
|
Thanks for your reply purephase and sorry everyone for staying off smarty topic
This solution looks ideal - but I don't think all databases support mysql's limit syntax
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 |
|
Back to top |
|
|