Pages

Thursday 29 August 2013

How Drupal "Views Auto-Refresh" really works

Views is a great module and as you'll probably know it is the most downloaded module in Drupal's history. The possibilities which Views provides you with are almost endless but there is one limitation. The generated output of a view is by default static. What if you want to have a dynamic activity stream as you know it from Twitter or Facebook?
Allow Drupal's unofficial slogan to answer that question: There is a module for that! The module in question is "Views Hacks" and contains another module called "Views Auto-Refresh". There is a blog post about how to implement this module in order to get it to work as you want to, but it seems like this post doesn't cover all of the aspects that are implemented in the "dev"-version. A follow up blog post offers a little more insight, but still not everything I needed.
On a side note: In this tutorial we will use the "dev"-version of "Views Hacks", because the alpha was buggy at the time, and the implementation of the JavaScript part is not in the Drupal way anymore.

Preparation

Views autorefreshb
Let's get started with the implementation. I assume that you have downloaded, installed and activated Views, Views UI, Views Hacks and Views Auto-Refresh. Further I assume that you have created a view for which you want to use the auto-refresh feature.
I will demonstrate the implementation of Views Auto-Refresh by showing screenshots of the actual project.

Implementation

Views autorefresh
Make the following configurations:
  • First of all, you need to duplicate your actual view as a view page. Give it a semantic name like "autorefresh".
  • Give the page a unique path as displayed in the screenshot above.
  • Also give an easy-to-remember machine name.
  • Make sure that the view is using AJAX.
  • Add the Content: Post date (with operator) or any other timestamp as a contextual filter (we used the "Content: Updated date"). Views Auto-Refresh will provide the timestamp needed.
Now head over to your view and add a "Global: Text area" with the text format "PHP Code" and add following code:
<?php print theme('views_autorefresh', array('interval' => '30000', 'incremental'=> array( 'view_base_path' => 'frontpage/autorefresh', 'view_display_id' => 'autorefresh', 'view_name' => 'articles', 'sourceSelector' => '.view-content', 'targetSelector' => '.view-content', 'firstClass' => 'views-row-first', 'lastClass' => 'views-row-last', 'oddClass' => 'views-row-odd', 'evenClass' => 'views-row-even', ))); ?>
Views autorefresh
 
As you can see, there is a base path and a display ID.
The base path equals your defined page path, and the display ID equals the Machine name of the auto-refresh View.
"interval" defines how often the auto-refresh View is being called while "view_name" is the machine name of the actual view.
The additional settings are the selectors and classes which will be addressed by the JavaScript of Views Auto-Refresh. I don't want to dig too deep since they should be self describing.
Now you might think that everything is done. But no, wait, we have to add the same code to the header of your original view. So do the same thing there as I have described it above. Please make sure that this view also uses AJAX, else it wouldn't work.

Further possibilities

In our project we use the jQuery library Isotope which sorts all the posts dynamically on loading or resizing. But you have to trigger the re-layout of the page if the Views Auto-Refresh has delivered some new posts. This is really simple and straight forward. You just have to add a Drupal behavior in your JavaScript like this:
/** * Add functionality to trigger reloadItems after an autorefresh */ Drupal.behaviors.triggerIsotopeAfterAutorefresh = { attach: function(context, settings){ $('.view-id-articles').bind('autorefresh.incremental', function() { //getting the content/context $isotope = $('.view-id-articles .view-content'); //reload all items by original order $isotope.isotope( 'reloadItems' ).isotope({ sortBy: 'original-order' }); }); } }
As you can see, you can just bind the event 'autorefresh.incremental' to execute your own code. 'autorefresh.incremental' is fired every time the Views Auto-Refresh module loads the designated view.

Conclusion



After a few trial and error attempts, I finally figured out how Views Auto-Refresh really worked. There is a lot more to this module that isn't documented. So it is much more powerful than I can describe in only one blog post. So go on and give it a go.

Update 9.5.2013: As pointed out by Phil Dodd in his comment the Views Auto Refresh module has been moved to its own home athttp://drupal.org/project/views_autorefresh.

No comments:

Post a Comment