drupal recipes: building image galleries with jquery and flickr
DESCRIPTION
Covering Flickr, jQuery, and Drupal best practicesTRANSCRIPT
Drupal Recipes: Building Image Galleries
Presented by Benjamin Shell from WorkHabit
Covering Flickr, jQuery, and Drupal best practices
Start with a plan, and make Drupal work for you.
(don’t limit your imagination to what Drupal and existing modules do out of the box)
Planning
Remember that most* people don’t think like a relational database
*Disclaimer: I recently used database concepts in an unrelated discussion with my wife...
My Plan
• Show random image thumbnails on the sidebar
• Show a sliding image viewer on the right
User Experience:
Technical Requirements:
• Download images from Flickr
• Store images as nodes
• Use Views to build queries
Looking for Modules
• drupal.org
• drupalmodules.com
• CVS checkout of all contributions (grep search for keywords)
• Asking around (drupal.org, IRC, co-workers, conferences, etc.)
Implementation
There are essentially two types of Drupal modules:
1. Reusable “ingredients”
2. Complete solutions
(there’s some overlap of course)
My Approach
Use complete solutions if appropriate, BUT:
• DON’T spend too long finding them
• DON’T spend too long forcing them to work for you
• DON’T load 2000 lines of code if you’re only using 50
My ApproachUse common “ingredients” to build what you need.
Building the site
Input OutputStorage Retrieval
start here
Storage
Preferred: CCK + Imagefield
Not-recommended:
• Attach multiple image files directly to a node
• Use a non-CCK node type
StorageNew content type: Image
Data Input
• Millions of people already use it
• Easy to upload photos
Why import to Drupal?
• Theming flexibility
• Integration
• Security
Flickr Import
Plan:
• Automatically download new photos from Flickr
• Create Drupal nodes with attached images
• Import Flickr tags to taxonomy terms
Problem: I couldn’t find a module to do this
The closest I could find...
• Activity Stream
• FlickrRippr
• Emfield/Emfield Import
• Flickr module
Flickr API ModuleNEW M
ODULE
• Loads phpFlickr
• Stores the Flickr API key
• Can be used by other Flickr modules
Flickr API Module
Flickr Sync ModuleNEW M
ODULE
Downloads new Flickr photos to new Drupal nodes
Flickr Sync ModuleSettings page:
• Configure the content fields to use
• Specify batch importing settings
Flickr Sync Module
Every user has Flickr sync settings in their account settings
Flickr Sync Module
Performing an import manually(cron will keep things up-to-date, but the manual
process is nice for the impatient among us)
Thumbnails with a lightbox
Lightboxes
• Popular replacement for popup windows
• Comparison of “lightbox” type modules:http://www.drupal.org/node/266126
• I used jLightbox for it’s simplicity, but Lightbox 2 is another great module
Lightboxes
Lightboxes typically work using the “rel” attribute of a link:
<a href="images/image-1.jpg" rel="lightbox">image #1</a>
Using the Views UI
Filter for image nodes
Create a block
Lightboxes
function phptemplate_views_view_imagelist($view, $type, $nodes) { foreach ($nodes as $n) { $node = node_load($n->nid); $original_file = $node->field_image[0]['filepath']; $lightbox_file = imagecache_create_url('lightbox', $file); $img_tag = theme('imagecache', 'sidebar', $original_file); $link = l($img_tag, $lightbox_file, array( 'rel' => "lightbox[sidebar]"), NULL, NULL, FALSE, TRUE); $output .= '<div>' . $link . "</div>\n"; } return $output;}
Theming the view
No more hunting for a module to do exactly what you want -- with just a little view theming code the
possibilities are endless!
Building an image slider
Image Slider Module
NEW M
ODULE
Concept based on jQuery slideViewer 1.1
Building a new module can be easier than building a
complex theme
Building the image slider
• Setup a new View (just like before)
• Call the View from your module:$view = views_get_view('imageslider');
• Render the View from your module:$output = views_build_view('block', $view, array(), false);
• Theme the View (just like before)
Theming output
<div class="imageslider" style="width: 500px; height: 300px"> <ul style="width: 1500px"> <li><img src="..." alt="" title="" /></li> <li><img src="..." alt="" title="" /></li> <li><img src="..." alt="" title="" /></li> </ul></div>
Image slider CSSdiv.imageslider { overflow: hidden; position: relative;}
div.imageslider ul { list-style-type: none; position: relative; left: 0; top: 0;}
div.imageslider ul li { float: left;}
Change left value to move
the slider
Image slider JavaScript
• Get the image slider container
• Find out how many images there are
• Get the width of the images
• For each button click, move the slider to the proper position:(current image number) x (width of images)
Add module settings
Easy to add, easy to change
Tips for using CSS and JavaScript with Drupal
CSS and JavaScript
Load only where needed
Adding JavaScript
JavaScript should be unobtrusive
“Auto Attach”
// Global Killswitch
if (Drupal.jsEnabled) {
$(document).ready(Drupal.imageslider.autoAttach);
}
Runs your JavaScript if JavaScript is available and when everything is ready.
Use Drupal.settingsDrupal can output settings that can
be easily read in your JavaScript:
drupal_add_js(array( 'imageslider' => array( 'easeFunc' => variable_get('imageslider_ease_func', ''), 'easeTime' => variable_get('imageslider_ease_time', 750) ) ), 'setting');
In PHP:
In JavaScript:var easeTime = Drupal.settings.imageslider.eastTime;
Adding JavaScript
Follow good naming conventions
Naming Conventions
var box = getBox();
var newBoxHeight = 20;
box.setHeight(newBoxHeight);
Typically lower/upper , but just be consistent with Drupal and jQuery, or whatever JS libraries you work with.
Adding JavaScript
Use proper namespacing
JavaScript Namespacing
What’s wrong with this?
for (i = 0; i < 5; i++) {
// do something
}
JavaScript Namespacing
Using undefined variables clutters the global namespace!
JavaScript Namespacing
Define every variable!
for (var i = 0; i < 5; i++) {
// do something
}
JavaScript Namespacing
Namespace everything. Even JavaScript functions will overwrite each other:
function test() { alert('foo');}
function test() { alert('bar');}
test();
overwritten!
JavaScript Namespacing
var Drupal = Drupal || {};
Drupal.extend = function(obj) { ... }
Drupal.dimensions = function (el) { ... }
An example of proper namespacing:
Adding JavaScript
Learn to understand scope
Understanding Scope
function autoAttach() { var settings = { foo: 'bar' };
jQuery("a").mouseover(function() { alert(settings.foo); });}
Simple Example of jQuery scope:
Understanding Scope
function autoAttach() { var settings = { foo: 'bar' }; jQuery("a").mouseover(function() { onOver.call(settings); });}
function onOver() { // 'this' is the settings object alert(this.foo);}
Using a separate function for handlers
Understanding Scope
function autoAttach() { var settings = { foo: 'bar' }; jQuery("a").mouseover(function(evt) { onOver.call(settings, evt); });}
function onOver(evt) { // 'this' is the settings object alert(this.foo);}
Passing additional variables with ‘call’
Tools
• Firefox with Firebug
• Aptana Studio
• Opera Developer Tools
• IE Developer Toolbar
• Windows (for testing)
New Drupal.org Releases
• http://drupal.org/project/flickrapi
• http://drupal.org/project/flickrsync
• http://drupal.org/project/imageslider