We recently had a client that wanted to have two different teaser treatments for a node type on their homepage: The first node would show more content, while the other nodes would have less content displayed. This is common for displays where you want, for example, a highlighted top post with more abbreviated lower posts.
We approached this using two views. The top view would return the top node of the view, while the second view would return everything but the most recent item, while displaying different teasers. The first view was easy: simply the most recent node of that type that had been published.
The second view, however, was created by using two functions from the views module and placed in the page-front.tpl.php file:
views_get_view($view_name)views_build_view($type, &$view, $args = array(), $use_pager = false, $limit = 0, $page = 0, $offset = 0, $filters = NULL)
We used views_get_view() to get the view object for the view and set it to a variable:
<?php
$second = views_get_view('Secondary_topics');
?>Next we used the views_build_view() to display the view on the home page:
<?php
print views_build_view('embed', $second, array(), FALSE, 5, 0, 1);
?>We stated the type as embed because the view is being embedded in a page. The the next parameter, $second, is the views object, which was returned by the views_get_view function.
To achieve the goal of getting five teaser views starting at the second most recent topic, we set the $limit parameter to 5 and the $offset parameter to 1.
For the other view that only displays the most recent node topic we used the same two functions, but set the $limit parameter to 1 in the views_build_view function:
<?php
$first = views_get_view('Front_Page');
print views_build_view('embed', $first, array(), false, 1);
?>We placed both of these steps into the page-front.tpl.php template in the appropriate places to display the content on the page and in the order that is needed.
Now the new issue is this: both contents look the same because the views are both calling the same node.tpl.php file and there is no flag to check for which view is being used.
To resolve this issue we used the global variable $current_view as a flag. The $current_view variable is an object that contains the name of the view being used ($current_view->name). We placed the $current_view variable at the top of the node.tpl.php template file. Next we used a conditional statement (if..elseif..else) to have the node.tpl.php file display different content for each view on the same page.
<?php
global $current_view;
?>This displays content for the first topic view on the front page, but not for the other view on the front page:
<?php if(($current_view->name == 'Front_Page') && $is_front): ?>
This will only display in the first view on the front page.
<?php endif; ?>I hope this helps other Drupal users. If anyone else has come across this and did it a different way, please share.








Comments
manuee writes:
Very interesting post, I remember wondering how to go about doing this not so long ago... your article triggered me to have a go at it. Here is how i did it, based on the handy information you provided:
Created two views, only filtering published nodes, and sorting on created time (descending). Only difference between them is one is a teaser view (secondary_nodes), and the other is a full nodes view (latest_node).
I then put this code instead of the $content on my page-front.tpl.php:
<?php$first = views_get_view('latest_node');
print views_build_view('embed', $first, array(), FALSE, 1);
$second = views_get_view('secondary_nodes');
print views_build_view('embed', $second, array(), FALSE, 10, 0, 1);
?>
Seems to work great, many thanks for sharing! :D
Elvis McNeely writes:
Thanks for sharing this. I am curious if there is anything special to do in the view itself?
In the past I have done something similar by creating functions in template.php then calling those functions from a block:
<?php print function_name($type='blog' $max='5'); ?>I imagine you could do the same this with the views_build_view() function?
Jody Hamilton writes:
This is interesting, especially the global $current->view.
I believe if you bring in your views as panel views into Panels 2 that you can actually set an offset when you do that and get the same effect.
I also think it may be possible to include an offset in the 'argument handling code' section of the view, perhaps by just entering $view->offset = 1; ? Not sure about that, but I know you can actually do a lot of custom things to views by putting code there.
merlinofchaos writes:
I have done similar treatments with Views using a purely theming method. There are a few really interesting tricks you can do because theme_views_view_nodes() is so very simple.
Assuming my view is named 'foobar':
<?php/**
* Display the nodes of a view as plain nodes.
*/
function phptemplate_views_view_teasers_foobar($view, $nodes, $type) {
foreach ($nodes as $count => $n) {
$node = node_load($n->nid);
$node->template = $count ? 'short' : 'long'; // apply a variable to the node that we can use later.
$output .= node_view($node, TRUE, FALSE, TRUE);
}
return $output;
}
?>
In template.php, in _phptemplate_variables, under case 'node':
<?phpcase 'node':
if (!empty($vars['node']->template)) {
$vars['template_files'][] = 'node-view-' . $vars['node']->template;
}
?>
Now, based upon the value I set in the view theme function, the actual node template used is based upon whether count is 0 (node-views-long.tpl.php) or non-zier (node-views-short.tpl.php).
This method is superior because 1) only one view 2) purely at the theming layer 3) less code 4) very very flexible.
gollyg writes:
This is the same approach I have taken, and it seems to work perfectly. There is no issue of 'normalising' you views, as you are only dealing with the one view.
dalin writes:
global $current_view; won't always work for you. It can give false positives if the view exists in a block and you're logic switching is in node.tpl.php
I think there's a situation where it can give you false negatives too, but I can't remember what that is.
dagomar writes:
Hi,
it seems to me that this is more work than needed! I made for my girlfriend a blog and on the homepage it will show the latest post (a view that takes the latest post and displays it completely), then i created a second -list- block - view that shows only the titles as link with an offset in the argument field of that view ($offset = 1;). There was no need for me to fiddle around with template files! Just 1 view and a views block!