2

I'm using Views to generate a number of lists, e.g. Newest articles and Popular articles. Now, often newest articles will also be in the Popular articles list.

So when I'm using both views on frontage, I would like to prevent, that the same article is shown on both lists.

So basically skip articles in Popular list, if they also are available on Newest list.

4 Answers 4

5

This is not trivial to accomplish, and will in most cases require coding.

First of all, it's necessary to determine in which order the lists should be evaluated. One of them needs to take priority. The gist of the solution, is that in some way, you need to feed the hits from the first list, as arguments to the second list.

In Views, you can add a Contextual filter, or Argument, depending on your version. These arguments can be set to "exclude" their matches, and it's also possible to allow "multiple arguments per filter".

The high priority View can be left as it is, but the low priority View should be configured so that it takes several entity-id's as arguments, and excludes those from the result. The real difficulty for most is going to be in passing arguments between these two Views.

In code:

$first = views_get_view('most_important_view');
$second = views_get_view('less_important_view');

// Get results, but don't render them.
$first->preview('machine_name_of_display');

// Append together a list of node id's to a string.
$nodes_to_exclude = '';
foreach($view->result as $node) {
  $nodes_to_exclude .= $node->nid . '+';
}
// Remove the trailing +.
$nodes_to_exclude = rtrim($nodes_to_exclude, '+');

$second->execute_display('machine_name_of_display', array($nodes_to_exclude)););
return $second->render();

If you are not comfortable using the above code, there is a module called Viewfield that allows you to call a second View from a primary View. But unfortunately I'm not aware of a way to configure this to pass several arguments on, but just a single one, so I'm not sure if that's helpful.

2
  • 1
    Just as an aside, if you want to achieve this wih a single argument, you could use the fact that the newest articles are in time order, and pass the created time on the last one in the newest list as an argument to the most popular list, excluding anything with timestamp greater than or equal that value. Commented Oct 24, 2013 at 11:16
  • 1
    Nice answer! Instead of adding the nids to string and then use rtrim you can use an array, and then implode($nids, '+') .
    – rreiss
    Commented May 1, 2014 at 7:12
0

I was recently viewing videos about the Rules module at dev.nodeone.se, and it discusses such a situation. Check it out.

1
  • This answer doesn't say much, if not suggesting to use the Rules module. May you expand on what the OP needs to do?
    – apaderno
    Commented Jan 1, 2012 at 22:41
0

A module exists to accomplish this. It started within Drupal 6. It is Views exclude previous. Details from project page:

The Views exclude previous module provides a views filter that excludes nodes that have already been loaded/displayed on the current page.

This is very useful when you have pages with several embedded views, and you want to make sure that a given node only appears once in the page.

The advantage of using Views exclude previous rather than manually excluding nodes is that:

  • Each view does not need to know which context it will be displayed in
  • Each view can be displayed in a different context (different page, different order) without needing to change the filter
  • Only the nodes that are actually displayed are taken into consideration - not those that would fall beyond the first page of the pager

Believe it relies on keeping track of node loads, so it won't work with field-based views and perhaps not with other entities. I'm sure the module could use some love.

-1

I think the best way to achieve this is use selection rules (I'm not completely certain if you can filter by those properties but I think you can). I'm not really sure how you are going about defining "new" and "popular" but if is something that can show in the selection rules you can use that to filter.

3
  • Selection rules have nothing to do with what the OP wants to accomplish.
    – Letharion
    Commented Feb 2, 2012 at 20:02
  • My thought process was this, if you have two views you can put logically opposite filters on them. So one would have "has new content" the other "does not have new content". Now that I look though, there is no such filter "does not have new content", which I find strange because you can expose it. I guise the reason I posted was just to illustrate that in some circumstances to get mutually exclusive views, It's as simple as setting opposite filter criteria.
    – user379468
    Commented Feb 3, 2012 at 14:53
  • I probably just misunderstood your answer, selection rules is a completely different concept from views filters. If your suggestion is to use filters, it makes sense.
    – Letharion
    Commented Oct 24, 2013 at 13:39

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.