Really Simple Slideshow in Drupal Blocks
Thomas Ingham | 02-27-09Building a really quick taxonomy-based slideshow in The Drupal using Blocks and some SQL magickery.
Recently had a chance to build out a very simple, yet elegant slideshow for a client who already had a bunch of data stored in their drupal website. Since writing it only took about a third of the time that I thought it was going to I figure it would make for a good Blog post. The more exposure I have with Drupal (and I’ve had a mess of it lately) the more I like it. Granted as the CTO here at Coalmarch I don’t very often get the opportunity to play around in the guts of these applications so this was a nice “spice of life moment” for ol’mom.
Ingredients
1 Drupal version 6 website.
1 Content type that contains at least 1 CCK image field.
1 Knowledge of SQL, PHP, Javascript and HTML
1 About 20 minutes free.
1 PHP Field must be enabled.
Since our content type (Project) has been dilligently assigned to various taxonomy terms, we want to pull a list of unique term items, with matching node data to display in a slideshow. Additionally each of the slides in the show need to link to the node underneath it.
Step 1
Create a new block and make sure to limit it’s visibility to whatever page (in this case I used the <front> tag) and assign it to the Content portion of the page.
Inside of the block itself, you’ll want to switch to PHP Input format. The first piece of code is basically just a container for the actions we’re going to take:
<div id="slide" class="block">
</div>
Not too difficult. The second bit is to open up a script block:
<script language="javascript" type="text/javascript">
Then create an array in javascript to hold our items:
var hpImagesArray = new Array();
Nested inside of this, we’ll create our php block to encapsulate our elite codes. We’ll define our sql query as making a join between a Node, our taxonomy terms table and the files table. We’re using imagecache in our example, but that could just as easily be the native filepath. Further, we group on taxonomy “term_data.name” so that we only get a single result for each term that has a matching node. This means that there’s no WHERE clause required in the simplest example, but you could easily extend this to support filtering on whether or not a node is pushed to the front-page; or a limitless supply of other factors. Because we’re linking across the project content type table we don’t have to specify a type, and we’ll only ever get results that match that node type. Handy.
<?php
$sql = "select drupal_term_data.name, drupal_files.filename, drupal_files.filepath, drupal_node.nid from drupal_node
inner join drupal_term_node on drupal_term_node.nid = drupal_node.nid
inner join drupal_term_data on drupal_term_data.tid = drupal_term_node.tid
inner join drupal_content_type_project on drupal_content_type_project.nid = drupal_node.nid
inner join drupal_files on drupal_files.fid = drupal_content_type_project.field_mainimage_fid
group by drupal_term_data.name;";
Here we send the query to the database using the built-in “db_query” method.
$result = db_query($sql);
And then just like we normally would, we iterate the results.
while( $row = db_fetch_array($result) )
{
$image = "/sites/default/files/imagecache/img_medium/".$row['filepath'];
$url = "/node/".$row['nid'];
$name = $row['name'];
This is a simple cast of our member variables into a pseudo-object in javascript. This is how I tend to build stuff out, setting up a datasource in one area so I can use it without modifying the php code again later.
print "hpImagesArray[hpImagesArray.length] = {theImage:\"$image\",theURL:\"$url\",theName:\"$name\"};";
}
?>
And finally, we call a timer event every 15 seconds that randomly selects an image from the set and displays it in the background of the main container.
window.setInterval( flopHP, 15000 );
flopHP();
function flopHP()
{
var element = document.getElementById('hp');
var randValue = parseInt(Math.random()*(hpImagesArray.length));
element.style.backgroundImage="url("+hpImagesArray[randValue].theImage+")";
element.innerHTML = "<h1>"+hpImagesArray[randValue].theName+"</h1>";
element.onclick = function()
{
document.location.href = hpImagesArray[randValue].theURL;
};
}
</script>
Implementing this is pretty simple, but you will need to have some CSS on the container to control the appearance of the background image and also set up the boundary of the frame. Imagecache allows you to create resized versions of your images, so matching the dimensions on a Scale operation seems like a good fit.
A couple of quick notes:
- My first thought was to do this using views but unfortunately there’s no really easy way to unique on the term name.
- When referencing files using imagecache, make sure you use the basename of the filepath of the file record. Using filename is volatile and won’t always point to the correct resource.
And finally, some links to relevant Modules:

Comments