The joy of views_embed_view()
I love Views. For those who don’t know it; it’s basically a visual query builder that you want to use in every Drupal project. You might use it to create listings of content, commens, users, and what not. Add arguments, filters, sorts, a search box… you name it. Views can do anything! Well, almost anything.
I use it on a daily base for years now and I keep inventing new stuff it can do. A few weeks ago I had to build an overview that got me stuck. The overview was a list of forums, and for each forum the latest 3 comments. So what I basically needed was a view within a view. First, a view that shows all forums. And then a view that shows the three latest comments for each forum. The first views is easy; just an overview of node type ‘Forum’ where status = ‘Published’ ordered by date. You know the drill.
The second one is a bit harder. Views has the ability to use Contextual Filters (previously known as arguments) that can be used as dynamic filters. An example is a list of related items in the sidebar, where you need the Node ID given in the URL to find related content. For my overview, I’ve added the contextual filter Comment: Nid (The node ID to which the comment is a reply to).
I tried to combine the two views via the interface but didn’t manage. Gladly I discovered the function views_embed_view() which can be used to retrieve the output of a view from within your custom module. The function has three arguments:
- The system name of the view (forum_comments)
- The display name of the view (block_1 for example)
- And the last argument can be used to pass arguments
So I wrote a custom block (using hook_block_info() and hook_block_view() that did something like this:
$result = db_query("SELECT n.nid FROM {node} n WHERE n.type = 'forum' AND n.status = 1 ORDER BY n.sticky DESC, n.created DESC");
$forum_nids = array_values($result->fetchCol());
foreach ($forum_nids as $nid) {
print views_embed_view('forum_comments', 'block_1', $nid);
}
Ain't that cool? If you want to use views_embed_view() with several arguments at once, that’s also possible. Keep in mind that you cannot use an array to pass the arguments, you need to seperate those argument with plus-characters or comma's. Example:
views_embed_view('forum_comments', 'block_1', implode('+', $nids));
The best part is that you can still use the Views interface to sort. order and change the way the comments are displayed.
Tags: