Skip to main content

Drupal Views Slideshow: Prevent widowed items on slides.

We have a site that is running the views slideshow module to display advertisement images. Recently a client asked us to prevent these advertisements from displaying only one item on the screen. In order to do this I began dissecting the views slideshow module code and I came across the template_preprocess_views_slideshow_cycle_main_frame() function. This function takes care of rendering the rows.

The solution I came up with is in this section of code:

  1.   // Find how many slides we need to deal with.
  2.   $num_slides = ceil((count($rows) / $items_per_slide));
  3.  
  4.   // Create a temporary array to store the column counts.
  5.   $columns_temp = array();
  6.   $columns_temp = array_fill(0, $num_slides, '');
  7.  
  8.   // Loop through the rows and split them into equal columns.
  9.   foreach ($rows as $count => $item) {
  10.     $columns_temp[$count % $num_slides][] = $item;  
  11.   }
  12.  
  13.   $items = array();
  14.   $slideshow_count = 0;
  15.   $rendered_rows = '';
  16.   // Loop through the rows again for output.
  17.   foreach($rows as $count => $item) {
  18.     $items[] = $item;
  19.     // If the item count is equal to the count of our column_temp array, theme the row and increment our column counter.
  20.     if(count($items) == count($columns_temp[$slideshow_count])){
  21.       $rendered_rows .= theme('views_slideshow_cycle_main_frame_row', array('vss_id' => $vss_id, 'items' => $items, 'count' => $slideshow_count, 'view' => $vars['view']));
  22.       $items = array();
  23.       $slideshow_count++;
  24.     }
  25.   }

Step1

Get the number of slides we need to handle the content in the view.

  1.   // Find how many slides we need to deal with.
  2.   $num_slides = ceil((count($rows) / $items_per_slide));

Step 2

Generate a temporary array to store the content.

  1.  // Create a temporary array to store the column counts.
  2.   $columns_temp = array();
  3.   $columns_temp = array_fill(0, $num_slides, '');

Step 3

Loop through the rows and split the rows into multiple 'columns'.

  1. // Loop through the rows and split them into equal columns.
  2.   foreach ($rows as $count => $item) {
  3.     $columns_temp[$count % $num_slides][] = $item;  
  4.   }

Step 4

Loop through the rows again, this time matching checking the count against our temporary array's column count in step 2. Doing this ensures the original order is maintained, while still splitting the slides into equal rows.

  1. $items = array();
  2.   $slideshow_count = 0;
  3.   $rendered_rows = '';
  4.   // Loop through the rows again for output.
  5.   foreach($rows as $count => $item) {
  6.     $items[] = $item;
  7.     // If the item count is equal to the count of our column_temp array, theme the row and increment our column counter.
  8.     if(count($items) == count($columns_temp[$slideshow_count])){
  9.       $rendered_rows .= theme('views_slideshow_cycle_main_frame_row', array('vss_id' => $vss_id, 'items' => $items, 'count' => $slideshow_count, 'view' => $vars['view']));
  10.       $items = array();
  11.       $slideshow_count++;
  12.     }
  13.   }

This code will prevent widowed items from displaying in your slideshows.

--

The full original function, with my few modifications are below.

  1. function THEME_preprocess_views_slideshow_cycle_main_frame(&$vars) {
  2.   $settings = $vars['settings'];
  3.   $rows = $vars['rows'];
  4.   $view = $vars['view'];
  5.   $vss_id = $vars['vss_id'];
  6.  
  7.   // Cast the strings into int or bool as necessary.
  8.   $new_settings = array();
  9.   foreach ($settings as $key => $value) {
  10.     if (is_string($value)) {
  11.       if (stristr($value, "\n")) {
  12.         $value = str_replace("\n", ' ', $value);
  13.       }
  14.       $value = trim($value);
  15.  
  16.       if (is_numeric($value)) {
  17.         $value = (int)$value;
  18.       }
  19.       elseif (strtolower($value) == 'true') {
  20.         $value = TRUE;
  21.       }
  22.       elseif (strtolower($value) == 'false') {
  23.         $value = FALSE;
  24.       }
  25.     }
  26.  
  27.     $new_settings[$key] = $value;
  28.   }
  29.  
  30.   $settings = array_merge(
  31.     array(
  32.       'num_divs' => sizeof($rows),
  33.       'id_prefix' => '#views_slideshow_cycle_main_',
  34.       'div_prefix' => '#views_slideshow_cycle_div_',
  35.       'vss_id' => $vss_id,
  36.     ),
  37.     $new_settings
  38.   );
  39.  
  40.   // We need to go through the current js setting values to make sure the one we
  41.   // want to add is not already there. If it is already there then append -[num]
  42.   // to the id to make it unique.
  43.   $slideshow_count = 1;
  44.   $current_settings = drupal_add_js();
  45.   foreach ($current_settings['settings']['data'] AS $current_setting) {
  46.     if (isset($current_setting['viewsSlideshowCycle'])) {
  47.       $current_keys = array_keys($current_setting['viewsSlideshowCycle']);
  48.       if (stristr($current_keys[0], '#views_slideshow_cycle_main_' . $vss_id)) {
  49.         $slideshow_count++;
  50.       }
  51.     }
  52.   }
  53.  
  54.   if ($slideshow_count > 1) {
  55.     $vss_id .= '-' . $slideshow_count;
  56.     $settings['vss_id'] = $vss_id;
  57.   }
  58.  
  59.   // Don't load javascript unless libraries module is present.
  60.   if (module_exists('libraries')) {
  61.     // Load jQuery Cycle
  62.     if ($cycle_path = _views_slideshow_cycle_library_path()) {
  63.       drupal_add_js($cycle_path);
  64.     }
  65.  
  66.     // Load Json2
  67.     $json_path = libraries_get_path('json2');
  68.     if (!empty($json_path) && file_exists($json_path . '/json2.js')) {
  69.       drupal_add_js($json_path . '/json2.js');
  70.     }
  71.  
  72.     // Load our cycle js
  73.     $module_path = drupal_get_path('module', 'views_slideshow_cycle');
  74.     drupal_add_js($module_path . '/js/views_slideshow_cycle.js');
  75.   }
  76.  
  77.   // Load our cycle css
  78.   drupal_add_css($module_path . '/views_slideshow_cycle.css', 'file');
  79.  
  80.   drupal_add_js(array('viewsSlideshowCycle' => array('#views_slideshow_cycle_main_' . $vss_id => $settings)), 'setting');
  81.  
  82.   // Add hover intent library
  83.   if ($settings['pause']) {
  84.     if (module_exists('libraries')) {
  85.       // Load jQuery hoverIntent
  86.       $hoverIntent_path = libraries_get_path('jquery.hoverIntent');
  87.       if (!empty($hoverIntent_path) && file_exists($hoverIntent_path . '/jquery.hoverIntent.js')) {
  88.         drupal_add_js($hoverIntent_path . '/jquery.hoverIntent.js');
  89.       }
  90.     }
  91.   }
  92.  
  93.   // Add the slideshow elements.
  94.   $vars['classes_array'][] = 'views_slideshow_cycle_teaser_section';
  95.  
  96.   $styles = '';
  97.   if (isset($view->display_handler->display->display_options['style_options']['views_slideshow_cycle'])) {
  98.     $styles = $view->display_handler->display->display_options['style_options']['views_slideshow_cycle'];
  99.   }
  100.  
  101.   $styles_default = '';
  102.   if (isset($view->display['default']->display_options['style_options']['views_slideshow_cycle'])) {
  103.     $styles_default = $view->display['default']->display_options['style_options']['views_slideshow_cycle'];
  104.   }
  105.  
  106.   // Retrive the number of items per frame
  107.   if (isset($styles['items_per_slide']) && $styles['items_per_slide'] > 0) {
  108.     $items_per_slide = $styles['items_per_slide'];
  109.   }
  110.   elseif (isset($styles_default['items_per_slide']) && $styles_default['items_per_slide'] > 0) {
  111.     $items_per_slide = $styles_default['items_per_slide'];
  112.   }
  113.   else {
  114.     $items_per_slide = 1;
  115.   }
  116.  
  117.   $vars['items_per_slide'] = $items_per_slide;
  118.  
  119.   // Find how many slides we need to deal with.
  120.   $num_slides = ceil((count($rows) / $items_per_slide));
  121.  
  122.   // Create a temporary array to store the column counts.
  123.   $columns_temp = array();
  124.   $columns_temp = array_fill(0, $num_slides, '');
  125.  
  126.   // Loop through the rows and split them into equal columns.
  127.   foreach ($rows as $count => $item) {
  128.     $columns_temp[$count % $num_slides][] = $item;  
  129.   }
  130.  
  131.   $items = array();
  132.   $slideshow_count = 0;
  133.   $rendered_rows = '';
  134.   // Loop through the rows again for output.
  135.   foreach($rows as $count => $item) {
  136.     $items[] = $item;
  137.     // If the item count is equal to the count of our column_temp array, theme the row and increment our column counter.
  138.     if(count($items) == count($columns_temp[$slideshow_count])){
  139.       $rendered_rows .= theme('views_slideshow_cycle_main_frame_row', array('vss_id' => $vss_id, 'items' => $items, 'count' => $slideshow_count, 'view' => $vars['view']));
  140.       $items = array();
  141.       $slideshow_count++;
  142.     }
  143.   }
  144.  
  145.   /*//Original code.
  146. foreach ($rows as $count => $item) {
  147.     $items[] = $item;
  148.     if (count($items) == $items_per_slide || $count == (count($rows)-1)) {
  149.       $rendered_rows .= theme('views_slideshow_cycle_main_frame_row', array('vss_id' => $vss_id, 'items' => $items, 'count' => $slideshow_count, 'view' => $vars['view']));
  150.       $items = array();
  151.       $slideshow_count++;
  152.     }
  153.   }
  154. */
  155.  
  156.   $vars['rendered_rows'] = $rendered_rows;
  157. }


Comments