Creating a grid of images for an album in Drupal 6 with pagination
Following on from the original tutorial on creating a grid of images for an album in Drupal 6, a few people asked how to add pagination on to this for large albums.
Unfortunately from what I can tell Drupal's pagination function only works with SQL queries so we are unable to use the existing data available in the node object. But due to Drupal's nice database schema, it is very simple to write some simple SQL to give us the pager.
Below is the full code and below the code I will explain what each part does.
<?php
$count = count($node->field_images);
if ($count > 0):
$images_per_page = 9;
$sql = "SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = ". $node->nid;
$count = "SELECT COUNT(f.fid) FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = ". $node->nid;
$query = pager_query($sql, $images_per_page, 0, $count);
while ($data = db_fetch_object($query)) {
$images[$data->fid] = array(
'filepath' => $data->filepath,
'data' => unserialize($data->field_images_data),
);
}
$rows = array();
$images_per_row = 3;
$i = 0;
$row = 0;
foreach ($images as $image) {
$rows[$row][$i] = '<a class="gallery-thumbs" title="'. htmlspecialchars($image['data']['description']) .'" rel="lightbox[photo_gallery-'. $node->nid .']" href="'. imagecache_create_url('lightbox', $image['filepath']) .'">'. theme('imagecache', 'thumbnail', $image['filepath'], $image['data']['title'], $image['data']['title']) .(trim($image['data']['description']) != '' ? '<br /><small>'. $image['data']['description'] .'</small></a>' : '');
$i++;
if ($i == $images_per_row) {
$row++;
$i = 0;
}
}
?>
<table class="views-view-grid">
<tbody>
<?php foreach ($rows as $row_number => $columns): ?>
<?php
$row_class = 'row-' . ($row_number + 1);
if ($row_number == 0) {
$row_class .= ' row-first';
}
elseif (count($rows) == ($row_number + 1)) {
$row_class .= ' row-last';
}
?>
<tr class="<?php print $row_class; ?>">
<?php foreach ($columns as $column_number => $item): ?>
<td class="<?php print 'col-'. ($column_number + 1); ?>">
<?php print $item; ?>
</td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php print theme('pager', array(), $images_per_page, 0); ?>
<?php else: ?>
<p>No images in album</p>
<?php endif; ?>
First thing we do is check to see if there are any images. Rather than doing a SQL query to get the result, I have chosen to use the already existing array of images in the node object.
<?php$count = count($node->field_images);?>
Then as before we check to make sure we have images, then create our query to generate the pager.
<?php$images_per_page = 9;
$sql = "SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = ". $node->nid;
$count = "SELECT COUNT(f.fid) FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = ". $node->nid;
$query = pager_query($sql, $images_per_page, 0, $count);
while ($data = db_fetch_object($query)) {
$images[$data->fid] = array(
'filepath' => $data->filepath,
'data' => unserialize($data->field_images_data),
);
}?>
In the query, we are gathering the file id (fid) of each individual image, the field_images_data which is a serializd array of the title, description and alt text of the image from when it was uploaded and the filepath of the image. The count isn't necessarily needed, but I have found the pager can act oddly when the $count part of pager_query() is missing.
pager_query() also requires 2 other elements. The first after $sql, is the amount of rows to be taken out the database. The next number is the element number. This is needed for pages with multiple pagers on them. If you have got multiple pagers and experience trouble then you will need to change this.
Then from this we recreate the $images array that we had before, although it is missing some information which is provided through the $node object, it provides everything that we need to display the image on the page.
The whole table HTML section remains untouched, but it is followed by an extra line:
<?php print theme('pager', array(), $images_per_page, 0); ?>
This prints out the Drupal pager below out table of images. This can be used multiple times on a page, so you can have some pagination below and above the table of images.
If the page you are displaying the albums on already has pagers, you may need to change the 0 in both the theme_pager() and pager_query().
You should now have a fully working grid with pagination.
Edit: As pointed out by dukat in the comments, you can change the original SQL query to the following to keep the images in the order defined in the node.
<?php$sql = "SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = ". $node->nid ." ORDER BY i.delta ASC";?>
Obviously you can change the order between ASC or DESC.
Comments
Jason
Wed, 2010-03-10 16:33
Permalink
Awesome - works perfectly,
Awesome - works perfectly, thanks for the additional tutorial, couldn't have come at a better time!
Makoto
Wed, 2010-03-10 17:05
Permalink
Excellent tutorial! Very well
Excellent tutorial! Very well explained and easy to implement.
Thanks a lot!
dukat
Thu, 2010-04-01 22:31
Permalink
Thanks for this great
Thanks for this great tutorial.
Perhaps it's a good idea to add the order criterion "ORDER BY i.delta" to $sql.
Than the gallery grid will use the list order.
admin
Thu, 2010-04-01 22:49
Permalink
dukat, good idea, I hadn't
dukat, good idea, I hadn't thought about any ordering issues.
Raitsa
Sat, 2010-04-17 11:22
Permalink
Hey James, sent you an email
Hey James, sent you an email about Drupal image gallery stuff 15.4.2010 but did not hear from you back?
Just trying to make sure you got my email :)
admin
Sat, 2010-04-17 11:33
Permalink
To which email address? I
To which email address? I haven't got any emails about Drupal on 15.04.2010
Raitsa
Sat, 2010-04-17 20:40
Permalink
Hey James, where can i send
Hey James, where can i send you email to?
I tried to send it to James Tombs Google-profile cos dont have your email addy.
admin
Mon, 2010-04-19 09:59
Permalink
Ah right, it wasn't forwarded
Ah right, it wasn't forwarded on, I use my gmail account to forward email to another account but this one didn't come through.
Astrid
Tue, 2010-05-04 11:24
Permalink
I am a newbie for Drupal but
I am a newbie for Drupal but I love these tutorials.
I created a few albums (5) but I dont want the album covers to show if you open the album. At the moment the album cover is also the first thumb shown in the opened album.
Thanks for your help!!
Astrid
Tue, 2010-05-04 14:17
Permalink
One more question, for the
One more question, for the albums I want number of colums 3 but for the album details I want more colums, 5 for example. How can I do this?
Astrid
Tue, 2010-05-04 14:21
Permalink
Never mind my last question,
Never mind my last question, I found the solution.
Still looking for the album cover problem...
admin
Tue, 2010-05-04 17:33
Permalink
If you always used the first
If you always used the first image as the album cover, in the code you could use unset() to remove the first image from the array.
Astrid
Wed, 2010-05-05 07:55
Permalink
Where in the code should I
Where in the code should I use this and how?
admin
Wed, 2010-05-05 09:08
Permalink
Line before $count, write
Line before $count, write unset($node->field_images[0]);
Astrid
Wed, 2010-05-05 09:56
Permalink
If I write
If I write unset($node->field_images[0]); before $count, the album cover is shown as last pic in the album details
admin
Wed, 2010-05-05 13:13
Permalink
Change the view to use the
Change the view to use the first image of the gallery. You would also need to change the SQL queries to ignore the album cover.
Ian
Thu, 2010-06-17 14:09
Permalink
Fantastic tutorial James!
Fantastic tutorial James! This has helped me get my first gallery live!
Just wondering - is it possible to create sub gallery's using this method, also maybe even dedicated user 'areas' to upload their own photographs?
It would be nice if you had the option of selecting a gallery for the photo(s) to go into when you upload them.
Thanks!
Matt
Sun, 2010-10-10 16:21
Permalink
Great tutorial!
Great tutorial!
Navnish
Thu, 2010-10-21 21:24
Permalink
Ian, I have not tried it
Ian,
I have not tried it but handling these galleries through taxonomy temrs from this point would be easiers. We can now assign terms to these galleries and can create hirarchy...just a thought..
Navnish
Mac
Thu, 2010-10-28 20:06
Permalink
Fantastic tutorial. Worked
Fantastic tutorial. Worked like a charm, was wondering if the hyperlink to "download image" was possible to add in the lightbox 800x600 display? I thought it appeared at one point, but no longer.
James
Thu, 2010-10-28 20:19
Permalink
See my comments from 21
See my comments from 21 October on this post - http://jamestombs.co.uk/2009-06-25/creating-a-grid-of-images-for-an-albu....
Glenn
Sun, 2010-12-26 11:01
Permalink
Good one James, you are the
Good one James, you are the king of tutorial for drupal views galleries!
Anonymous
Fri, 2011-09-02 09:45
Permalink
Getting error
I'm getting this error using your code:
user warning: Table 'cupramontana1.content_field_images' doesn't exist query: SELECT COUNT(f.fid) FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = 2 in C:\virtual G\Cupramontana 1\drupal\sites\all\themes\garlanddpm\node.tpl.php on line 24.
user warning: Table 'cupramontana1.content_field_images' doesn't exist query: SELECT f.fid, i.field_images_data, f.filepath FROM content_field_images i JOIN files f ON f.fid = i.field_images_fid WHERE nid = 2 LIMIT 0, 9 in C:\virtual G\Cupramontana 1\drupal\sites\all\themes\garlanddpm\node.tpl.php on line 24.
warning: Invalid argument supplied for foreach() in C:\virtual G\Cupramontana 1\drupal\sites\all\themes\garlanddpm\node.tpl.php on line 35.
The only difference in my album is that i added a date field. Can it be the couse of the error?
I double checked that field name (field_images) is correct.
PS: of course it is not working!
james
Fri, 2011-09-02 19:03
Permalink
On your image field have you
On your image field have you selected it to be more than 1 image?