You are here

views_load_more.module in Views Load More 7

views_load_more.module

A Views pager module to allow new content to be appended to the bottom of a view instead of replacing it.

File

views_load_more.module
View source
<?php

/**
 * @file views_load_more.module
 *
 * A Views pager module to allow new content to be appended to the bottom
 * of a view instead of replacing it.
 */

/**
 * Implementation of hook_views_api().
 */
function views_load_more_views_api() {
  return array(
    'api' => '3.0-alpha1',
  );
}

// We need to implement our own tpls for items being return via the load-more pager.

/**
 * Implementation of hook_theme().
 */
function views_load_more_theme() {
  return array(
    'views_load_more_pager' => array(
      'variables' => array(
        'tags' => array(),
        'quantity' => 10,
        'element' => 0,
        'parameters' => array(),
      ),
      'pattern' => 'views_load_more_pager__',
    ),
  );
}

/**
 * Implements hook_views_ajax_data_alter().
 */
function views_load_more_views_ajax_data_alter(&$commands, $view) {

  // Support No results behavior.
  if (!$view->total_rows) {
    return;
  }
  if (is_a($view->query->pager, 'views_plugin_pager_load_more')) {

    // This is a work-around for allowing exposed for on the page.
    if ($view->query->pager->current_page == 0) {
      return;
    }
    foreach ($commands as $key => $command) {

      // Remove "viewsScrollTop" command, as this behavior is unnecessary.
      if ($command['command'] == 'viewsScrollTop') {
        unset($commands[$key]);
      }

      // The replace should the only one, but just in case, we'll make sure.
      if ($command['command'] == 'insert' && $command['selector'] == '.view-dom-id-' . $view->dom_id) {
        if ($view->style_plugin->plugin_name == 'list' && in_array($view->style_plugin->options['type'], array(
          'ul',
          'ol',
        ))) {
          if (empty($view->style_plugin->options['wrapper_class'])) {
            $target = "> {$view->style_plugin->options['type']}:not(.links)";
          }
          else {
            $wrapper_classes = explode(' ', $view->style_plugin->options['wrapper_class']);
            $wrapper_classes = implode('.', $wrapper_classes);
            $target = ".{$wrapper_classes} > {$view->style_plugin->options['type']}:not(.links)";
          }
          $commands[$key]['targetList'] = $target;
        }
        else {
          if ($view->style_plugin->plugin_name == 'table') {
            $commands[$key]['targetList'] = '.views-table tbody';
          }
        }
        $commands[$key]['command'] = 'viewsLoadMoreAppend';
        $commands[$key]['method'] = 'append';
        if (isset($view->query->pager->options['effects']) && $view->query->pager->options['effects']['type'] != 'none') {
          $commands[$key]['effect'] = $view->query->pager->options['effects']['type'];
          $commands[$key]['speed'] = $view->query->pager->options['effects']['speed'];
        }
        $commands[$key]['options'] = array(
          // @todo change to content_selector
          'content' => $view->query->pager->options['advance']['content_class'],
          'pager_selector' => $view->query->pager->options['advance']['pager_selector'],
        );

        // Trim html to avoid whitespaces.
        $commands[$key]['data'] = trim($commands[$key]['data']);
      }
    }
  }
}

/**
 * Theme function for the view_load_more_pager theme hook.  Based loosely on
 * theme_pager, outputs markup needed for the Load More pager.
 */
function theme_views_load_more_pager($vars) {
  global $pager_page_array, $pager_total;
  $tags = $vars['tags'];
  $element = $vars['element'];
  $parameters = $vars['parameters'];
  $pager_classes = array(
    'pager',
    'pager-load-more',
  );
  $li_next = theme('pager_next', array(
    'text' => isset($tags[3]) ? $tags[3] : t($vars['more_button_text']),
    'element' => $element,
    'interval' => 1,
    'parameters' => $parameters,
  ));
  if (empty($li_next)) {
    $li_next = empty($vars['more_button_empty_text']) ? '&nbsp;' : t($vars['more_button_empty_text']);
    $pager_classes[] = 'pager-load-more-empty';
  }
  elseif (is_array($li_next) && isset($li_next['title'], $li_next['href'], $li_next['attributes'], $li_next['query'])) {
    $li_next = l($li_next['title'], $li_next['href'], array(
      'attributes' => $li_next['attributes'],
      'query' => $li_next['query'],
    ));
  }
  if ($pager_total[$element] > 1) {
    $items[] = array(
      'class' => array(
        'pager-next',
      ),
      'data' => $li_next,
    );
    return theme('item_list', array(
      'items' => $items,
      'title' => NULL,
      'type' => 'ul',
      'attributes' => array(
        'class' => $pager_classes,
      ),
    ));
  }
}

/**
 * Implements hook_views_pre_render().
 *
 * Load js file only if ajax is enabled.
 */
function views_load_more_views_pre_render(&$view) {
  if (!$view->use_ajax) {
    return;
  }
  if (isset($view->query->pager->plugin_name) && $view->query->pager->plugin_name == 'load_more') {
    drupal_add_js(drupal_get_path('module', 'views_load_more') . '/views_load_more.js');
  }
}

/**
 * Implements hook_features_pipe_COMPONENT_alter().
 *
 * @param array $pipe
 *  Further processors to call.
 * @param $data
 *  An array of machine names for the component being exported.
 * @param $export
 *  An array of components being exported.
 *
 * @see hook_features_pipe_COMPONENT_alter()
 */
function views_load_more_features_pipe_views_view_alter(&$pipe, $data, &$export) {

  // Each 'views_view' component in this feature will pass us its machine name.
  foreach ($data as &$machine_name) {

    // Try to load the view so we can see what components its using.
    // If the "Load More" is in use, add this module as a dependency.
    if ($view = views_get_view($machine_name)) {

      // It isn't possible to know which display is using this pager,
      // since the view isn't being executed,
      // so we'll need to check them all.
      foreach ($view->display as &$display) {
        if (!empty($display->display_options['pager']['type']) && $display->display_options['pager']['type'] == 'load_more') {

          // Although we COULD replace the "views" dependency with our own,
          // this is a really bad practice, because we will not always know
          // if another module/component has a similiar intent.
          // Changing that information could cause unintended errors.
          $export['dependencies'][] = 'views_load_more';

          // Check if waypoints is in use as well.
          if (!empty($display->display_options['pager']['options']['waypoint']['infinite'])) {
            $export['dependencies'][] = 'waypoints';
          }
        }
      }
    }
  }
}

Functions

Namesort descending Description
theme_views_load_more_pager Theme function for the view_load_more_pager theme hook. Based loosely on theme_pager, outputs markup needed for the Load More pager.
views_load_more_features_pipe_views_view_alter Implements hook_features_pipe_COMPONENT_alter().
views_load_more_theme Implementation of hook_theme().
views_load_more_views_ajax_data_alter Implements hook_views_ajax_data_alter().
views_load_more_views_api Implementation of hook_views_api().
views_load_more_views_pre_render Implements hook_views_pre_render().