On Mon, Apr 27, 2009 at 2:22 PM, Jonathan Vanasco <[email protected]>wrote:

> The way Pylons works, you can't really consolidate all the Plugin
> stuff as 'neatly' as with other systems: ie- you can't really do an
> isolated tree that offers it's own MVC directories.
>
> But you can do something where you can import 'shared' controllers or
> models, and then just subclass them or use as-is.. and have your own
> templates folder.
>

This is effectively how I did it, back in the day when I was doing stuff
like this.  It might be useful to describe this, as it at least worked, even
if it didn't feel incredibly decoupled (and maybe this can't be that
decoupled).  I think it helps to enumerate the issues; my personal pet peeve
with these plugin discussions is that they aren't sufficiently rooted in use
cases.

This was at my previous employer, Imaginary Landscape, where we did lots of
bespoke web sites, and we were starting to create reusable web applications
for clients.  A typical client would use 2-5 applications we sold them,
integrated into one site and customized to some degree.  We used Paste, and
it looked pretty similar to what Paste is currently, as well as PasteWebKit
for the framework (which is crufty but workable).

Each application was an independent application, in exactly the way a Pylons
application works.  Each time we set up an application we'd edit the Apache
configuration to redirect a certain path (e.g., /gallery/) to the client's
Paste server.  We used one server per client.  Then we had configuration
like:

# main.ini
[DEFAULT]
site_name = bobs_food_emporium
site_title = Bob's Food Emporium
auth_secret = 59482e34d
... a couple other client-specific variables here ...

[composite:main]
use = egg:Paste#urlmap
/gallery = config:gallery.ini
/menu = config:menu.ini
/login = config:login.ini
... etc ...

#gallery.ini

[app:main]
use = egg:IscapeGallery
... some gallery-specific configuration ...


>From there most of the rest of the framework happened in a single controller
superclass we had.  It was entirely equivalent to having a BaseController
subclass that all your application in turn subclass from.  Anything that
would go in the Pylons helpers module would typically be a method on the
this class, so it all got carried over.  There was also a simple dispatch
system that made it possible to mix in some functionality (
http://svn.w4py.org/Component/trunk).  For instance, the template renderer
used that (http://svn.w4py.org/ZPTKit/trunk).  We didn't *have* to use this,
because we didn't really need to remix these pieces -- we always used Zope
Page Templates, we always used the same auth system (
http://svn.w4py.org/LoginKit/trunk) etc.  But I developed this stuff long
before this system, so it did make it possible to incrementally do this
development.

All our applications used a template search path, in something like
/www/sites/${client_name}/templates/${app_name}/${template_name}.  This was
a *huge* feature for us, because 90% of the client customizations we did, we
did by copying a template from the application into this directory and
changing it.  No programmers needed to be involved in doing this.  Towards
the end of my stint we were thinking about making this more pluggable so
simple text changes didn't require copying templates (basically so there was
a through-the-web interface to customize all the little chunks of text).

Also, all applications used templates that subclassed from one of two
templates (an admin template for internal screens, and a site template).
This template was big and hairy and drew heavily from code in the common
subclass.  This arranged all the navigation, which included all the
applications in the system.  To get a list of all the applications and a
bunch of configuration about how they were laid out, there was a second
config file.  This config file regularly referred to things that weren't in
Paste or might not have even been hosted locally (per this pattern:
http://blog.ianbicking.org/2008/12/27/avoiding-silos-link-as-a-first-class-object/).
This file could use indirection similar to how "use = config:..." works in
Paste Deploy config files, and it would look like "use = egg:MyApp", and it
would look for MyApp.egg-info/iscape_tool.ini, and you could override
specific values from that.

For identification we used auth_tkt cookies, and authentication was checked
in the superclass (in the equivalent of __before__).  An application was
always mounted at /login that could actually set this cookie.  We didn't use
middleware.

For authorization we eventually created a system where we'd define
application-local permissions, and then map those to site-wide roles via an
XML file, which we could override on a per-client basis.  Applications would
manually check for permissions.  A separate application managed users and
permissions (built into the login app, I believe).  We put a lot of this
role information into the auth_tkt cookie (database sharing wasn't
necessary), though eventually it got to be too big and we had to refactor
that.

A non-code feature that was important was a stylesheet.  That is, an HTML
page that listed how you use markup and CSS styles.  This was the primary
way visual consistency was attained.  Without this consistency you can't
really expect things not to look like a mish-mash, and serendipity of using
the same styles without that is uncommon or at least error prone.

Hmm... that most of what we did, I guess.  Well, also stuff like workingenv
which became virtualenv for package management, and stuff like
sqlobject-admin for migration and paster make-config/setup-app for
deployment -- some of those things never were really finished, which is why
you might notice some inelegance.

I think in terms of scope it was similar to Pinax.  Django itself doesn't
integrate in quite that way.  You could of course build just this on Pylons
as well.  It wouldn't *be* Pylons, but you'd certainly be no worse off for
using Pylons as a starting point.  It always was fairly workable for one-off
applications, it didn't involve any terrible conceptual overhead.  Which is
kind of true for Django too... just because it's more integration focused,
you can still ignore that stuff and use it as a simple framework.

-- 
Ian Bicking  |  http://blog.ianbicking.org

--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to