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:

  1. The system name of the view (forum_comments)
  2. The display name of the view (block_1 for example)
  3. 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. 

Next post

Exporting your module configuration using Ctools or with custom code - when to use which method?

Read More »

Comments