On Fri, Aug 6, 2010 at 8:53 PM, BrianTheLion <[email protected]> wrote:
> Assume for a moment that we are writing a Facebook work-
> alike in Pylons. Then, a GET of http://pylonsfacebook.com/user/brianthelion
> would be a request - and I'll use Facebook-speak here - to view
> BrianTheLion's "profile." If we're following the REST formula that
> we've argued for, then UserController.show(id=brianthelion) is getting
> executed. Awesome.
I have never seen a social network site or user-profile site that used
REST or even good URLs. It's usually some horrible monstrosity like:
/viewpicture.php?imageid=1234&friendid=5678§ion90&size=small$feature=fl
Those irritate me. Yet the sites are successful and profitable, and
most users aren't complaining about the URLs. If a site can at least
get one URL right, the user's main page as "/username" or
"/uisers/username", that's a big step.
> At this point in the example, though, there is giant code-hole. On
> Facebook, a user's profile is an extremely complicated UI. It's a
> "hybrid view" (is there a better term?) of data from many different
> model entities: user, event, photo, message, mail, news, etc, etc. To
> build our work-alike, we need to take information about the user, the
> events he's invited to, the photo's he's in, the things his friends
> are saying, etc, and render all of that to fun-to-look-at HTML. So,
> the context of our PylonsFacebook, the question is: How does
> UserController.show() go about producing this immensely complicated
> output? How should all of the code between HTTP and HTML - and there's
> a lot of it; the majority, in fact - be encapsulated? How can we best
> make it reusable?
I don't know if there's a single answer, because every site has
different kinds of entities. If the problem is similar HTML chunks to
display the same image thumbnail or message in different places, the
answer is probably a Mako #def method. You can put these in a utility
template and import them.
If the problem is a chunk of Python code that's used on several pages,
you can make them into methods in the base controller, helper
functions, or lib functions. I prefer to keep everything that accesses
the magic globals in controller methods, but some others put them in
functions. I would use helpers only for things that will likely be
called from templates, and put other logic in lib functions or
classes.
There is an argument for putting as much of the site's functionality
as possible into the model or lib classes -- everything that's not
Pylons-specific or UI-specific. That way you can use it outside the
webapp or with another framework should the need arise.
I would read the Mako manual closely, especially the #def,
inheritence, and call-wtih-content sections. Mako is powerful and you
can do a lot with it.
However, some people don't like text-based templates. Some people
prefer objects that know how to render themselves, and a Stan-like or
Breve-like template language, where the structure of the HTML is
expressed by Python objects. Tavis Rudd, who wrote the Cheetah
template system, has this intriguing anti-template system called Throw
Out Your Templates.
http://bitbucket.org/tavisrudd/throw-out-your-templates/src/tip/throw_out_your_templates.py
However, it's not as good if your pages tend to have paragraps of
static text as mine do. (Instructions here, a FAQ there, etc.)
> SQLAlchemy aside, this territory seemed pretty lawless to me. In my
> naivety I came up with the idea of "named views." For example, a GET
> of http://pylonsfacebook.com/photo/981388324/icon and
> http://pylonsfacebook.com/photo/981388324/full would render the "icon"
> and "full res" views of that photo, respectively. Pretty self-
> explanatory. This made some nice sense because then for the
> PhotoController I'd have a "show_icon" method and a "show_fullres"
> method, as well as a "photo.mako" with "icon" and "fullres" defs. The
> rendered HTML output of the aforementioned URLs served as nice visual
> building blocks for more complicated web pages, and GET-ing them
> allowed me to test the code easily.
>
> I ran into problems, though, when I started needing to build "hybrid"
> views, named views that depended on other named views. For example,
> http://pylonsfacebook.com/user/brianthelion/photos would call
> UserController.show_photos(id=brianthelion). It's output would depend
> on the output of, say, PhotoController.show_icon(id=29459285) and
> PhotoController.show_icon(id=299498594). So then I'd need to
> instantiate a PhotoController from within my UserController, and that
> seemed - at least in MY mind - to break the Pylons paradigm.
No, don't have one controller call another. Put the method in the
base controller. Or if there's a group of methods that only certain
controllers will use, make an intermediate class (a subclass of
BaseController) to put the methods in. Or you can use helper
functions or lib functions if you prefer..
The /photo/1234/full and /photo/1234/icon URLs look as good as any.
--
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.