14

With the help of another question: Show newest nodes for each taxonomy term in Views I have been able to create the view I require, except that it displays all posts for each term (grouped by term)? How do I limit each term to display only 3 of their latest posts.

e.g.

Term 1
- Post 1
- Post 2
- Post 3

Term 2
- Post 1
- Post 2
- Post 3

Term 3
- Post 1
- Post 2
- Post 3

9

If you need only one node you can use “Representative node” relationship. But if you need three nodes per each term, use something like Views Field View.

1) Create "child" view for content. Something like this: enter image description here

Add taxonomy term argument, pager limits, sorting and etc: enter image description here

Now you can attach this view to another one.

2) Create taxonomy view: enter image description here

Add hidden term ID field and then add “Global: View” field: enter image description here

Don't forget to configure caching. From Views Field View page:

It's highly recommended to use this module in conjunction with views caching. Views Content cache and Cache Actions are good ways of caching views.

  • Thanks Kalabro. Your approach is correct as well. I was originally going this route but wanted to see if there was a better way than creating a ton of views and then embed view after view. – Nigel Waters Dec 13 '12 at 22:30
  • 2
    That's not a ton, @NigelWaters. That's only two: one for nodes and one for terms. This solution is quite stable and I use it for non-standard views listings. – kalabro Dec 14 '12 at 8:47
  • My misunderstanding. I thought I needed to create a view for each group. – Nigel Waters Dec 14 '12 at 18:04
  • This is almost perfect for my use case. My only issue is the "more" link for a child view, links to the same view, and still only displays the limited number of elements! The titles from the parent view link to the taxonomy which works as desired. – Mark Dec 17 '14 at 21:55
  • Ahah - I created a block display for my child view with only the first n items shown, and a more link. The more link navigates to the page display, and it displays all items with a pager. Great! Now the only issue is the header (in the master view) links to the taxonomy term, but I can either unlink that, or change the page display of the child view to the same URL. – Mark Dec 17 '14 at 22:08
7
+100

Upon further investigation, it seems like Peek Summary might be exactly what you want. The screenshots on the documentation are for Drupal 6, and it's slightly different in Drupal 7, so I've attached some updated screenshots.

  • Choose Peek Summary from 'Contextual Filters' > 'When the filter value is not in the URL' > 'Display a summary' > 'Format'

Choose Peek Summary from 'Contextual Filters' > 'When the filter value is not in the URL' > 'Display a summary' > 'Format'

  • You'll see a view of sub-views. Click on the gear next to the pager for the group you'd like to limit.

Click pager preferences icon

  • Enter the max items to display on the pager options.

First field under Pager Options

You'll have to edit the pager for each and every group you'd like to limit, which is unfortunate. When you edit the pager for one group, it changes the settings for all groups. If you want to display a number of nodes per group different than the total number of groups, override that in the 'Format' settings under 'Contextual Filters' (on first screenshot in purple).

It has the disadvantage of essentially creating [n] views for [n] groupings, which could be a performance issue depending on how many groupings you have, but it does limit the query to only the number set to display. This could improve your performance, depending on your use case. As always, cache responsibly.

  • It appears that a pager cannot be overridden per group. Hitting edit on a pager in a group, pulls up the master pager settings. Unless I am missing something? – Nigel Waters Dec 13 '12 at 22:11
  • Ah, right you are. Well, that's perfect then. You'll be able to limit all of them at once. – beth Dec 13 '12 at 22:13
  • Unfortunately that means the pager affects the number of groups shown too. I suppose my original post is misleading as the example only show three terms with three posts each. I need to show 10 or more terms with 3 posts per term on a single page. So close :( – Nigel Waters Dec 13 '12 at 22:19
  • I was wrong about the "override items to display" doing nothing. Use that to determine how many groups to show. Entering '0' gives you infinite groups. – beth Dec 13 '12 at 22:25
2

A way to limit this in code would be to add something like the following to a custom module:

function custom_views_pre_render(&$view) {
  //get the rows from the view just before render
  $results = $view->result;
  //create a counter
  $count = '';
  //we're going to built up a new $result array
  $new_results = array();
  //iterate through each view row
  foreach($results as $result) {
    //find the taxonomy term
    $term = $result->taxonomy_term_data_name;
    //add the term to a string of all the terms we've seen so far
    $count .= $term;
    //make sure to separate them with spaces to make them easier to count
    $count .= ' ' ;
    //count how many rows have the same term as the current one
    $term_count = array_count_values(str_word_count($count, 1));

    if($term_count[$term] <= 3){
      //if this is the third or fewer row with this term, add it to the new result array
      $new_results[] = $result;
    }
  }
  //instead of the normal view output, only show the results we put in our array.
  $view->result = $new_results;
}

This is for a view of taxonomy terms that is connected to nodes via a relationship. If you just have a view of nodes, your mileage may vary.

Though it prevents the display of more than 3 per term, this will not prevent the query from returning all the results for each term, so it doesn't improve SQL performance at all. If you have a very large number of results for each term, making separate view panel displays and putting them all in one region using something like CTools Page Manager so you're not running huge queries.

As always, you're going to want to cache this stuff on production.

  • 2
    There's really no need to comment on my gender. It's quite damaging. t.co/i1dKE8hQ t.co/ATfV3mBG Anyway, Hook_views_pre_build() or hook_build_pre_execute() might be usable for something like this that reduces the performance hit, but I'm not as familiar with those. Or you might like my answer to this question previously. – beth Dec 13 '12 at 19:59
  • Update: I have it on good authority (Crell and stevector) that "You can't limit each group separately in a single query. You have to do it in the rendering stage. SQL can't do that, sadly." They also said "Best you could do is a series of union queries" but they don't think Views can do that either. – beth Dec 13 '12 at 20:09
  • Ah, I mistook you for the OP. In any event, the Peek Summary module might be useful in this case, though it presents its own performance issues. Its creator warns that it's "sort of gross, but sort of cool." – beth Dec 13 '12 at 20:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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