Here's the brief:

Show a page where the first Y posts on the first N pages are in a grid. The remaining X - Y posts are in a HTML list. On the N+1th page the view should show X posts in the HTML list.

A specific use case:

The first blog post on the first page (only) of a blog landing is displayed very differently from the rest.

Currently this doesn't seem possible, as adding an attachment to the main view, and setting the offset to Y means that the attachment shows up on every page in the view, not just the first.
If you resort to code, it does seem possible however, for the simple case:


/**
 * Implementation of hook_views_pre_render()
 *
 * This is a bit sneaky, we make it so that our attachment only shows up on the
 * first page.
 */
function hook_views_pre_render(&$view) {
  //dsm($view);
  if (($view->name == 'blog_landing') && ($view->current_display == 'page_1')) {
    if ($view->pager['current_page'] == 0) {
      // Get the number of items to remove:
      $num_to_remove = $view->display['attachment_1']->display_options['items_per_page'];
      for ($iLoop = 0; $iLoop < $num_to_remove; $iLoop++) {
        unset($view->result[$iLoop]);
      }
    }
  }
  if (($view->name == 'blog_landing') && ($view->current_display == 'attachment_1')) {
    if ($view->pager['current_page'] != 0) {
      foreach ($view->result as $key => $v) {
        unset($view->result[$key]);
      }
    }
  }
}

Just want to get this out there, I'm looking for a cleaner solution in the views_attachment plugin itself.

CommentFileSizeAuthor
#25 Selection_879.png17.95 KBschiavone
#25 Selection_878.png6.83 KBschiavone
Membership dollars fund testing for the Drupal project. Drupal Association Learn more

Comments

merlinofchaos’s picture

You could change that code to an argument validator; use the Global: NULL argument and use the page number to 'validate' the null argument. The global: null argument doesn't actually do anything, but it does allow you to create PHP decision points on a view, particularly one that is not already receiving arguments.

Steven Jones’s picture

Right, but how do I then remove the result on the main view for the first page only?
Put Null arguments on both the displays?

I need to get proper arguments to the blog btw :)

merlinofchaos’s picture

You can still the global: null argument on both and validate both of them properly, I think. That should continue to work.

Steven Jones’s picture

It seems like this should be an option that I can set on the attachment. Is my approach of unsetting the $view->result likely to break lots of things? The pagers need to work, so I can't just tell the main view to render X - Y posts on the first page and then X on subsequent pages, as the pagers won't match.

merlinofchaos’s picture

This is unlikely to become an option within Views, because the use case is very very narrow. I think you're going to need to stick with a custom solution.

Steven Jones’s picture

Status: Active » Closed (won't fix)

This is now handled by the Views attachments - First page only module

bdhowell’s picture

I'd like to see this upgraded for use with Views 3. I'm willing to put some time into it (have to learn more about Views internals, first, though). The first order of business seems to be obtaining the view's pager's current_page value, which appears to be quite buried, in part because of the pluggable pagers of V3: (I found it at)

$view->old_view[1]->query->pager->current_page. Or am I overlooking something.

For a view with one before attachment.

By the way, it seems that there are other people interested in this module--though I think a number of them give up for lack of documentation. It took me a while to figure out how to make it all work as it's a bit arcane. I'll try to write some documentation (I'm also a technical writer) for the Views 2 version when my current project ends in 2-3 weeks.

I think that there is more of a demand for this feature (attachment only on the first page) than you realize, Merlin. I think that it's the kind of feature a lot of folks would use if they knew they could do it. It's great for emphasizing a particular post (or posts) in a pageable list--or is there some other way to do that?

taite11’s picture

I tried Views attachments - First page only. It's a great idea. Unfortunately, it didn't work for my site (#922160: Module Does Not Perform It's Job).

It seems to me that the default behaviour of attachments should be to only show on the first page.

dsayswhat’s picture

For what it's worth to others who happen upon this thread, I had a similar need, but used panel variants and a custom php selection rule to do the same thing - show a 'featured' block for the first page only

I'm using panels to set up my taxonomy term pages, but you could do similar things on non-taxonomy pages.

First, I set up a taxonomy page variant that DOESN'T include the featured block - that covers the default behavior I want for pages that don't have featured content, or 2nd-3rd-nth term pages.

$_GET['page'] is only set for non-first views pages. So you just check if it's there - if it's not set, you're on page 1.

Then, I set up a variant for with the following custom php selection rule:

return ! isset($_GET['page']);

So that panel variant contains my featured block, plus my 'normal' ( non-featured ) views page display, with a pager set up on it. First page, featured variant shows, 2nds and later, non-featured variant shows.

Works pretty well for me, and I don't have to go much beyond the basic usages of views and panels.

Bastlynn’s picture

This is also doable from within Views 2 directly, without too much work. It takes a little bit of careful thinking but here's the idea:

1. On your attachment, give it an argument - Global:Null.
2. Give the argument a default (doesn't really matter what).
3. Then validate the argument based on the page of the view. I used PHP validation for this.
4. Return true on pages you want to show, false on those you don't.

This let me create a frontpage view showing the first post as a full node, and all other posts afterward as teasers, with pagination that didn't repeat the display of the first post over and over again.

(And this shows what I get for not thoroughly reading earlier posts - Merlin already covered the basics of this process. Ignore me - I need to read more closely. ;) )

XiaN Vizjereij’s picture

What would be the correct php code for the argument validator?

I have a view with 2 displays and one attachment i want to show only on the first page. Both are ajax displays ( so $_get don't work ).

I tried everything, but i can't get the current pager page :S

XiaN Vizjereij’s picture

Category: feature » support
Status: Closed (won't fix) » Active
dawehner’s picture

Status: Active » Fixed

I have a view with 2 displays and one attachment i want to show only on the first page. Both are ajax displays ( so $_get don't work ).
$view->pager['current_page']

has the current page as variable.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.

loopduplicate’s picture

Details of only showing an attachment on the first page of a view using the method merlinofchaos mentioned

 

First, create an argument for your attachment.
Make it Global:Null
Select Provide default argument for the "Action to take if argument is not present"
Add a word of plain text into the Default argument input box, pick whatever word you want
Under validator options, select PHP code.
Put the following code in the PHP validate code textarea:

return ! isset($_GET['page']);

This took me hours to figure out. Hope this helps someone. The View Attachment - First Page Only module did not work for me no matter what config options I used. So I had to learn a bit more about views. It was very rewarding.

Cheers! -Jeff

Steven Jones’s picture

I can see that your method means that the attachment is only rendered on the first page, but I'd like to know how you deal with duplicate results, i.e. doesn't the attachment render the same results as the main view (or some subset of them)?

incrn8’s picture

#15 works perfectly. Thanks loopduplicate!

harrrrrrr’s picture

#15 does the job.

drupalpal’s picture

anyone can give a concise quick tutorial on how this can be applied for Drupal 7? The contextual filter global null thing is not working with me.

thanks.

AgaPe’s picture

For ajax paging in Drupal 6 Views 3 #13 didn't work for me but #7 did, so i wanted to display this attachement only on the first page and validated it by:

return ($view->old_view[1]->query->pager->current_page == 0);

Thanks!
Maybe this works for Drupal 7?

theoracleprodigy’s picture

9 works for me on some sites but not on others. I have taxonomy terms being called as arguments with a validation. It something that might not be needed so will remove it and see if it works.

The module does not work at all that was mentioned. This is a very much needed feature. We have quite a few websites and I only have a few that don't need this. Glad someone here has some solutions to work with.

Ryan258’s picture

I'm not totally sure that the #15 solution works as it sounds like you would either have duplicates or you would be missing content.

Here's what I mean:

You have an attachment for the 1st 3 results to display one way.

Then you have your page set to offset that 3 and display 7 results.

Problem a foot seems to be that when you page to the next page, even though you remove that view attachment with return ! isset($_GET['page']); and grab the page, you're still dealing with that offset of 3, so on every pager page you click through you're skipping 3 articles of content.

I'd love to know if I'm either simply misguided or there's a work around for this.

bburg’s picture

I banged my head on this for a while and thought I would share. I don't use php fields because of their security risk, so previous suggestions weren't really an option. Also, the problem with $view->set_items_per_page(0) is that zero indicates that all items should be displayed. So I implemented this in a custom module:

/**
 * Implements hook_views_pre_view().
 */
function hook_content_types_views_pre_view(&$view, &$display_id, &$args) {
  if($view->name == 'view_name' && $display_id == 'display_name' && !empty($_GET['page'])) {
    $view->is_attachment = TRUE;
  }
}

You see, in https://api.drupal.org/api/views/includes%21view.inc/function/view%3A%3A..., this property is used to prevent other attachments from being added to this display, so we're tricking it into not attaching it at all. I'm still not certain if this will cause other headaches for me, but so far so good.

loopduplicate’s picture

Hi All,

Wow, this is an old thread :) Just want to mention that Display Suite comes with options to do these sort of things now with it's views row plugin. See this video: https://www.youtube.com/watch?v=egVp3i44wpY&index=4&list=PL7E361A55994F1648

Regards,
Jeff

schiavone’s picture

Issue summary: View changes
FileSize
6.83 KB
17.95 KB

#24 works great for Drupal 7

Choose display suite for Format Show

Format Show Display Suite

In settings choose a default display e.g. Teaser and alternative display for the first row e.g. Full Node

Row style options

Select "Use the changing view mode selector"