jacmaes Posted March 7, 2019 Share Posted March 7, 2019 On a photographer's site, I have multiple albums. Each album is made up of a series of pages (1 image per page). So navigating the album is matter of going from one child page to the next. Now let's say I'm viewing image number 15 in a very large album containing more than 100 images. Showing the full list of images in this album as a thumbnail gallery and highlighting the current image/page is easy enough: <?php foreach ($page->siblings as $child): $current = null; if ($child == $page) $current = " aria-current='page'"; echo "<a$current href='{$child->url}'><img src='{$child->photo->size(150,150)->url}' width='75' height='75' alt=''></a>"; endforeach; ?> But if my album contains 100 images, it becomes impractical and slow to show the full list of thumbnails. What I'd like to do instead is detect the current page/image position, and show the previous 10 and next 10 images. I've managed to show the next 10 with "slice": <?php $current_position = $page->index(); $next_10 = $page->siblings->slice($current_position, 10); foreach ($next_10 as $child): $current = null; if ($child == $page) $current = " aria-current='page'"; echo "<a$current href='{$child->url}'><img src='{$child->photo->size(150,150)->url}' width='75' height='75' alt=''></a>"; endforeach; ?> How would I go about showing the previous 10 also? Link to comment Share on other sites More sharing options...
elabx Posted March 7, 2019 Share Posted March 7, 2019 Maybe with prevAll() ? https://processwire.com/api/ref/page/prev-all/ $prev = $page->prevAll(); //Asuming it returns sorted in the same order (I'm not certain) get the last 10 pages $prev = $prev->slice($prev->count - 10); Link to comment Share on other sites More sharing options...
jacmaes Posted March 7, 2019 Author Share Posted March 7, 2019 Thanks @elabx for pointing me to prevAll(), which I had not encountered yet. Unfortunately, the order is not respected and the results seem also random (sometimes it retrieves fewer results than expected). Link to comment Share on other sites More sharing options...
LostKobrakai Posted March 7, 2019 Share Posted March 7, 2019 $page->prevAll("sort=sort"); This should force the order. 1 Link to comment Share on other sites More sharing options...
jacmaes Posted March 7, 2019 Author Share Posted March 7, 2019 @LostKobrakai that helped, thanks. @elabx 's suggestion still retrieves unexpected results: Photo #1: nothing shown, as expected. Photos #2 to #6: work. Photo #7: shows only 4 previous images instead the of the expected 6. Photo #8: shows only 3. Photo #9: shows only 2. Photo #10: shows only 1. Photo #11: works. Photos #12 and above: only shows first 10… Link to comment Share on other sites More sharing options...
BrendonKoz Posted March 7, 2019 Share Posted March 7, 2019 Although slow and impractical to show all 100 images on a single page in a gallery, would it be as slow and impractical if you used the JS-based lazy-loading for images (don't forget to force container size on the image so there's no re-flow issues during rendering -- ex: https://css-tricks.com/preventing-content-reflow-from-lazy-loaded-images/). It's not necessarily a better solution, just an alternative. Link to comment Share on other sites More sharing options...
Robin S Posted March 7, 2019 Share Posted March 7, 2019 If you have a large number of images in the gallery it would be better not to load all the pages into memory only to display a portion of them with slice(). Better to use start and limit in your selector to get only the pages you will display. You could adapt the example given here: 3 Link to comment Share on other sites More sharing options...
jacmaes Posted March 7, 2019 Author Share Posted March 7, 2019 Great, thanks @Robin S! Your example looks like what I'm looking for. I'll give it a try early next week and report back with my adapted solution, if I manage to make it work. 2 Link to comment Share on other sites More sharing options...
jacmaes Posted March 12, 2019 Author Share Posted March 12, 2019 Here's @Robin S code adapted to produce the following thumbnail navigation (semi-transparent thumb #98 is the current one): <?php // Number of thumbs to show $limit = 9; // Get the number of visible siblings $num_siblings = $page->parent->numChildren(true); // The default start value is zero $start = 0; // If the number of siblings is greater than the limit then we need to adjust the start value if($num_siblings > $limit) { // Get the halfway point of the limit $half_limit = floor($limit / 2); // Get the index of the current page relative to its siblings $index = $page->index(); // Adjust the start value to keep the current page within the sibling links if($index > $half_limit) $start = $index - $half_limit; if($num_siblings - $start < $limit) $start = $num_siblings - $limit; } $items = $page->siblings("start=$start, limit=$limit"); // Next page and previous page relative to current page $next_page = $page->next(); $prev_page = $page->prev(); // Next and previous SVG icons $left_arrow = "<svg role='img' aria-labelledby='previous-icon' class='icon icon--inline' height='24' width='24'><title id='previous-icon'>Next photo: {$page->prev->title}</title><use xlink:href='#icon--left-arrow'></use></svg>"; $right_arrow = "<svg role='img' aria-labelledby='next-icon' class='icon icon--inline' height='24' width='24'><title id='next-icon'>Previous photo: {$page->next->title}</title><use xlink:href='#icon--right-arrow'></use></svg>"; ?> <?php if($items->count > 1): echo "<div class='thumb_gallery'>"; if ($prev_page->id) echo "<a class='thumbnail' href='$prev_page->url'>$left_arrow</a>"; foreach($items as $item): $number = $item->index() + 1; $current = null; if ($item == $page) $current = " aria-current='page'"; echo "<a$current class='thumbnail' href='$item->url'>"; echo "<img class='responsive-images thumbnail__image' src='{$item->photo->size(150,150)->url}' width='75' height='75' alt=''>"; echo "<span class='thumbnail__label'>$number</span>"; echo "</a>"; endforeach; if($next_page->id) echo "<a class='thumbnail' href='$next_page->url'>$right_arrow</a>"; echo "</div>"; endif; ?> I hope this can help someone else. Thanks again @Robin S !! 4 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