Drupal Views Pager with Different Default Page
When working with Drupal Views recently, I wanted to make the Views pager behave like the Related Videos block of the Videos section on this site. In other words, I wanted the block to display the page that the current content is on by default as opposed to showing the first page of content. The primary focus of the site I am working on is video focused so using the Videos section for reference made sense.
I couldn't find a solution online for my problem so I figured that I should post my findings. Getting the page that the content resided compared to other videos was not too difficult and it just involved a simple hook implementation. The hook that was implemented was the hook_views_pre_build ().
/**
* Implements hook_views_pre_build ()
*/
function hfcustom_views_pre_build(&$view) {
if ($view->name == "related_playthrough_vids") {
if (!isset ($_GET["page"]) || !is_numeric ($_GET["page"])) {
$node = node_load (arg (1));
if ($node->type == "playthrough_video") {
$query = db_select ('node', 'n')->condition ("n.type", "playthrough_video", "=")
->condition ("n.nid", arg (1), "<");
$query->join ("field_data_field_playthrough", "play", "n.type = play.bundle AND n.nid = play.entity_id");
$query = $query->condition ("play.field_playthrough_nid", $node->field_playthrough["und"][0]["nid"])->countQuery ();
$num_rows = $query->execute ()->fetchField ();
$page = floor ($num_rows / 5);
//$remain = $num_rows % 5;
$view->current_page = $page;
$view->items_per_page = 5;
}
}
}
}
Once the proper view has been detected, the function checks if a page number has been specified as a GET variable and then tries to find the appropriate page number if one has not been provided. The nid of the current node is taken from the URL and then the node is loaded. Then a count query is used to find the number of videos stored before the current video. The placement in the pager and specifying the number of items in the list is performed at the end of the function; the value for number of items specified in the Views UI is not accessible at this point so it must be specified here as well.
Now that a proper default page has been determined, the next issue that had to be fixed was that the page number has to be explicitly specified for the first page; Drupal will usually omit the page component for the first page but that behavior will cause issues when using a different default page. It took too long to figure out but I eventually came up with a solution. Firstly, more views hooks had to be implemented. hook_views_pre_render () had to be implemented as well as hook_views_post_render () in order to undo my change in.
/**
* Implements hook_views_pre_render ()
*/
function hfcustom_views_pre_render (&$view) {
if ($view->name == "related_playthrough_vids") {
global $in_playthrough_vid;
$in_playthrough_vid = true;
}
}
/**
* Implements hook_views_post_render ()
*/
function hfcustom_views_post_render (&$view, &$output, &$cache) {
global $in_playthrough_vid;
if ($view->name == "related_playthrough_vids") {
$in_playthrough_vid = false;
}
}
Even though I don't like using global variables, this was one case where using a global variable was necessary. $in_playthrough_vid designates that the related_playthrough_vids block is being rendered. The variable will later be used in a preprocess template function.
function hellfirecomms_preprocess_pager_first (&$variables) {
global $in_playthrough_vid;
global $pager_page_array;
$element = $variables["element"];
// Only do this on first page
if ($in_playthrough_vid && $pager_page_array[$element] == 1) {
$variables["parameters"] = array ("page" => 0);
}
}
The relevant function for the upcoming pager is the theme_pager_first function. As opposed to overridding the theme_pager_first function, a template preprocess function can be used to change the input variables being passed to the theme_pager_first function. In the previous code, the function will check that the related_playthrough_vids block is being rendered and that the first page link should be rendered. If so, the page number for the first page must be given. The way to do this is to add the page number to the parameters variable.
With this code in place, a page number will be passed for the first page which will work with the hfcustom_views_pre_build function mentioned earlier. Without the page number, the new default page would have loaded again and the first real page would never be accessible.
This is the extent of my pager customization adventure. It is good that Drupal is so flexible.



