views:

246

answers:

5

The whole point of an MVC framework is to separate design (templates) from logic (controllers). However, template languages often afford a limited degree of "design logic" to occur. This includes basic if statements, loops, filtering, etc.

I've created a Django template tag that can take any list or QuerySet and "pagify" it. It splits the list up into pages based on a specified page size then adds the pages into the Context. The usage is as follows:

{% pagify articles by 20 as pages %}

I can then call a separate include to iterate over the pages and produce a nice list of pages wherever I needed it.

This seemed like an optimal way to do it because it allowed me to page any list in the context; I didn't have to rely on the controller to return paged results. But a colleague argued that this seemed like too much logic for the template. I thought this still fell within the realm of design-based logic since the page would still function even without paging, and determining page size feels like a template responsibility.

My question, is this too much logic for the template? or is this a clean way to be handling this?

+2  A: 

The view should not contain business logic or navigation logic. What you are describing is presentation functionality (carefully avoiding the l-word here), which can be placed in the view layer.

Kees de Kooter
A: 

I agree with your colleague; the template should be fed paginated data rather than performing the pagination. The key question, I think, is whether determining page size is a template duty, and I don't think so; I'd say it should be handled at a higher level.

chaos
Good point, my template tag *does* have to check the request for a ?page=1 variable. That's the part that makes it feel much more view-centric.
Soviut
+5  A: 

It's always been my understanding that the view isn't supposed to be devoid of logic. It's just supposed to be devoid of any controller logic. Paging just has to do with how the data is displayed which is exactly what the view logic is supposed to contain.

Spencer Ruport
+1. Moving presentation logic into the business logic just because it's logic is a Bad Thing. In some languages you have to do that because the templating language is so weak, but if you've got all of Python to hand there's no need.
bobince
My issue wasn't so much having *any* logic in the templates, just whether pagination was considered template logic or business logic.
Soviut
+4  A: 

Put it this way; what if you were using your data model in another medium, say, not on the web but via some kind of console-based application or background task? Wouldn't it be nice to be able to get "pages" of data through a controller (or manager) rather than having to somehow rely on a template to do this work for you?

While I'd certainly agree that the "look" of the paged data should be handled by your template, the "act" of paging should be left up to a controller (Django view) or even through some kind of custom manager (models.Manager) method.

Ryan Duffield
very good point, I wasn't considering a scope that broad, mainly because of the lazy loading that QuerySets in Django afford. Once you start dealing with JSON data and other views that don't render templates, my solution doesn't work.
Soviut
+1 for custom manager as a means of paging as well. It wouldn't be quite as automatic as my template solution, but its an elegant way of dealing with pages straight off the model.
Soviut
Same deal for website themes/skins. If your clients can choose which skin they want, they probably expect pagination to work the same on all of them. I agree that if it's a one-liner it's not a big deal; but in principle pagination shouldn't rely on the presentation so much.
Nikhil Chelliah
+1  A: 

You may want to check out django-pagination, which provides a similar template tag.

Carl Meyer