Search Google Appliance


FAQs

How do I add an image gallery (image rotator) to my Drupal site?

As a site manager, you won't be installing any modules to add functionality to your site. The template and theming system does, however, give site managers access to add CSS and Javascript to their sites. The workflow outlined below requires three things:

  1. Site Manager access to your site
  2. A basic understanding of how cascading style sheets (CSS) work.
  3. A basic understanding of how Javascript (JS) and jQuery works.

You need not be an expert in the coding techniques; it is even less necessary to understand the inner workings of how the elements we use work. It is only necessary to understand how to use the plugins, which is a nice abstraction for the everyday user. The widget we produce is built upon Malsup's JQuery Cycle Plugin, which we will refer to later. Note that this plugin is very flexible, and we show two ways to use the same plugin to produce different results. After working through one of the methods outlined below, it should be fairly obvious how to tweak your slideshow's behavior.

This tutorial provides two variants of an image gallery, and this is not the only way to make it work, but this method produces a sleek result. A similar workflow would work for other jQuery plugins.

For more background information, see the following links:

Finally, you'll need to do some basic HTML coding to make it work. We hope to deploy a feature module to accomplish the same thing in a point-n-click way, but for now this is how you do it. You also may want to check if this method could work for you; it's a different way to do the same thing using external services.

Image Gallery Setup

The output you see on the page looks something like this when you are done with the tutorial:

PSU Drupal 7 Image Gallery Widget

 

The setup consists of the following workflow:

  1. Upload the images you wish to use to the media library
  2. Create specially-formatted HTML that will work with the Cycle plugin
  3. Add some site-specific javascript to your site in theme settings
  4. Add some site-specific CSS to your site in theme settings
  5. Validate results

The following numbered sections detail each step. Onward.

1. Uplaod the images 

Head to your site, log in, [1] click on Content on the admin toolbar, [2] then on Media :

Portland State First Stop Portland | Content

 

To keep things easy to find, create a folder to contain the images for your gallery. On the media screen, click the Folder Management button. Then on the following screen, [1] title the folder something your remember, [2] make the parent directory Media Root, then [3] click Save & Continue.

Adding folders to media library

 

You are retuned to the Add folder interface, with a message in the help area that the folder was successfully created (note that the settings fields have been reset to allow you to create another folder, which we aren't doing). Now, click the Media link in the admin breadcrumb area:

Adding folders to media library.

 

You are returned to the Media browsing interface. Click the Media breadcrumb element (as shown above), to return to the Media screen. On that screen, click Add files:

Add files to media library

 

On the next screen, [1] change to the folder you just created, [2] then click Add files. You can multi-select in the browsing dialog to upload multiple. When done, [3] click Start Upload.

Portland State First Stop Portland | Content

 

Go through the standard dialog of browsing your local system for images. (You can also drag-n-drop onto the upload dialog instead of clicking Add files to accomplish multiple-file upload.) All the images you upload should be the same size for the best results (resize your images before you upload if necessary, you'll see why later in this tutorial). 

Next, you're returned to the Media interface at Media Root. Click on the folder you just uploaded to (the example in the image below is Cycle Images):

Check your uploaded images

 

There you should see your uploaded images. Now that we have the images available, we proceed to setting up the page in question with the proper HTML to allow the Javascript and CSS to work together to produce the gallery.

[ back to steps ]

2. Set up the HTML

The first thing we need to do is get the source (big) images on the page you want the rotator, so browse to the page in the normal way--make sure you are logged in--then click the Edit tab. The template choice isn't really relevant to this discussion, but for the purposes of this example, we're placing the gallery before any text content in the page, so X-Level makes the most sense. Feel free to make your own choice:

Choosing templates

 

Further down the page, you see the WYSIWYG editor. Click into the area of the page that you want to insert the image rotator, and click the Insert Media button:

Inserting media into a page

 

You are presented with the Media insertion dialog box. First, [1] click on the Library Plus tab, then [2] click on the folder you created, and [3] click on an image, then [4] click Continue with selection:

Insert media from library folder

 

On the next screen of the dialog, [1] change the format to original, [2] add a description (this will serve as the accessible alt text), [3] click Submit.

Inserting Media and alt text from library

 

You are returned to the editor where you see your image in the page. Don't worry about the size at this point, as the javascript will automatically create thumbnails and set everything up. Back in the editor, place your cursor after the image. Press Return on your keyboard to go to a new line and repeat the image insertion process until you have placed all the images. Your editor should look something like the following:

Large images for rotation inserted sequentially

 

You should be able to scroll up and down and see your images one after the other. Save the page as we are at a good pause point. Take a look at what you have at this point: just all the big images going down the page. Make sure you have the proper images, and that they are approximately the same size (there is another way to make consistent image sizes using Styles in Drupal 7, but that's another tutorial).

Now, go back to editing your page (click the Edit tab), then click the HTML button on the editor:

Edit HTML in editor

 

This opens a popup with the HTML. The part we are interested in is shown below:

MEDIA markup in HTML mode

 

The snippets are JSON (javascript object notation) arrays specifying each image in the media library. It's not important to know what it means, it's just important to know that each snippet represents an image. Now, we need to change the HTML structure to something that our preferred jQuery library can use.

Before we edit, the expected HTML structure is the following:

<ul class="image-rotator">
<li class="slide">
<div class="media">[media markup for image]</div>
<div class="media-info">
</li> 
<div class="media-teaser">[CAPTION HERE]</div>
<li class="slide">...</li>
<li class="slide">...</li>
</ul>
<div class="rotator-nav">&nbsp;</div>  

So in HTML mode change the markup we denoted earlier to look like this:

<ul class="image-rotator">

<li class="slide">
<div class="media">[media markup]</div>
<div class="media-info">
<div class="media-teaser">Portland's Pearl District: Go by Streetcar</div>
</div></li>

<li class="slide">
<div class="media">[media markup]</div>
<div class="media-info">
<div class="media-teaser">Hard-hat tour, Skanska USA</div>
</div></li>

<li class="slide">
<div class="media">[media markup]</div>
<div class="media-info">
<div class="media-teaser">Public Art and Transit Development: Jamison Square</div>
</div></li>

<li class="slide">
<div class="media">[media markup]</div>
<div class="media-info">
<div class="media-teaser">Sustainable Transit Oriented Design and Local Economic Development Discussion at GBD Architecture</div>
</div></li>

<li class="slide">
<div class="media">[media markup]</div>
<div class="media-info"><div class="media-teaser">OHSU Tram to South Waterfront Redevelopment</div>
</div></li>

</ul>
<div class="rotator-nav">&nbsp;</div> 

Keep in mind that [media markup] is each snippet from inserting your media in a previous step. Also, the class attributes for the <ul> and <li>'s should be identical, as shown above. You need to manually code the structure, but cut and paste (in HTML mode) the media markup into the .media div. Click the Update button on the editor, and you will be returned to normal edit mode. You should see a bulleted list of image/caption pairs:

Rotator prep: bulleted list of image/caption pairs

 

If so, save your page, and you should see the same thing in view mode as you saw in edit mode: a bulleted list of image/caption pairs. If not, take a closer look at your HTML structure to be sure there's no malformed tags or structure.

That finishes the HTML setup. Lets continue to the Javascript setup.

back to steps ]

3. Set up the Javascript

In Drupal 7, the core theming system makes JQuery 1.4 available to all pages. What we need to add is the plugin that creates the rotator, and a top-level manipulator script to tell JQuery where and what to do with the markup intended to serve as the image rotator. We start by adding site-specific Javascript to your site in theme settings. This is where needing site manager permissions comes in. Content managers cannot add site-specific CSS or JS to their theme. If you don't know if you are a site manager, then you likely don't have that access.

On the admin toolbar, click [1] Theme Settings, then [2] click the Advanced theme settings to expand the fieldset.

Site Config: advanced theme settings

 

When the fieldset expands, you'll see two fields: one for javascript and one for CSS. It is important to not confuse the two fields. What you need to do is copy the following javascript snippet:

$(document).ready( function() {
// attach cycle plugin and snap together the rotator
$.getScript('/sites/default/files/jquery.cycle.all.min.js',
  function() {  // callback executes after cycle is attached at global scope
    $('ul.image-rotator').cycle({  // any cycler-containing page
      fx:"fade", 
      speed:1000, 
      timeout:0, 
      pager:".rotator-nav",
      pagerAnchorBuilder: function(idx, slide) { 
        var _navItem = document.createElement('li');
        var _navLink = document.createElement('a');
        var _navThumb = document.createElement('img');
        var _imgURL = $(slide).find('.media-image').attr('src');      
        _navThumb.src = _imgURL;
        _navThumb.width = "50";
        _navThumb.height = "50";
        _navLink.appendChild(_navThumb);
        _navLink.href='#';
        _navItem.appendChild(_navLink);
        return _navItem;
      }
    });
  }
);
});

Then, [1] paste it into the Additional JavaScript field, and [2] click save:

Image Gallery site-specific Javascript

 

Once this javascript becomes part of the theme Javascript, this is what happens on each page load:

  1. After the document (DOM: document object model) has been loaded, call the getScript function to add the cycle rotator library to the available JS on the page. Think of it as a stack of Javascript: Cycle on top of JQuery on top of Javascript.
  2. If a unordered list (<ul> with the class of "image-rotator"
  3. is found, instantiate a cycler with the specified parameters utilizing the content panels defined by the child list elements (<li class="slide">(see Cycle Option Reference for more options).
  4. Look at each list item and find the image. Create a thumbnail for each, then append it to the navigation div.
  5. Snap the widget together and provide clickable functionality with the plugin.

 

If no cycler div is found the script stops and your browser continues normally without doing anything. We're almost there, but there's not yet anything to see; we still need the CSS.

back to step list  ]

4. Create site-specific CSS for the rotator.

Copy the following code snippet:

.image-rotator {
  display:block;  overflow:hidden;
  margin:0;
  width:680px;  /* full page width */
  height:408px; /* image + caption height */
  padding:0;
}
.image-rotator .slide {
  width:680px;
  list-style:none;
}

.slide .media-info {
  width:680px;
}
.media-info .media-teaser {
  padding-top:10px;
  float:left;
  padding-right:8px;
  display:inline;
}
ul.rotator-nav {
  float:left;
  display:block;
  margin:0; padding:0;
  width:680px;
}
.rotator-nav li {
  float:left;
  margin:5px;
  padding:0;
  list-style:none
}
.rotator-nav img {
  border:1px solid #fff;
  padding:2px;
}
.rotator-nav a.activeSlide img {
  border:1px solid #ddd;
  background:#efefef;
  color:#6a7f10;
  padding:2px;
}
.rotator-nav a:hover {
  border-bottom:0 none;
}
.rotator-nav a:hover img {
  background-color:#777;
}

 

And paste it into the advanced theme settings Additional CSS field, and click save, like so:

rotator: site specific CSS for cycler

 

Note that in the screen shot, you can't see the whole field. Make sure you scroll up and down in the field to be sure you have everything pasted.

Explaining each CSS hook is outside the scope of this tutorial, but just know, for now, that we matched some of the styling to the image sizing. Feel free to experiment with the CSS. The Javascript is less forgiving, however. Both the JS and the CSS work together to create the rotator widget.

back up to step list ]

5. Validate

Go back to your page with the rotator, and you should now see something like this:

PSU Drupal 7 Image Gallery Widget

 

Again, you can alter your layout a bit if you want. The size of the thumbnails are set in the javascript. You want to make sure you pick a size--this example went with 50 by 50--that makes sense for the page. Also, note that the slide area has sizing controlled by CSS, so you want to do the math and set the height and width according to your images and keeping in mind the width of the content area (680 pixels).

Troubleshooting

If you run into problems, you first want to make sure that your HTML structure matches--exactly--the structure we covered in the HTML setup portion. If you misplace a class specifier, or the HTML is malformed, it may not work. Next, if you are confident that the HTML structure is sound, be sure the CSS and JS snippets you pasted are matching and there are no missed symbols; malforming either of these snippets can also cause issues.

If you still encounter issues, drop a line to ucomm-support@pdx.edu, and we can help walk through the troubleshooting process.

back up to step list ]

Variant: Text-based Image Paging

Those of you familiar with the PSU homepage in Drupal 6 days will remember what the rotator then looked like:

Portland State University | Home (drupal6)

 

With just a few changes to the configuration of the JS and CSS in advanced theme settings, you can implement this type of solution with the same resources. The workflow is exactly the same, but we change the HTML slightly and what we put into the JS and CSS fields are tweaked.

1. HTML Structure

Note the addition of a tab below the image. This is accomplished by adding some HTML to each slide (note the div class="more-tab" in the snippet below):

<li class="slide">
<div class="media">
<a href="/insidepsu/success-initiative"><img width="560" height="315" alt="Success Initiative" src="/sites/default/files/media_assets/feature_slides/homepage_success.jpg"></a>
<div class="media-info">
<div class="more-tab">
<a href="/insidepsu/success-initiative">About</a>
</div>
<div class="media-teaser">
<a href="/insidepsu/success-initiative">Clearing the path from cradle to career!</a>
</div></div>
</li>

We account for the additional HTML in the CSS.

2. Site-specific CSS for text-based paging

The CSS to use in theme settings is the following:

.image-rotator { 
  display:block;
  overflow:hidden;
  margin:0;
  padding:0;
  width:560px;
}
.image-rotator .slide{
  list-style:none;
  width:560px;
  height:
}
.slide .media {
  width:560px;
  height:315px;
}
.media a:hover {
  border:0;
}
.slide .media-info {
  width:560px;
}
.media-info .media-teaser {
  padding-top:10px;
  float:right;
  padding-right:8px;
  display:inline;
}
.media-info .more-tab {
  background:#6a7f10;
  height:15px;
  float:right;
  padding:10px 15px;
  border-bottom-right-radius:6px;
  -moz-border-radius-bottomright:6px;
  -webkit-border-bottom-right-radius:6px;
  border-bottom-left-radius:6px;
  -moz-border-radius-bottomleft:6px;
  -webkit-border-bottom-left-radius:6px
}
.more-tab a {
  color:#fff;
  text-decoration:none;
  letter-spacing:1px;
  padding-right:13px;
  text-transform:uppercase;
  background-image:url(/sites/default/files/media_assets/feature_slides/more-arrow_white-trans.png);
  background-position:right 1px;
  background-repeat:no-repeat
}
.more-tab a:hover {
  color:#a8b400;
  text-decoration:none;
  border:0
}
ul.rotator-nav {
  float:left;
  display:block;
  margin:0; padding:0;
  width:560px;
}
.rotator-nav li {
  float:left;
  margin:5px;
  padding:0;
  list-style:none
}
.rotator-nav li a {
  padding:5px 7px 2px 7px;
  border:1px solid #fff;
  color:#000;
  float:left;
  text-decoration:none;
  font-family:Frutiger,"Frutiger Linotype",Univers,Calibri,"Gill Sans","Gill Sans MT","Myriad Pro",Myriad,"DejaVu Sans Condensed","Liberation Sans","Nimbus Sans L",Tahoma,Geneva,"Helvetica Neue",Helvetica,Arial,sans serif
}
.rotator-nav li a.activeSlide {
  border:1px solid #ddd;
  background:#efefef;
  color:#6a7f10
}
.rotator-nav li a:hover{
  color:#a8b400
}

Note how the structure of the CSS is largely the same, we just tweaked some dimensions and accounted for the extra HTML. Now you just would need the Javascript.

3. Site-specific JS for text-based paging

Here's the snippet you need:

$(document).ready( function() {
$.getScript('/sites/default/files/jquery.cycle.all.min.js',
  function() {  // callback executes after cycle is attached at global scope
    $('#feature-rotator').cycle({  // any cycler-containing page
      fx:"fade", 
      speed:1000, 
      timeout:0, 
      pager:"#rotator-nav",
      pagerAnchorBuilder: function(idx, slide) { 
        var _navItem = document.createElement('li');
        var _navLink = document.createElement('a');
        _navLink.href='#';
        _navLink.innerHTML = idx+1;
        _navItem.appendChild(_navLink);
        console.log(_navItem);
        return _navItem;
      }
    });
  }
);
});

Note that we just change the pager function to create numbers instead of display thumbnails. Then we styled the numbers with the CSS.

Conclusion

From this discussion, it can be seen that the plugin is flexible enough to implement different behaviors for rotators with the same underlying resources--it's all about how you "call" the rotator (JS) and style the output (CSS). Take a look at the difference between the thumbnail and text versions JS, and it's just the pager builder function that changes. Likewise, we just accounted for the added HTML in the CSS.

If you become familiar jQuery and CSS, you can implement other widgets/plugins using the same workflow.

Questions or issues should be directed to ucomm-support@pdx.edu.