Creating an AJAX Node Field Pager with an Embedded Contextual View
I get great ideas from users of both my Drupal contrib themes, Bamboo and Gratis. Typically a user will write to me and ask, "how do I do x" with your theme? Most of the time these types of requests are out of scope in terms of what the theme can do on its own out of the box and have more do do with an actual use case that relates to Drupal site building or theming. However, I feel compelled to help out in some small way and explore what the user is asking for; it gets me thinking in different and creative ways. It also gives me a chance to use my contrib themes in real world scenarios that in the end can help improve the theme itself.
Goal
As the title of this post suggests, we want to attach a pager to a specific field within a node in an AJAX way. In researching this, I found the CCK Pager module but it does not have AJAX capabilities so when it pages a field, it literally reloads the page and appends odd query strings to the url structure that are undesirable. I got to thinking that Views has an ultra elegant way of paging content using AJAX so I figured I could substitute a view for the node field I wanted to page and then add a contextual filter to make it relative to the node you're currently on. I also recently discovered a nice way to embed a view within a node in a programatic way so this will come in handy here.
Getting Started
For our example I'll use a content type called Gallery with an imagefield called Gallery Image. The field will hold multiple images that we want to page through one at a time in a node. Create your field as usual and set the field display to be hidden. We hide it because we are going to substitute the view we'll create later. Next generate some content, I like using Drupal Ipsum Devel Generate to get a realistic feel for demo content.
Create the view
Once you've generated some content, create a new view, call it Image Pager and add block display in the process. I call my block "Image Pager Block" with a machine name of image_pager_block. Additional settings are as follows:
- Filter criteria - use the gallery content type we've created.
- Use a field display to show the gallery image and under Multiple field settings for it, uncheck Display all values in the same row.
- If you've generated a bunch of nodes, you'll now see the view display all images from all your nodes.
- Under Advanced > Other be sure to set: Use AJAX:Yes. This will enable the AJAX pager.
- Finally, add the argument; under the advanced tab, add a contextual filter for Content: Nid > When the filter value is NOT available > Provide default value > Content ID from URL. This setting is what filters images only relevant to the node you are on within the View. Your Views preview will now go away but this is normal. However you can preview the view by adding a relevant node ID into the Preview with contextual filters text box.
- Be sure to save your view.
Add some code
Now it's time to add a little code so we can embed the view. In your theme's template.php file, we'll add a node preprocess function which will create a variable for the view for later use to embed it in our theme's node.tpl.php. You can also use a custom node template as well.
/\*\*
- Override or insert variables into the node template.
\*/
function MYTHEME_preprocess_node(&$vars, $hook) {
// Global node.
$node = $vars['node'];
// Create a variable to render the view in the node template.
$vars['image_pager_view'] = views_embed_view('image_pager', 'image_pager_block', $node->nid);
}
The code above creates a variable for the view we created, image_pager_view
, indicates which display to show and adds our nid argument. So now in your theme's node.tpl.php, we can render the variable as:
<?php print $image_pager_view; ?>
In my template I render this right under the content variable:
<?php print render($content); ?>
<?php print $image_pager_view; ?>
That's all there is too it. If all went well, you'll now see your nice imagefield with an AJAX pager and all. In my example, I'm also rendering each image's alt tag as an HTML 5 caption which I've covered in a previous blog post.
Resources
- Views
- CCK Pager
- Views contextual filters
- Drupal 7 Template (Theme Hook) Suggestions
- Drupal Ipsum
- Implementing HTML5 Image Captions with Drupal 7