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.
Next post
Comments
There's a module for that
You don't need code at all. You can use views_field_view to embed one view inside another.
views_embed_view
I recently had to prepare a navigation block that presented X latest project nodes, which normally would be a piece of cake even for a Views novice. The catch was however that I had to group them by taxonomy term in a way that is not supported by Views UI. The views_embed_view came to the rescue - I prepared 2 sub-views and printed them out in my custom hook_block_view. I tried also another way - by building the markup with EntityFieldQuery which was surprisingly easy to do.
I still wish there was a "barebone" display style in Views that generates minimized markup with no wrappers whatsoever, except where necessary (such as li/ol or a when asked to list or hyperlink an item). Having to overwrite the markup in several places is a pain. This might be a challenge for myself to write such a useful module.
There is such a module
Check out the Semantic Views module, it's awesome.
And exposed forms?
Thank you very much for your overview.
I run into another problem: I have two views for the same content type: one with only the first result of my query with a bigger image and some more informations as teaser and the other view with the next 10 Elements of the query and a pager etc.
For this view I also got an exposed form - but the exposed form filters only apply to the second view.
Is there any possibility to add the exposed form filters to the views_embed_view command?
Use Display Suite
Display Suite has a views integration in which you can use alternating view modes. With this, you can set the first item to use a different view mode than the other items.