[Drupal] How to create default Slideshow for Drupal 7 themes?

By | 12th Jun 2013 | 7 min read

In this article we will be explaining a small feature we implemented in our Drupal themes, its called Slideshow. Will be explaining how to create and implement Slideshow feature for your theme. Before we start, hope you all know about PHP templates and Java Script, because these two play a major role in implementing the slide show.

Will start with preprocess function themename_preprocess_page() and its written in template.php file, its mainly used to keep .tpl.php files tidy and for generating variables before they are merged with the markup inside .tpl.php files. In this function will check whether theme is called for the first time. Its done by checking value of the variable theme_ themename_first_install is True or False. If TRUE then will call the function _themename_install() and returns the value False for the variable theme_themename_first_install. So next time when theme is enabled it won't call the function _themename_install() but get the value from banners directly. Now a banner is called using function themename_show_banners(). In preprocess_page function it also checks whether the user is at front page if yes will call the js file slide.js

See the code below.

/*template.php*/
function themename_preprocess_page(&$vars) {
	
  //Check if theme is called first and install banners.
  if (variable_get('theme_themename_first_install', TRUE)) {
    include_once('theme-settings.php');
    _themename_install();
  }
  //to print the banners
  $banners = themename_show_banners();
  $vars['banner'] = $banners;
  if(drupal_is_front_page()){
    drupal_add_js(path_to_theme() .'/js/slide.js', 'file');
  }
}
/**
 *
 * @return 
 *    html markup to show banners
 */
function themename_show_banners() {
  $banners = black_lagoon_get_banners(FALSE);
  $output = ' <div id="orbitDemo">';
  for ($i=0; $i<count($banners); $i++) {
    if (empty($banners[$i]['image_title'])) {
      $output .=  l('<img class="img-sl" src="' . file_create_url($banners[$i]['image_path']) . '" alt="slider image' . $i . '" />', $banners[$i]['image_url'],array('html' => TRUE));
    }
    else {
   $output .= '<div data-caption="#caption' . $i . '">' . l('<img class="img-sl" src="' . file_create_url($banners[$i]['image_path']) . '" alt="slider image' . $i . '" />', $banners[$i]['image_url'], array('html' => TRUE)) . '</div>';
   }
  }  
  $output .= '</div>';
  for ($i=0; $i<count($banners); $i++) {
    $output .= '<span class="orbit-caption" id="caption' . $i . '">' . $banners[$i]['image_title']  . '</span>';
  }
  return $output;
}

/**
 * Get banner settings.
 *
 * @param  $all
 *    Return all banners or only active.
 *
 * @return 
 *    Settings information
 */
function themename_get_banners($all = TRUE) {
  // Get all banners
  $banners = variable_get('theme_black_lagoon_banner_settings', array());
  $delay = theme_get_setting('banner_delay');
  $animation_speed = theme_get_setting('animation_speed');
  $caption_animation_speed = theme_get_setting('caption_animation_speed');
  drupal_add_js('var delay = "' . $delay . '"', 'inline');
  drupal_add_js('var animation_speed = "' . $animation_speed . '"', 'inline');
  drupal_add_js('var caption_animation_speed  = "'. $caption_animation_speed . '"', 'inline');
  // Create list of banner to return
  $banners_value = array();
  foreach ($banners as $banner) {  
    $banner['weight'] = $banner['image_weight'];    
    $banners_value[] = $banner;   
  }

  // Sort image by weight
  usort($banners_value, 'drupal_sort_weight');

  return $banners_value;
}

/**
 * Set banner settings.
 *
 * @param  $value
 *    Settings to save
 */
function themename_set_banners($value) {
  variable_set('theme_mytheme_banner_settings', $value);
}

In function _themename_install() will call the default banner images, the path for default images are defined in .info file

/*theme-settings.php*/
function _themename_install() {
  // Default data
  $file = new stdClass;
  $banners = array();
  // Source base for images
  $src_base_path = drupal_get_path('theme', 'themename');
  $default_banners = theme_get_setting('default_banners');
  // Put all image as banners
  foreach ($default_banners as $i => $data) {
    $file->uri = $src_base_path . '/' . $data['image_path'];
    $file->filename = $file->uri;
    $banner = _themename_save_image($file);
    unset($data['image_path']);
    $banner = array_merge($banner, $data);
    $banners[$i] = $banner;
  }
  // Save banner data
  themename_set_banners($banners);
  // Flag theme is installed
  variable_set('theme_themename_first_install', FALSE);
}


/*themename.info*/

settings[default_banners][1][image_path]      = images/slideshows/1.jpg
settings[default_banners][1][image_url]       = Url for image 1

settings[default_banners][2][image_path]      = images/slideshows/2.jpg
settings[default_banners][2][image_url]       = Url for image 2

settings[default_banners][3][image_path]      = images/slideshows/3.jpg
settings[default_banners][3][image_url]       = Url for image 3

Now to upload new banner/slideshow images first we have to alter theme settings form and provide a provision to upload new images. Its done is as follows

/*theme-settings.php*/

function themename_form_system_theme_settings_alter(&$form, $form_state) {
  $form['banner'] = array(
    '#type' => 'fieldset',
    '#title' => t('Banner managment [Upload images with dimension 960*502]'),
    '#weight' => 1,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
  ); 

  // Image upload section ======================================================
  $banners = themename_get_banners();
  
  $form['banner']['images'] = array(
    '#type' => 'vertical_tabs',
    '#title' => t('Banner images'),
    '#weight' => 2,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#tree' => TRUE,
  );

  $i = 0;
  foreach ($banners as $image_data) {
    $form['banner']['images'][$i] = array(
      '#type' => 'fieldset',
      '#title' => t('Image !number', array('!number' => $i + 1)),
      '#weight' => $i,
      '#collapsible' => TRUE,
      '#collapsed' => FALSE,
      '#tree' => TRUE,
      // Add image config form to $form
      'image' => _themename_banner_form($image_data),
    );

    $i++;
  }

  $form['banner']['image_upload'] = array(
    '#type' => 'file',
    '#title' => t('Upload a new banner'),
    '#weight' => $i,
  );

  $form['#submit'][]   = 'themename_settings_submit';
  return $form;
}

In this we established a fieldset element and then places a file element to upload the new image. To view previously uploaded images we call the function themename_get_banners() and store it to variable $banners and to display these images in theme settings page we call the form _themename_banner_form(). in this form there will be able to provide a link to images and also able to delete the image.

See the form below:

function _themename_banner_form($image_data) {
  $img_form = array();

  // Image preview
  $img_form['image_preview'] = array(
      '#markup' => theme('image', array('path' => $image_data['image_thumb'])),
  );

  // Image path
  $img_form['image_path'] = array(
      '#type' => 'hidden',
      '#value' => $image_data['image_path'],
  );

  // Thumbnail path
  $img_form['image_thumb'] = array(
      '#type' => 'hidden',
      '#value' => $image_data['image_thumb'],
  );


  // Link url
  $img_form['image_url'] = array(
      '#type' => 'textfield',
      '#title' => t('Url'),
      '#default_value' => $image_data['image_url'],
  );

  // Delete image
  $img_form['image_delete'] = array(
      '#type' => 'checkbox',
      '#title' => t('Delete image.'),
      '#default_value' => FALSE,
  );

  return $img_form;
}

Now in form _themename_banner_form() there is a textfield to enter the url and checkbox to delete images.

Click save configuration to upload the images. The image saving is done by submit function themename_settings_submit(). In this first it will check whether $img_form['image_delete'] checkbox is checked or not if yes delete the corresponding images. Now to save image first it will check for a new upload file using function file_save_upload('image_upload') and if its true then will call save function _themename_save_image(). In this first it will check whether any directory is created for image saving, if not will create two folders one for main image and one for thumbnail image. Here saved images are stored to variable $banner and its called in tpl file page--front.tpl.php.

/**
 * Save settings data.
 */
function themename_settings_submit($form, &$form_state) {
  $settings = array();

  // Update image field
  foreach ($form_state['input']['images'] as $image) {
    if (is_array($image)) {
      $image = $image['image'];

      if ($image['image_delete']) {
        // Delete banner file
        file_unmanaged_delete($image['image_path']);
        // Delete banner thumbnail file
        file_unmanaged_delete($image['image_thumb']);
      } else {
        // Update image
        $settings[] = $image;
      }
    }
  }

  // Check for a new uploaded file, and use that if available.
  if ($file = file_save_upload('image_upload')) {
    $file->status = FILE_STATUS_PERMANENT;
    if ($image = _themename_save_image($file)) {
      // Put new image into settings
      $settings[] = $image;
    }
  }

  // Save settings
  themename_set_banners($settings);
}

/**
 * Save file uploaded by user and generate setting to save.
 *
 * @param  $file
 *    File uploaded from user
 *
 * @param  $banner_folder
 *    Folder where save image
 *
 * @param  $banner_thumb_folder
 *    Folder where save image thumbnail
 *
 * @return 
 *    Array with file data.
 *    FALSE on error.
 */
function _themename_save_image($file, $banner_folder = 'public://themename-banner/', $banner_thumb_folder = 'public://themename-banner/thumb/') {
  // Check directory and create it (if not exist)
  _themename_check_dir($banner_folder);
  _themename_check_dir($banner_thumb_folder);

  $parts = pathinfo($file->filename);
  $destination = $banner_folder . $parts['basename'];
  $setting = array();

  $file->status = FILE_STATUS_PERMANENT;

  // Copy temporary image into banner folder
  if ($img = file_copy($file, $destination, FILE_EXISTS_REPLACE)) {
    // Generate image thumb
    $image = image_load($destination);
    $small_img = image_scale($image, 300, 100);
    $image->source = $banner_thumb_folder . $parts['basename'];
    image_save($image);

    // Set image info
    $setting['image_path'] = $destination;
    $setting['image_thumb'] = $image->source;
    $setting['image_url'] = '';
    $setting['image_visibility'] = '*';
    return $setting;
  }

  return FALSE;
}

/**
 * Check if folder is available or create it.
 *
 * @param  $dir
 *    Folder to check
 */
function _themename_check_dir($dir) {
  // Normalize directory name
  $dir = file_stream_wrapper_uri_normalize($dir);

  // Create directory (if not exist)
  file_prepare_directory($dir,  FILE_CREATE_DIRECTORY);
}


/*page--front.tpl.php*/


  

Now comes the css file


/*layout.css*/
div.slider-nav {
    display: block }

div.slider-nav span {
    width: 39px;
    height: 50px;
    text-indent: -9999px;
    position: absolute;
    z-index: 10;
    top: 50%;
    margin-top: -25px;
    cursor: pointer; }

div.slider-nav span.right {
    background: url(../images/orbit/right-arrow.png) no-repeat;
    right: 0px; 
    display: none;
    height:59px;
    right:20px;
    margin-right:9px;
    }

div.slider-nav span.left {
    background: url(../images/orbit/left-arrow.png) no-repeat;
    height:159px;
    display: none; }

Now come the js file


/*slide.js*/
jQuery(document).ready(function ($) {
    $(window).load(function() {
    $('#orbitDemo').orbit({
         animation: 'fade',
         bullets: true,
     });
     });

   
    $('.slider').mouseover(function() {$('.slider-nav span.right').show()});
    $('.slider').mouseover(function() {$('.slider-nav span.left').show()});
    $('.slider-nav span.right').mouseover(function() {$('.slider-nav span.right').show()});
    $('.slider-nav span.left').mouseover(function() {$('.slider-nav span.left').show()});
    $('.slider').mouseleave(function() {$('.slider-nav span.right').hide()});
    $('.slider').mouseleave(function() {$('.slider-nav span.left').hide()});    
     });

We have uploaded this themes in drupal.org. You can refer following themes for complete code.