4

I have a current view set up that displays a feed of stories and is sorted in descending order. I now need to have the first 4 stories display as a different style then the remaining ones. I have pagination set to 10. I only want the first 4 to show differently on page 1, and then the current style will show on the remaining pages. Is there a way to do this?

5

You can use views attachment to have a different styles for the first few item in list. By default, the attachment will be displayed in every pages of list.

If you want to limit the attachment works on the first page only, please implement hook_views_pre_build() in your custom module.

Assuming views name is stories, main display ID is block_1 and attachment display ID is attachment_1.

/**
 * Implements hook_views_pre_build().
 */
function mymodule_views_pre_build(&$views) {
  if($views->name == 'stories' && $views->current_display == 'block_1') {

    // if 'page' is not defined, we assume it is the first page.
    if (empty($_GET['page'])) {

      // The offset number y should be equal to the number of items on
      // attachment. If we want to keep the total n items on list, the
      // number of items on main display should be (n - y).
      // Note: get_items_per_page() and get_offset() is not working here.
      $views->set_items_per_page(6);
    }
    else {

      // Remove attachment for other pages.
      $views->is_attachment = TRUE;

      // We don't need to handle the offset anymore.
      $views->set_offset(0);
    }
  }

  // We set the item number again because the it seems
  // be overrided by previous call of set_items_per_page().
  if($views->name == 'stories' && $views->current_display == 'attachment_1') {
    $views->set_items_per_page(4);
  }
}

Below is the steps of using views attachment

  1. Add attachment display

    enter image description here

  2. In the attachment display, you need to specify how many items you want to have.

    enter image description here

  3. Then you need to attach the attachment display to the main display.

    enter image description here

  4. Remember to set the offset in main display for preventing repeating the item in list.

    enter image description here

|improve this answer|||||
  • Thanks for the detail @Jimmy Ko The only issue I found is that on page 2 I don't want the 4 to be at the top anymore. It's only when people land on page 1. Is this possible. – kayzoe Jul 20 '16 at 14:25
  • Um... I misunderstand your question. If it is a node list, there is a simple solution with display suite. – Jimmy Ko Jul 20 '16 at 14:30
  • I will look into that. I haven't worked with Display Suite so was hoping to find a solution with Views. Thanks. – kayzoe Jul 20 '16 at 14:37
  • Please check the updated answer. – Jimmy Ko Jul 20 '16 at 14:45
  • My view name is 'stories', display id is 'block_1' and then the attachment id is 'attachement_1'. When I implement those into the function, and put it into the template.php page, then clear cache, I am not seeing the effects. Do you know what I may have done incorrectly? – kayzoe Jul 20 '16 at 15:15
1
  1. In Views, change FORMAT to Show Fields, if you don't have it already.

enter image description here

  1. Add fields, title, body (for formatter you could use Summary or trimmed), post date, comment link, etc...

  2. Add image field twice, one with style x other with style y, if you want the top 4 to have different image style.

  3. In Fields, Add View result counter and start counter at 1.

  4. Create a template for your view fields:

    views-view-fields--[view-name]--[machine-name].tpl.php

    Example: views-view-fields--hello-world--block-1.tpl.php

In template file you add an if statement to test if counter row is 1, 2, 3, or 4

<?php

if ($fields["counter"]->raw == (1 or 2 or 3 or 4)){

  echo '<div class="top4-title">' . $fields["title"]->content . '</div>';
  echo '<div class="top4-body">' . $fields["body"]->content . '</div>';
  echo '<div class="top4-image">' . $fields["field_image"]->content . '</div>';
  echo '<div class="top4-date">' . $fields["field_created"]->content . '</div>';
  echo '<div class="top4-clink">' . $fields["comments_link"]->content . '</div>';

} else { 

  echo '<div class="reg-title">' . $fields["title"]->content . '</div>';
  echo '<div class="reg-body">' . $fields["body"]->content . '</div>';
  echo '<div class="reg-image">' . $fields["field_image_1"]->content . '</div>';
  echo '<div class="reg-date">' . $fields["field_created"]->content . '</div>';
  echo '<div class="reg-clink">' . $fields["comments_link"]->content . '</div>';

}
  1. Place template file in your /sites/all/themes/YOURTHEME/templates folder

  2. Clear/Flush the cache.

    Note: Since the view template gets added to your theme, the view preview will not reflect this template because the view preview uses the administration theme. The default admin theme is Seven. You would have to add the template to Seven too, but IMO that's un-necessary.

  3. Go to the page where the view gets displayed to see changes.

|improve this answer|||||
  • Thank you @NO Sssweat. I have tried this and for some reason all rows after row 4 pick up the last row styling (ie. <div class="top4-clink">. Should I be doing something with the counter in addition to above noted? Appreciate your help. – kayzoe Jul 21 '16 at 15:45
  • That's odd, do you have echo '<div class="reg-clink">' . $fields["comments_link"]->content . '</div>'; inside the else statement? Did you clear/flush the cache? If yes, maybe try changing the counter to $fields["counter"]->content – No Sssweat Jul 21 '16 at 22:07
  • Hmmm. Still not working. – kayzoe Jul 22 '16 at 15:39
  • @kayzoe I know, I believe it's the or's as explained here This is why you should NEVER use the OR operator without explicit parentheses around the expression where it is being used. So we can use the other or format || or add parenthesies around the or's, updated my answer – No Sssweat Jul 22 '16 at 22:54
  • @kayzoe sorry this was my first time using or, I normally go with || but decided to try or here, I wasn't aware of this gotcha. Code should work now. – No Sssweat Jul 22 '16 at 23:06

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.