Good discussion already! Let me frame the three issues that I brought up in a broader context. IMHO, the "web pages" that we see gaining popularity these days tend to be collections of little widgets. I am thinking mostly of Facebook here, where each little widget gives us a slightly different view of the underlying data. One widget gives us a look at one subset of the data, another gives us a look at a different subset, etc. A user's "home page" is just a frame for a bunch of widgets. The user can "drill down" and get expanded views of the data by clicking through the widgets. I guess I'm struggling to implement this kind of user experience in the MVC paradigm.
I start with two things: 1) A clear idea of how I want the user's experience to work (eg, what I just described) 2) A URL schema that - and maybe this is where I am going wrong - implements a kind of "pointer system" to the various views of the data that I want to show the user. An example of #2: http://mysite/user/danny gives danny's profile (a bunch of widgets) http://mysite/user/danny/email gives danny's email console http://mysite/user/danny/trips gives danny's trip console http://mysite/trip/1/participants (you get the idea...) This schema is maybe best described as {entity}/{id}/{view} or somesuchthing. For each kind of entity, I have a different Controller class and, typically, a database table and the rest. Different "views" get different Controller methods. So, UserController would have an "email" method, a "trips" method, and so forth. So I've got my #1 and my #2 and I start working in from both directions. The problems start to arise when I try to collect a bunch of different views into one, like on the user's "home page." This page would, basically, just be a frame that holds the output of http://mysite/user/danny/email/widget and http://mysite/user/danny/trips/widget and so forth. This is easy to implement using AJAX, but doing so seems really kludgey. I've also thought about passing the controller instance right into the template and calling the controller methods that correspond to the URLs (eg, UserController.email_widget and UserController.trips_widget), but that seems silly too. All of which leads me to believe that I'm violating the paradigm somehow. Any thoughts? ~br On Jul 21, 10:55 pm, Mike Orr <[email protected]> wrote: > On Wed, Jul 21, 2010 at 5:44 PM, BrianTheLion <[email protected]> wrote: > > I was > > hoping that some of the more experienced Pylons crew would take a few > > minutes and maybe help compile some "best-practices" that will allow > > others get off the ground more quickly. > > There aren't really any definitive answers to these. Many of the > design decisions in Pylons or in Pylons tutorials are arbitrary. There > are several roughly equal ways to do something, and the Pylons > developers prefer one way, other frameworks prefer another way, etc. > Many of these alternative designs can be implemented in Pylons, but > they would be unfamiliar to a new Pylons developer who joins the > project, or somebody on IRC you ask a question to. > > > 1) How many Controllers? > > Pylons supports multiple Controllers. When should you use more than > > one? How many should you use? One for each of the major entities in > > your object mode? > > It depends how complex the application is. If the site has multiple > sections, each with more than one or two actions, it makes sense to > use a separate controller for each section. And of course, RESTful > resources deserve their own controllers. Miscellaneous onesie and > twosie actions can be put together in a miscellaneous controller; I > use a controller called 'main' for these. > > > 2) How to treat templates? > > The Pylons documentation seems to suggest (to me at least) that the > > "right" way to use templates is to dump data - typically strings and > > other literals - into the template context and simply render the > > template. We could choose, instead, to use render_def and pass the > > data as explicitly named parameters to template defs. Which method do > > people prefer? > > The traditional Pylons way is to assign them to 'c' variables > ('tmpl_context' attributes), and access them in the template as > '${c.foo}'. The reason for this is historic. Myghty predated Pylons, > and Myghty had several magic one-letter variables, 'c' being one of > them. It follows a certain MVC pattern, 'c' being a scratchpad for > request-local variables. 'c.' also makes it easy to tell in the > template whether the variable was defined in the template or came from > higher up. > > Older Pylons (0.9.6 and earlier) had a render function that took > keyword args for variables. but the official way was to use 'c'. The > keyword args were eliminated in 0.9.7 to confirm to the Python > principle "There's Only One Way To Do It". > > But it does make a difference between Pylons and TurboGears, with > doesn't normally use 'c'. A TG action returns a dict of variables, and > the @expose decorator applies them to a template. This means you have > to add 'c.' or remove 'c.' when porting templates to/from TG. > > You can make a new render function that does what you describe, but > you'd have to write it yourself. > > > 3) Segregation of display functions from other processing > > This is a more general encapsulation question suggested by the > > previous question. We COULD, if we wanted to, have the controller add > > ITSELF to the template context. The template, then, would have access > > to all the functionality that the Controller embodies. Alternatively, > > we could put just the Controller's methods into the template context. > > Or we could just pass in literals. Where do folks draw the line? > > This gets into the alternative MVC theories. The Pylons/TG tradition > is that the model knows only about itself, the template knows only > about itself and its context variables, and the controller knows about > both the model and the template. Some developers allow the template to > access the model for trivial lookups (e.g., to expand abbreviations), > but not for the main action data. > > Another tradition, which I've seen in Java and wxPython apps, moves > the database out of MVC. The controller instantiates a model and > passes it to the view. The model is a class which contains the data > the view needs, or what Pylons calls 'tmpl_context'. But in this other > MVC it's a class designed specifically for this view, not a generic > container. There's also a scratchpad, a set of request-local data > which is available to all the utility methods and the view. > > And of course, Django calls the controller the view, and the framework > the controller. > > What you're talking about is something different still, the view > knowing about the controller. Although that could be reconciled with > the Java MVC if we equate the controller with the model. > > See how confusing it gets? "Who's on first? --No, What's on first. > --No, What's on second; Who's on > first."http://www.phoenix5.org/humor/WhoOnFirst.html > > What you seem to be getting at is, there's no place for view logic in > Pylons except in the template. And Python code in the template is hard > to debug unless it's short and simple. So people put it in the > controller instead, even if it's view logic. This could be alleviated > if there were a view object for every view, and the view object > managed the template. You could do this with Pylons, but you'd have to > write it yourself. I don't know of anyone who has written an > application this way, but it sounds good theoretically. > > Putting the controller into the view means the view would have access > both to things that are appropriate for it, and things that are not > appropriate for it. It might make it harder to port the templates to > another framework later. Part of the philisophy of MVC is that any > part can be replaced without changing the other parts. Also, there's > 'h' ('helpers'), which is a set of more-or-less generic functions > which are useful in multiple views and controllers. That's another way > to get logic into the templates. > > -- > Mike Orr <[email protected]> -- You received this message because you are subscribed to the Google Groups "pylons-discuss" group. To post to this group, send email to [email protected]. To unsubscribe from this group, send email to [email protected]. For more options, visit this group at http://groups.google.com/group/pylons-discuss?hl=en.
