Tutorial - How to Build a Lightbox Portfolio in Drupal 7Tutorial - How to Build a Lightbox Portfolio in Drupal 7


Drupal is great for large community driven websites. However, it is likely that not every site you build will be a huge site with 50 modules and dozens of content types. Why learn 2 systems? You can build small sites with Drupal too. The nice thing about this is, because Drupal is so expandable, later on you can add in features without worrying about running into the limitations of your CMS.

Today we're going to build a small portfolio site. As a matter of fact we aren't going to even bother with multiple pages this time around. We're going to set up a View with our portfolio work in it. Each will open in a lightbox-style window. It will be a simple, no frills site made in Drupal 7.

Let's look at what we'll be building:

Required modules:
- Colorbox
- CTools
- Views

1. Setup

Go and install your modules. Colorbox requires some additional steps, just follow what it says on its configuration page. Colorbox has several features but the important one is that we "Enable Colorbox inline." This will allow us to use the module from coding in our TPL file using a link class. Set the style and options as you see fit, I have mine set to expand to 90% screen height and width.

The next thing we need to do is set up our content type. Let's call it "Project." I am going to disable pretty much all the options of these like displaying authoring info, comments, etc. I am going to attach 2 image fields to this. The first is going to be the cover image that shows up on the actual page. The second field is going to be the image or images we are displaying in the lightbox. For this second field make sure you have "Number of values" set to unlimited. This will allow you to add additional images as needed.

Also make sure you have all your field labels hidden. You can set your image restrictions as you need to on your own site. I'm not going to bother with that as I'll be uploading pre-processed images that are sized how I want them, but if you are operating a multi-user site you might want to make things easier on them by using image presets or restrictions on your upload fields. When all is said and done here are the fields for my content type:

Go ahead and create 4 or 5 pieces of content for testing and themeing.

Next lets create our View. I want to only show Project content in a grid format. Being a single-page site I will set it to display 30 items, which should be enough to display all my most recent work. Since we aren't bothering with other internal pages, I am going to also set the View to show full nodes.

Now we just need to double check our Format: Grid Settings and make sure we set "Number of columns" to 3. Everything else should be fine here, so let's save the View and move on.

2. The Colorbox Conundrum & Fixes

When I first thought of doing this tutorial I didn't think I would run into any issues. After all, this seems like the simplest implementation of a couple modules that you could get. However, I ran into one very large problem. Colorbox works really well out of the box if you are displaying some images, perhaps as thumbnails, which you then click on to see an enlarged version. This can be done all in Drupal UI settings with no coding involved. Colorbox likes to attach itself directly to a field, which makes sense. However, on this site we want a gallery to open up a set of image fields from a link which is on a completely different image field. Remember, we have a "cover" image which is displayed on the actual page and then several "project" images which is what the gallery will show. The problem is that the Colorboxed fields need to be invisible on that actual page but I still need to get the Colorbox link to show up. If Colorbox is attached to an invisible field then the link will then be invisible.

This is compounded by the fact that I want the ability to upload multiple images for my project. It gets a little hard to explain until you peel open the code, but here is an image which attempts to explain the issue.

For a while I couldn't figure out how I was going to get the link to correctly attach to my cover image but still have the image hidden within the Colorbox itself. After a lot of trial and error I found what works. I am not a programmer by any stretch, so there are probably better ways of doing this. But, as it happens some of the time, I found out how to get it working and that's good enough for me.

The first thing is to make a copy of node.tpl.php for our project content type (node--project.tpl.php). Next we need to note a few things.

How to print our cover image:



How to print our node id:



How to access the Array of project images:



How to get colorbox to pick up on a link and add it to a specific gallery:

<a href="[PATH TO IMAGE]" class="colorbox-inline" rel="[SOME UNIQUE ID]"></a>


Note that the "rel" attribute is important. Without it, every single image on the page would be added to the same gallery. We want to localize and limit each colorbox to a specific project. To do this, we will need a unique identifier. You may have guessed that we'll use the node id as the identifier.

So the things we need to accomplish are: 1. Cycle through the project image array. 2. If it hits the first image, then we'll print our cover image but LINK it to the project image using the colorbox class and use the node id as the gallery ID. 3. If there are more project images simply print a link to the image using the colorbox class and use the same gallery ID as before, but don't show the images. Here is the code:

  $i = 0;
  foreach($node->field_pimage['und'] as $image) {
    $pathtoimage = 'sites/default/files/' . $image['filename'];
    if($i == 0){
      print '<a href="' . $pathtoimage . '" class="colorbox-inline" rel="group-' . $node->nid . '">' . render($content['field_cimage']) . '</a>';
    else {
      print '<a href="' . $pathtoimage . '" class="colorbox-inline" rel="group-' . $node->nid . '"></a>';


Basically we are pulling the project images directly from the $node variable instead of using render($content['field_pimage']. If you had used the render function then you would get Drupal's formatted version, which doesn't work.

3. Styling

Now the easy part. Some basic CSS to get the styling we want. Just a note that I used Futura as my font of choice for this offline demo. Always make sure you have permission from the font publisher to embed fonts with @font-face on a live site.

@font-face { font-family:Futura; src:url(Futura.otf) format('opentype'); }
body { background:#edf2f4; color:#000000; font-family:Futura, Arial; margin:0; padding:0; }

.wrap { width:900px; margin:auto; }
#header .wrap { border-bottom:5px solid #a9c2cb; padding:75px 0 0 0; }

a:active { color:#000000; text-decoration:none; }
h2 { font-size:0.9em; text-transform:uppercase; }

.node-project { width:260px; height:195px; background:#ffffff; padding:10px; text-align:center; float:left; margin:30px 30px 0 0; box-shadow:0px 0px 3px rgba(0,0,0,0.1)}
.node-project .imagewindow { width:260px; height:160px;overflow:hidden; }


And that's it! I didn't want to turn this tutorial into a PHP codefest but sometimes there is no other way to get Drupal to behave the way you want. I spent a few hours figuring this out so hopefully somebody will benefit from my effort! Cheers.

Need a Custom Designed Theme?

If you need a custom designed theme for your business then our designers can work with you to create a unique concept that is consistent with your brand, clearly communicates your value proposition and helps you achieve your goals. >> Click here to contact us and let us know about your needs and we'll analyze and provide you with an estimate for designing and development your custom theme.