Well not exactly, but close enough to warrant the title I would think.
I know that I was supposed to publish another tutorial before this one, but I hacked this up last week, and thought it was cool enough to preempt the other post. So at work the new design we just launched called for a rotating, hyperlinked slideshow, with cross-fading.
Normally it would be “To the Flash Cave!”, but I was feeling extra crotchety so I decided to basically recreate Slideshow Pro in PHP, CSS and some JS-foo. Nothing to spectacular, but it is shiny. Be warned, this is a very long tutorial… use at your own risk.
The slideshow needed to be:
My solution currently addresses points 1 - 3 directly; point 4 is just waiting for me to write a simple web form page. Lower priority at the moment. So lets take a look at the parts that are assembled to make up this Justice League of the web.
So we will of course be making use of PHP 5 and all its OOP goodnes; throw in a liberal sprinkling of prototype and script.aculo.us and finally some auto-generated CSS for spice. Add that together, and you get this.
So lets go over the logic before we get into some code. To maximize flexibility we are going to be storing information on each image in our slideshow in a SQL database table (for this example a MySQL DB). We will query this table for all the images we have catalogued that aren’t retired or expired, and will use this information to generate CSS and JS to power our slideshow.
We all on the same page? Good lets move onto the first bit of our code, the slideshow table structure.
CREATE TABLE `slideshow` (
`ID` bigint(20) NOT NULL auto_increment,
`url` varchar(256) NOT NULL,
`description` text NOT NULL,
`filename` varchar(256) NOT NULL,
`expiredate` date NOT NULL,
`retired` tinyint(1) NOT NULL,
KEY `ID` (`ID`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=6 ;
Nothing to scary here I would say. But just in case lets look at each field in some more detail:
For the sake of this tutorial, we will use the data set from the Asbury Site. Next lets look at the slideshow class file.
Currently our class will only have one function create_show() but once we start to make a web interface this class will be come much more noisy. Since I primarily talk about WordPress here, we will assume that you will be using this on a WP powered site. If that is not the case, you should at least know how to connect to your DB… if that isn’t the case, stop now and come back when you do. Here is the code for our class:
<?php
// begin slideshow class
class slideshow {
function create_show() {
global $wpdb;
$today = date('Y-m-d');
$q = $wpdb->get_results( "SELECT ID, url, description, filename, expiredate, retired FROM slideshow WHERE retired = 0 AND expiredate < '$today' ORDER BY ID ASC" );
if( is_array( $q ) ) {
return $q;
} else {
return array();
}
}
} // end slideshow class
So lets step through the function. First we find out what todays date is and set it equal to $today. Then we perform an sql query against our slideshow table, where we look for records that are not retired (equal to 0) and that have an expiredate less than $today.
Okay so now we have our one function, lets make some use of it. Next we’ll look at the how we programmaticaly create CSS, HTML and the JS that powers the slideshow with this function.
To make the slideshow work, we are going to need three things: generated HTML, CSS and JS. I like to split out generated markup and scripting into thier own files, so that the static content we have can benefit from cacheing.
Here is the code for slideshow.css.php:
// begin CSS generation functions
$members = slideshow::create_show();
header('Content-Type: text/css; charset: UTF-8');
$i = 1;
$num = count( $members );
?>
<?php foreach ( $members as $picture ) {
echo "#" . 'spot-' . $i . "\n";
echo '{' . "\n";
echo ' position: absolute;' . "\n";
echo ' left: auto !important;' . "\n";
echo ' left: 7.8em;' . "\n";
echo '}' . "\n";
echo "\n";
$i++;
} // end CSS generation functions
Nothing to out of the ordinary going on here, we call our create_show() function, then loop through the results returned creating a CSS rule for each result we find. Next we create the JS that powers the cross-fading-foo we all love so much:
// begin JS generation code
header('Content-Type: text/javascript; charset: UTF-8');
$members = slideshow::create_show();
$i = 1;
$num = count( $members );
?> var divs_to_fade = new Array(<?php foreach ( $members as $picture ) { ?><?php echo "'" . 'spot-' . $i . "'"; ?><?php $i++; ?><?php if ( $i == $num + 1 ) { echo ''; } else { echo ', '; };
}
?>);
var i = 0;
// the number of milliseconds between swaps. Default is five seconds.
var wait = 5000;
// the function that performs the fade
function swapFade() {
Effect.Fade(divs_to_fade[i], { duration:1, from:1.0, to:0.0 });
i++;
if (i == <?php echo $num; ?>) i = 0;
Effect.Appear(divs_to_fade[i], { duration:1, from:0.0, to:1.0 });
}
// the onload event handler that starts the fading.
function startSlideShow() {
setInterval('swapFade()',wait);
}
<?php // end JS generation code ?>
Again, very straightforward. Some of you might have noticed that we queried for all of the fields in the table in each of these examples, but didn’t actually use the information. We could have created another function, that only returned the ID for example, and used it when creating the CSS and JS.
I decided it was silly to have two functions, but if you want to go that way, by all means do. It makes no difference to me. Next we need to create some HTML. I have this in a template file (slideshow.php) that I load via our nifty theme system.
When using WordPress you could place this code in the index template, or the header template wrapped in if ( is_home() ) if you wanted it to only show up on the root of your site. Here is the code to generate the markup for the slideshow:
<?php
// begin HTML generation functions
$members = slideshow::create_show();
$i = 1;
foreach ( $members as $picture ) {
?> <div id="spot-<?php echo $i; ?>"<?php if ( $i == 1 ) { echo ''; } else { echo ' style="display:none"'; } $i++; ?>> <a href="<?php echo $picture->url; ?>" title="<?php echo $picture->description; ?>"><img src="theme/default/images/spots/<?php echo $picture->filename; ?>.jpg" alt="<?php echo $picture->description; ?>" /></a> </div><?php } // end HTML generation functions ?>
When run succesfully this code will give you something like this:
<div id="spot-1"> <a href="/url1/" title="URL and Image 1"><img src="/wp-content/themes/default/images/image1.jpg" alt="URL and Image 1" /></a> </div> <div id="spot-2" style="display:none"> <a href="/url2/" title="URL and Image 2"><img src="/wp-content/themes/default/images/image2.jpg" alt="URL and Image 2" /></a> </div> <div id="spot-3" style="display:none"> <a href="/url3/" title="URL and Image 3"><img src="/wp-content/themes/default/images/image3.jpg" alt="URL and Image 3" /></a> </div> <div id="spot-4" style="display:none"> <a href="/url4/" title="URL and Image 4"><img src="/wp-content/themes/default/images/image4.jpg" alt="URL and Image 4" /></a> </div> <div id="spot-5" style="display:none"> <a href="/url5/" title="URL and Image 5"><img src="/wp-content/themes/default/images/image5.jpg" alt="URL and Image 5" /></a> </div>
So that is it, you have the core of functionality that can be found in SlideShow Pro, for free throught the clever use of PHP, CSS and JS. Now, let me say that I don’t have any problem with Todd’s product. It is pretty amazing and very affordable, I just didn’t want to use Flash for this when there was a much more interesting method that could be employed.
Again to see this in action, just load the Asbury College Homepage and be amazed by the fadey goodness.
As always, questions and comments are welcome in the, uh… comments section.
Stroll on over and visit Arthus Erea
March 1, 2007
Very nice; I tried doing something like this a while back and ended up just going back to Flash. Of course, I didn’t know about script.aculo.us then. Flickr should use this on the front page!
Stroll on over and visit tom
March 1, 2007
nice tutorial derek, when thing would be always that easy :)
arthus, that was my first thought too, flickr should use this too. not exactly this handmade script, but a feature with a slideshow would be nice
is this available as a plugin?
Stroll on over and visit Chris J. Davis
March 1, 2007
Thanks for the comments guys. I should think that Flickr will use soemthing like this when they can, since they have been moving away from dependency on flash.
And Tom, I am using Derek’s theme for this month but this is my site (Chris J. Davis), not Derek’s. And no, it isn’t available as a plugin. I am not sure I will be rolling it up intp one.
Stroll on over and visit Nathan Smith
March 1, 2007
Very nice writeup, and nicely done on Asbury.edu as well. You’re cleanin’ up that on-horse town. :)
Also, hadn’t mentioned it before, so I will do so here: I’m really diggin your new site design. It’s very Jeff-Croft-esque, but with enough CJD flavah to make it feel unique. Might I suggest a little show/hide JS action on the tags though? It’s sort of overwhelming. Anyway, I’m just complaining needlessly. Don’t mind me.
Stroll on over and visit Nathan Smith
March 1, 2007
Update: I just realized it’s a skin. Please disregard my previous nit-picky-ness (nit-picky-ness spelled wrong intentionally).
Stroll on over and visit tom
March 1, 2007
forgive me 100000 times, im sorry :)
Stroll on over and visit Andy
March 1, 2007
Chris-
Thanks - onload=”startSlideShow();” did the trick - I must be going mental!
I am running it all in PHP4 so I guess it should work - I just stripped out the OO for now - all should still work though.
Thanks again!
-Andy
Stroll on over and visit CJGraphix
March 22, 2007
Thanks so much for this. I found it extremely helpful. While I ended up modifying some portions of the code to suit my personal needs I never would have gotten there if it wasn’t for this tutorial.
Stroll on over and visit Vidar
October 25, 2007
Oh wow, look at it go. It’s awesome.
P.S: freenode is filtering me out, I miss you guys a lot!
Stroll on over and visit murray
February 16, 2008
Say, can I email you a question about CSS inside PHP?
Thanks
Murray
Stroll on over and visit lockemonda
April 8, 2008
Hi:
I’m going to ask what is probably a stupid question. I usually work in Dreamweaver. What kind of document do I set up to start creating the slideshow? Should I choose a Javascript document? Or a PHP document?
Thanks!
Stroll on over and visit Don
June 4, 2008
First, I really like this slideshow. I already inputed the older version you had of this on the site I’m currently testing with.
I’m trying to use this new one you have up as the site currently has both jquery and prototype running and that’s 2 big scripts and now that you have this version using prototype I look forward to simplifying things. I’m stuck though as I’m unsure about some of the JS code. Also asbury appears to still use the old version you posted (though I may be wrong) so I’m not sure how to judge the new coding you have here against that other than visually.
The site is already connected to the mysql DB so I’m not so worried there. I guess its more I’m not sure how the rest of it has changed from the previous version.
I will admit that I haven’t used the php xx generate code function yet because I’m unclear as to how that actually works.
Any help would be great.
Pingbacks & Trackbacks
Leave a Reply