best way to create a projection with a different number of items on the first page?

Topics: Customizing Orchard, Writing modules
Aug 2, 2013 at 6:57 PM
Edited Aug 2, 2013 at 7:06 PM
I'm trying to figure out how to create a projection where the number of items is different on the first page, such that:

first page:

/MyProjection?Page=1 returns 7 items

all subsequent pages:

/MyProjection?Page=2 returns 9 items
/MyProjection?Page=... returns 9 items

I tried to do a bit of debugging to figure out what I might have to change to get this functionality.

I thought a good place to start would be to debug the ProjectionPartDriver Display() method, but to my surprise, this never gets hit when the projection page is viewed.

Ok, I thought, well the code must be looking for ItemsPerPage somewhere so it knows how many items to list. So I did a solution-wide search for ItemsPerPage, and got no results except in the ProjectionPartDriver which as mentioned does not get hit in the debugger, the ProjectionPartRecord (doesn't get hit either when viewing), and ProjectionPartEditViewModel which isn't relevant at this point.

So, I'm a bit lost where to start.

I'm guessing I want to suppress/change the ProjectionPartRecord to add a "ItemsOnFirstPage" property, but I can't figure out where I would put code to make use of it afterwards.

Maybe there is a much simpler way to achieve what I want?

Another thing I considered was to use 2 projections - one with 7 items, and one with 9 items, but the problem then is that I would have to change the pager "next" anchor url from /MyProjection to /MyProjection2 - which doesn't meet requirements, as the url must stay the same excepting the page number.

Maybe I would just be better off forgetting a projection page, and just using a standard controller/view + route and a direct query?

Something like this:
var titlePart = _contentManager.Query<WidgetPart, WidgetPartRecord>().Where(x => x.Title == "SomeProjection").List().First();
            var part = _contentManager.Query<ProjectionPart, ProjectionPartRecord>().Where(x => x.Id == titlePart.Id).List().First();

            dynamic shape = _contentManager.BuildDisplay(part, "MyProjection");

            var model = new NewsAndFeatures { newsShape = shape };
            return View(model);
Any ideas about the right/fastest way greatly appreciated.

Right now, I'm stuck and I need to get this done.
Aug 5, 2013 at 5:22 AM
The page size is stored in the ProjectionPart, and used in the Display method in the ProjectionPartDriver.
What you could do is copy this entire driver to your own module and make adjustments so that it returns your own shapes and uses your own custom paging logic.
Use Placement.Info in your theme to make sure your custom shapes get rendered instead of the ones returned from the ProjectionPartDriver.

Alternatively, as you suggested, you could use your own controller and render your list from there. Or write a custom widget.