This tutorial attempts to unveil the beauty of Drupal's modular architecture, which allows for combination of three modules to provide a functionality which would at the first thought require a separate software add-on of its own.
These days, users are provided with a Recently Viewed block on quite a few websites. It's a useful on-site history of last ten or twenty content pages you've viewed, which follows you wherever you're logged in from. Variations exist which combine the list with user's favourite content or recommendations.
The most straightforward approach to implementation of such a feature would be a module built around a database table with three columns -- viewing user's uid, viewed node's nid and date of viewing. The module's
hook_nodeapi('view', FALSE, TRUE) implementation would update the history stored in our database table.
Is it really necessary, though, to start writing a module from scratch? Could we possibly use what Drupal project is already offering? With three popular modules which most likely you've had installed already, we can quickly put together a recently viewed list of nodes for each user.
We're going to use Flag module to flag each visited node with a per-user flag. To have it flagged automatically and re-flagged at each consecutive visit of the node, we'll use a little help from Rules module. Finally, to display the user's list of recently viewed content, e.g. in a form of a block, we'll use the must have Views module.
That pretty much sums it up. If you know what I'm talking about and how to make it work by yourself, go ahead. Here's a long version for the rest of you.
Flag module is an incredibly useful Drupal module. At first glance, it might seem to be only good for users to bookmark their favourite content. But for website developers it provides great means of grouping content, "marking" it for later use.
Just an example of what you can use it for (apart from bookmarks and recently viewed content) -- on a real estate website I've worked on recently, I used Flag module to implement a Unit comparison feature. User would flag individual living units with an Include in comparison flag and a simple view would render the unit comparison table itself with all flagged nodes' data included.
A very important feature of flags, in addition to linking a node record with a user one, is that it also stores the date and time of when the flagging occurred.
Let's set up a flag we'll to use to "mark" visited nodes as users are browsing our website. Navigate yourself to Administer » Site building » Flags configuration page and add a new flag with settings along these lines:
Submit. The flag we're creating won't be visible to users and so it doesn't really matter what you use for title and link texts. What's important, though, are the following fields:
Like I said, we want to make this flag "automatic" and not visible to users at all.
I haven't used Rules module excessively but I believe it's alright to think of it as of Trigger module on steroids. It lets you define conditionally executed actions based on occurring events. Which is what we need now.
Every time a user views content, we want Rules to flag it with our recently_viewed flag. To preserve the actual viewing order and to have the flagging time updated on each visit, we need to work around a minor Flag module annoyance -- if the node is already flagged, it does not get re-flagged. Thus, the date and time won't get updated. To make it work our way, we unflag the node first, then re-flag it again.
Make your way to Administer » Rules » Triggered rules configuration page and click Add a new rule:
Since Flag is smart enough to follow its configuration and will only flag the nodes of allowed types on behalf of allowed users, we don't need to create duplicate Rules conditions. We can set up Rules to flag every node user visits and let Flag decide what will get flagged eventually, based on the flag's settings.
To prevent Rules from re-flagging the nodes each time they appear as teasers in taxonomy pages or items in Views, we want to add a condition to check for a truth value. This way we can make sure the actions only get executed when node is displayed as page:
Our rule has two actions: unflag the node and flag it again. Add an action:
Submit and continue:
The second action of our rule is set up the exact same way except for we're flagging this time.
It's important to create the unflag action first and the flag action afterward. The action's Weight field is supposed to allow for action execution reordering, it just doesn't seem to be working for me.
Finally, to display the list of recently viewed content, we're going to use the almighty Views module. We want to set up a view to contain links of ten nodes most recently flagged with recently_viewed, ordered by recency and displayed in a block.
Click Add in Administer » Site building » Views configuration page to create a view:
That's about it. Just add a block display, save and you're ready to roll. The view will show up in the blocks configuration page, ready for you to add it to the user's account page or display it in sidebar as part of a user's toolbox.
I'm using recently viewed content block along with Insert View module to group a couple of useful views into a single Tools block.
The basic functionality outlined above only works for logged in users. If you'd like to have the same feature available for the anonymous users, you might want to have a look at the Session API. Not having used it myself, it seems to integrate with Flag. I'm not sure, though, how anonymous sessions would play with the page cache. It's likely the node viewing event wouldn't fire up on cached nodes and the actions wouldn't get executed.
You can extend the view with a few links and make it work like eBay's Recently viewed items. You can add a link to node's author account or to place a recently viewed item into user's watch list -- implemented using Flag module!
You can create a Recently changed content list with a mere change of Rule's triggering event from Content is going to be viewed to Content is going to be saved.
With another tiny change you can make it display only the current user's recent posts. Each of the three modules we've used today (Flag, Rules, Views) is robust and powerful enough to make their combination each Drupaller's heavyweight tool.
|Recently viewed Drupal module||9.5 KB|