by August 16, 2006

How to build Flickr in Drupal

(Note: If you don't already have it (for shame!), download the newest spanky copy of Drupal 4.7.)

f="">Flickr clone... in Drupal! This recipe will show you how!

Appetizer: Initial Setup


(Note: If you don't already have it (for shame!), download the newest spanky copy of Drupal 4.7.)

First, install and enable the modules below at administer >> modules:

  • Image
  • Image Exact Sizes (this module isn't strictly necessary, but it makes all the previews uniform which looks a bit nicer)
  • Views (remember to enable both "views" and "views_ui" modules)

Also make sure the core taxonomy and comment modules are enabled.

Next, configure access permissions under administer >> access control so that authenticated users have the ability to create and edit their own images, and both anonymous and authenticated users can view original images.


Next, we need to use Drupal's spiffy taxonomy system to create a "free tagging" vocabulary for images.

  1. Head to administer >> categories and click add vocabulary.
  2. Enter a Vocabulary name of something really original like, Tags.
  3. Under Types, check off image.
  4. Check the Free tagging checkbox.
  5. Submit the vocabluary.

User pictures

The last thing we'll do settings-wise is enable user "avatars" that get displayed on peoples' posts and comments, for that "oh-so-community site" feel. ;)

Go to administer >> settings >> user and set Picture support to Enabled.

Then, under administer >> themes >> configure, check off the User pictures in posts and User pictures in comments.

To add an avatar to your user, click my account, then edit, then Upload a picture. This avatar will then be displayed next to all of your posts and comments.

Main Course: Fun with Views

Now, for the "main course," Views. We'll need two Views: one to give us a list of images by term, so we can replicate this view: and one to give us a list of images by user, so we can replicate this view:

Head to administer >> views and click add to get started.

  1. For a Name, enter something like photos_tags.
  2. Give Access to both anonymous and authenticated users.
  3. Give it a good Description, like Bring up a list of photos by tag.
  4. Expand the Page fieldset.
  5. Check Provide page view.
  6. Give it a URL of photos/tags. This is the URL we'll enter to bring up this view. (Note: No forward or trailing slash!)
  7. Under View Type, select Teaser List. This will show the "preview" size images.
  8. Enter a Title of Photos tagged with %1. %1?! What the..?! Just hang in there, we'll get to that in a minute. ;)
  9. Expand the Arguments fieldset.
  10. Under Add Arugment, select Taxonomy: Term Name and click Add Argument. What does this do? It allows us to specify which stuff we want in the URL. So photos/tags/superman will bring up a list of all the images that were tagged "superman." And remember that %1 in the title? That gets replaced with "superman" too, so it becomes "Photos tagged with superman."
  11. Expand the Filters fieldset.
  12. From the Add Flter drop-down, select Node: Type and click Add Filter.
  13. Select Is One Of and Image. This will ensure that only image nodes and not other kinds are displayed in the listing.
  14. Expand the Sort Criteria fieldset.
  15. Under Add criteria, choose Node: Created Time and Add Criteria.
  16. Then, select Descending Order, so the newest images are shown first.
  17. Finally, click Save to save your View.

The "photos by user" View is basically exactly the same, so we can simply clone it. Change the following:

  1. Name: photos_user
  2. Description: Bring up a list of photos by user.
  3. URL: photos/user
  4. Title: %1's photos
  5. Arguments: Click the trash can next to Taxonoy: Term Name and replace it with User: UID is Author.

To test, create a few sample images from create content >> image with various tags. Notice how typing in will bring you a list of photos tagged as 'foo' and will bring up a list of all photos created by the first user.

Dessert: Theming-o-rama!

One nice feature that Flickr has is it allows you to click a person's nickname to be taken to a listing of all their photos, and click a tag name to be taken to a listing of all photos by that tag. However, by default Drupal links the author name to their user profile, and taxonomy terms to a listing of all content with that term, which may or may not be images. How can we deal with this?

The answer is, with a sprinkle of custom theming.

The file driving the default display of all nodes (linking taxonomy terms to taxonomy/term/# and linking the author name to their user profile) is node.tpl.php in your theme directory. And this works just fine for "normal" nodes like stories and pages. But we want to do something a little different for images.

First, copy your theme's node.tpl.php file to a file called node-image.tpl.php. Here's the one from Bluemarine:

  <div class="node<?php if ($sticky) { print " sticky"; } ?><?php if (!$status) { print " node-unpublished"; } ?>">
    <?php if ($picture) {
      print $picture;
    <?php if ($page == 0) { ?><h2 class="title"><a href="<?php print $node_url?>"><?php print $title?></a></h2><?php }; ?>
    <span class="submitted"><?php print $submitted?></span>
    <span class="taxonomy"><?php print $terms?></span>
    <div class="content"><?php print $content?></div>
    <?php if ($links) { ?><div class="links">» <?php print $links?></div><?php }; ?>

There are two things we want to change here:

  1. $submitted, which displays the "Submitted by [username] at [datetime]" on each node.
  2. $terms, which is a list of terms linking back to taxonomy/term/[term-id].

So, let's replace the two lines that contain $submitted and $terms with:

  <code class="language-php">
      // Load author details
      $author = user_load(array('uid' => $node->uid));
    <span class="submitted">From
  <code class="language-php">
      // We override the default user link here, because we want the link
      // to point to the user's gallery, rather than their account page.
      print l($author->name, "photo/user/$node->uid");
  <code class="language-php">
      // Let's format a nice date without the time (Aug 16, 2006)
      print format_date($node->created, 'custom', 'M d, Y'); 
    <span class="taxonomy">Tags: 
  <code class="language-php">
      // Rather than simply print $terms, we want to control where
      // the taxonomy links lead; therefore, we'll compile the list
      // manually.
      $term_links = array();
      foreach ($node->taxonomy as $term) {
        $term_links[] = l($term->name, "photo/tags/$term->name");
      // "implode" makes the terms comma-separated
      print implode(', ', $term_links);

Now, on each image node, the author name will link back to photos/user/[uid], and the term names will each link back to /photos/tags/[tag_name].

In case you'd like to try this out on your own site, attached is a .zip file containing three files:

  • photos_tags.view.txt: An export of the photos_tags view. Import it from administer >> views >> import.
  • photos_user.view.txt: An export of the photos_user view. Ditto.
  • node-image.tpl.php: The node-image.tpl.php file, which needs to go in your theme directory (ex: themes/bluemarine).