nikola Posted August 28, 2011 Share Posted August 28, 2011 I've set up a gallery page that uses "gallery" template. The gallery page will contain lots of images but I want to display only 20 per page. How can I accomplish pagination for this type of action? I don't want to set up children pages that will contain 20 images per page, rather let the Processwire do the pagination from one page. Thanks Link to comment Share on other sites More sharing options...
seddass Posted August 28, 2011 Share Posted August 28, 2011 Have you read the page at http://processwire.com/api/modules/markup-pager-nav/ Link to comment Share on other sites More sharing options...
nikola Posted August 28, 2011 Author Share Posted August 28, 2011 Yes, I have. I know how to return an array of pages and paginate them, but I need similar but different approach. I have only one page that contains images for gallery, it doesn't have parent page nor it spans across children pages with images. The page will contain lots of images and I want to set pagination to have 20 images per page but I don't know how to make pager limitation based on one page. Link to comment Share on other sites More sharing options...
seddass Posted August 28, 2011 Share Posted August 28, 2011 You should track the page number and have to adjust the "start" and "limit" selectors of images array using the find() or filter() methods. Instead: $results = $pages->find("start=0, limit=n"); You could use: $results = $images->find("start=0, limit=n"); to "paginate" the images on the page. And I hope that $pagination = $results->renderPager(); echo $pagination; will still work. Link to comment Share on other sites More sharing options...
nikola Posted August 29, 2011 Author Share Posted August 29, 2011 Unfortunately it doesn't work. I've tried various combinations and can't make it work... Ryan, any tips about the way it can be done? Link to comment Share on other sites More sharing options...
apeisa Posted August 29, 2011 Share Posted August 29, 2011 I think that pagination works only with pageArrays, so no help here. Building custom pagination for images is not that hard though, I'll provide you a starting point when I get to computer. Link to comment Share on other sites More sharing options...
nikola Posted August 29, 2011 Author Share Posted August 29, 2011 Thanks for you help, waiting for the code... Link to comment Share on other sites More sharing options...
seddass Posted August 29, 2011 Share Posted August 29, 2011 Try something like: $all_images = $page->images; $total = count($all_images); $images_per_page = 4; $all_pages = round($total / $images_per_page); $start = ($input->pageNum - 1) * $images_per_page; $images_limited = $all_images->slice($start, $images_per_page); foreach($images_limited as $img): $thumb = $img->size(200, 120); echo "\n<img src='{$thumb->url}' width='{$thumb->width}' height='{$thumb->height}' alt='' />"; endforeach; Link to comment Share on other sites More sharing options...
ryan Posted August 29, 2011 Share Posted August 29, 2011 (edited) I've not tried seddass's solution, but it looks right on. I'm using some of his code in my example too. So here's another option, which is to piggyback onto the MarkupPagerNav module, even though you aren't dealing with pages. <?php // get the images you are going to display $items_per_page = 4; $start = ($input->pageNum - 1) * $items_per_page; $total = count($page->images); $images = $page->images->slice($start, $items_per_page); // make this to give MarkupPagerNav what it needs $a = new PageArray(); // add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // tell the PageArray some details it needs for pagination // (something that PW usually does internally, for pages it loads) $a->setTotal($total); $a->setLimit($items_per_page); $a->setStart($start); // output your images foreach($images as $p) { $img = $p->img; echo "<img src='{$img->url}' alt='{$img->description}' />"; } // output the pagination navigation echo $a->renderPager(); Btw, an images field on a page isn't going to scale infinitely. At some point, you are going to find it difficult to manage, sort, etc. So I would still place some limits on yourself for the max number of images you are going to attach to a single page. Edited February 5, 2012 by ryan Corrected typo, changed $images_per_page to $items_per_page 4 2 Link to comment Share on other sites More sharing options...
apeisa Posted August 29, 2011 Share Posted August 29, 2011 Thanks guys, there is no reason for me to post yet another example anymore Btw, an images field on a page isn't going to scale infinitely. At some point, you are going to find it difficult to manage, sort, etc. So I would still place some limits on yourself for the max number of images you are going to attach to a single page. That will be hard when we get drag & drop magic working. It will be so much fun to add more and more images to single field! Link to comment Share on other sites More sharing options...
nikola Posted August 29, 2011 Author Share Posted August 29, 2011 I was unable to get images with pagination based on Ryan's method. I've decided to tako another route and follow Ryan's advice to make children pages underneath "Gallery" page that will contain 20 images per page. I use this code to merge them together, but yet again can't use pagination. <?php foreach($page->children() as $gallery) { if(!count($gallery->images)) continue; foreach($gallery->images as $image) { $thumb = $image->size(142, 92); echo "<a href='{$image->url}' rel='colorbox'><img src='{$thumb->url}' width='{$thumb->width}' height='{$thumb->height}' class='photo' /></a>"; } } ?> Probably it isn't the smartest way to do it but it gets the job done ... all I need is now to paginate them so I can have 20 images per page... Link to comment Share on other sites More sharing options...
ryan Posted August 29, 2011 Share Posted August 29, 2011 You mentioned that pagination wasn't working–can you provide more detail about what it is doing? Also, double check that page numbers are supported in your template settings, under the "URLs" tab. Without that turned on, pagination will not work. Link to comment Share on other sites More sharing options...
seddass Posted August 29, 2011 Share Posted August 29, 2011 I think he is trying to output all of the images from all of the child pages at once and later he is trying to paginate the $images array instead to paginate the child pages. Hope I am wrong here. Nikola, lets clear you mind. 8) 1) Try to create a "galleries" template with a few child pages with "gallery" template. You should to be able to paginate the child pages as described at http://processwire.com/api/modules/markup-pager-nav/. The pagination steps should to be one page per pagination step (i.e. limit=1). It should to be working. Haven't tried it. 2) In each "gallery" template with "images" field you could use your code below: foreach($page->images as $image): $thumb = $image->size(142, 92); echo "\n<a href='{$image->url}' rel='colorbox'><img src='{$thumb->url}' width='{$thumb->width}' height='{$thumb->height}' class='photo' /></a>"; endforeach; Hope i have helped. Link to comment Share on other sites More sharing options...
ryan Posted August 29, 2011 Share Posted August 29, 2011 PW actually won't attempt pagination with limit=1. It needs at least limit=2 before it'll attempt to determine totals needed for pagination. This is an optimization that lets the system run more quickly, since so many parts in PW use limit=1 (and this is the first instance where a limit=1 need has turned up in pagination). The more I think about it, I have to imagine that pagination wasn't working before because page numbers must have been turned off in the template. That's the only reason I can think of why our previous examples may have not worked on his site. One option for single-page pagination is to just use next/prev buttons. $page->next() and $page->prev() return the next and previous sibling pages, making this type of pagination very easy. i.e. <?php $prev = $page->prev(); $next = $page->next(); if($prev->id) echo "<a href='{$prev->url}'>Previous Page</a> "; if($next->id) echo "<a href='{$next->url}'>Next Page</a> "; You wouldn't want to do this with something that has thousands of pages, but it would be a good solution for smaller pagination groups. Link to comment Share on other sites More sharing options...
nikola Posted August 30, 2011 Author Share Posted August 30, 2011 I still haven't figured this out yet. When using Ryan's code I get following errors: Exception: Method Pageimages::renderPager does not exist or is not callable in this context (in C:\inetpub\wwwroot\pw\wire\core\Wire.php line 231) #0 C:\inetpub\wwwroot\pw\site\templates\gallery.php(46): Wire->__call('renderPager', Array) #1 C:\inetpub\wwwroot\pw\site\templates\gallery.php(46): Pageimages->renderPager() #2 C:\inetpub\wwwroot\pw\wire\core\TemplateFile.php(88): require('C:\inetpub\wwwr...') #3 [internal function]: TemplateFile->___render() #4 C:\inetpub\wwwroot\pw\wire\core\Wire.php(267): call_user_func_array(Array, Array) #5 C:\inetpub\wwwroot\pw\wire\core\Wire.php(229): Wire->runHooks('render', Array) #6 C:\inetpub\wwwroot\pw\wire\modules\PageRender.module(194): Wire->__call('render', Array) #7 C:\inetpub\wwwroot\pw\wire\modules\PageRender.module(194): TemplateFile->render() #8 [internal function]: PageRender->___renderPage(Object(HookEvent)) #9 C:\inetpub\wwwroot\pw\wire\core\Wire.php(267): call_user_func_array(Array, Array) #10 C:\inetpub\wwwroot\pw\wire\core\Wire.php(229): Wire->runHooks( If I use seddass's method I can't paginate either. I tried the solution with one page that holds images and with children pages that contain images and still no go. I'm attaching the screenshot how should it look like... Link to comment Share on other sites More sharing options...
ryan Posted August 30, 2011 Share Posted August 30, 2011 Looking at your error message, I see where it came from. There was an error in my earlier example (sorry). At the end of it, it should be: // output the pagination navigation echo $a->renderPager(); rather than $images->renderPager(); 1 Link to comment Share on other sites More sharing options...
nikola Posted August 30, 2011 Author Share Posted August 30, 2011 It works! Thanks Ryan for your help (others included ) Link to comment Share on other sites More sharing options...
nikola Posted September 5, 2011 Author Share Posted September 5, 2011 Hmm, It doesn't work as intended, Images are repeating themselves. I tried different approach: I have Gallery page in the root of the website, and Gallery page has children. I didn't put the limit on number of images that can appear on any of the children. I use this code to grab all image from all the children pages. I need to paginate them with the limit of 16 per page. <?php echo "<div class='photo-gallery'>"; $photos = $pages->get('/foto/'); foreach($photos->children as $photo) { foreach($photo->images as $p) { $t = $p->size(142, 92); echo "<a rel='colorbox' href='$p->url'><img src='{$t->url}' alt='{$t->description}' width='{$t->width}' height='{$t->height}' class='photo' /></a>"; } } echo "</div>"; If I use <?php foreach($photo->images->find("limit=16") as $p) { the limit count doesn't work right... and pagination doesn't work either. Template has numbering turned on. Link to comment Share on other sites More sharing options...
ryan Posted September 5, 2011 Share Posted September 5, 2011 Hmm, It doesn't work as intended, Images are repeating themselves. I'm not sure which solution we're talking about, because there have been a few posted. Can you post the code for the solution you were using? I'm guessing it would be an easy fix, but just need the context. <?php foreach($photo->images->find("limit=16") as $p) { The above will only cycle through the first 16 images on any page. Then it would move on to the next page in your $photos->children loop and display the first 16 photos from the next page. But it's not going to do anything for pagination. If you want to keep things from getting overly complex, I'd recommend either focusing on paginating the images from a single page (like the example below) or paginate multiple pages where each page has 1 image. I think we can find straightforward solutions for either of those. <?php $limit = 16; $start = ($input->pageNum-1) * $limit; $images = $page->images->slice($start, $limit); foreach($images as $image) { // ... } Link to comment Share on other sites More sharing options...
nikola Posted September 6, 2011 Author Share Posted September 6, 2011 Thanks, I've manage to solve it and ended up using this combination: <?php echo "<div class='photo-gallery'>"; $photos = $pages->get('/foto/'); $limit = 16; $start = ($input->pageNum-1) * $limit; $images = $page->images->slice($start, $limit); $total = count($photos->images); $a = new PageArray(); foreach($images as $unused) $a->add(new Page()); $a->setTotal($total); $a->setLimit($limit); $a->setStart($start); foreach($images as $image) { $thumb = $image->size(142, 92); echo "<a rel='colorbox' href='$image->url'><img src='{$thumb->url}' alt='{$thumb->description}' width='{$thumb->width}' height='{$thumb->height}' class='photo' /></a>"; } echo "</div>"; echo "<div class='clear'></div>"; $start = $a->getStart(); $end = $start + count($a); $total = $a->getTotal(); $num = $input->pageNum; $lastNum = ceil($total / $a->getLimit()); echo "<p class='numbering'>Prikazano fotografija: $start - $end od $total | stranica $num od $lastNum</p>"; echo $a->renderPager(array( 'nextItemLabel' => "Sljedeća", 'previousItemLabel' => "Prethodna", )); Link to comment Share on other sites More sharing options...
ryan Posted September 6, 2011 Share Posted September 6, 2011 Glad you got it working. Thanks for posting the final code. Link to comment Share on other sites More sharing options...
nikola Posted September 6, 2011 Author Share Posted September 6, 2011 No problem. Thanks for your help, Ryan. Link to comment Share on other sites More sharing options...
doolak Posted February 4, 2012 Share Posted February 4, 2012 Hello there, i am trying such simple image "pagination" which ryan described in post #9 - pagination works but page 1 displays still all 4 images (should display just 2 of them) - but there is a second page which then displays the last two pictures. Here is the code: <?php /** * Page template * */ include("./header.inc"); echo "<h1>" . $page->headline . "</h1>"; echo "<h1><?=$page->title?></h1>"; echo "<h2><?=$page->album_description?></h2>"; echo "<ul class='images'>"; // get the images you are going to display $items_per_page = 2; $start = ($input->pageNum - 1) * $items_per_page; $total = count($page->images); $images = $page->images->slice($start, $images_per_page); // make this to give MarkupPagerNav what it needs $a = new PageArray(); // add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // tell the PageArray some details it needs for pagination // (something that PW usually does internally, for pages it loads) $a->setTotal($total); $a->setLimit($items_per_page); $a->setStart($start); foreach($images as $p) { $thumb = $p->size(100, 100); // specify your own width/height echo "<li style='width:100px; height:100px; float:left; margin:5px;'>"; // better to use a stylesheet echo "<a href='{$p->url}' class='lightbox' rel='gallery'>"; echo "<img src='{$thumb->url}' alt='{$thumb->description}' /></a>"; echo "</li>"; } echo "</ul>"; echo "<br style='clear: both;' />"; // output the pagination navigation echo $a->renderPager(); include("./footer.inc"); Any idea why it does not work as it should? Kind regards, Christian Link to comment Share on other sites More sharing options...
Soma Posted February 4, 2012 Share Posted February 4, 2012 <?php $items_per_page = 2; $start = ($input->pageNum - 1) * $items_per_page; $total = count($page->images); $images = $page->images->slice($start, $images_per_page); Notice the typo? Link to comment Share on other sites More sharing options...
doolak Posted February 5, 2012 Share Posted February 5, 2012 @Soma: Thank you very very much! Works perfectly now. Here the corrected original code from post #9, which works fine as shown below - just, as Ryan already mentioned, don't forget do activate the support of page numbers in your template settings, under the "URLs" tab... <?php // get the images you are going to display $items_per_page = 4; $start = ($input->pageNum - 1) * $items_per_page; $total = count($page->images); $images = $page->images->slice($start, $items_per_page); // make this to give MarkupPagerNav what it needs $a = new PageArray(); // add in some generic placeholder pages foreach($images as $unused) $a->add(new Page()); // tell the PageArray some details it needs for pagination // (something that PW usually does internally, for pages it loads) $a->setTotal($total); $a->setLimit($items_per_page); $a->setStart($start); // output your images foreach($images as $p) { $img = $p->img; echo "<img src='{$img->url}' alt='{$img->description}' />"; } // output the pagination navigation echo $a->renderPager(); Kind regards, Christian 1 Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now