For TurboGears 0.8, I wanted to be able to easily deploy a couple of
TurboGears apps on a single site using CherryPy idioms. (Actually, the
*main* goal is to be able to deploy an app as an egg... it's a
secondary goal to deploy multiple apps.) Note that moving to Paste
Deploy may be a good solution for some issues, but TurboGears 0.8 will
not use Paste Deploy due to timing, if for no other reason.

This whole long message is all about packaging up of apps for other
people to use and using multiple TurboGears apps within a single site.
If that's not of interest to you, you'd better run for the exit now.

What do I mean by "CherryPy idioms"?

class UserStuff:
    blog1 = Blog()
    blog2 = Blog()

class Root:
    users = UserStuff()

This gives you two blogs at "/users/blog1" and "/users/blog2". This
example is complicated by the fact that these are not two *different*
apps, but rather two instances of the same app. Keep in mind, too,
that while these two blogs are just statically created with those
names, you could conceivably have any number of them with any names,
given Python's dynamic nature.

Let's look at the complexities here and some possible solutions:

1) URLs within an app

If the blog application tries to go to "/" to get to the top of the
blog, it's actually going to go to the top of the server. TurboGears
0.8 already has a way to deal with this: str(URL("/")) will give you a
link to the "application root". In other words, something like
/users/blog1. If the whole thing is being proxied behind an Apache
site at /foo, you can also configure it so that the URL would be
/foo/users/blog1.

2) Static files and other filter configuration

Static files are configured in the config file by specifying the path
to apply the static filter to. The paths in these configurations would
need to change to take into account where the root of the application
is.

This is tricky. The current version of the URL class computes the
application root based on the path traversed to get there. When you
instantiate blog1 above, there is no way for it to know that its path
(for CherryPy purposes) is /users/blog1 and that /users/blog1/static
should be configured for serving up static files.

It's easy enough to tell CherryPy to use a static filter via
_cpFilterList. The problem is that the static filter needs its
configuration set up for the correct path. But that path is not known.

You *could* just put the static paths into your final config file
manually, but that's ugly. Plus, it doesn't work if the Blog instances
are created dynamically (from a database, for example).

If there is some reasonable way to figure out the path for the sake of
the configuration, then this problem will go away. It makes me think
of acquisition from Zope (you basically want to acquire the
application root and its path).

My conclusion for this one is that the way the static filter works
right now is probably just not appropriate for applications that you
want to distribute. It would be possible to make a static
file/directory object (which is similar to how Nevow handles static
files) that you could just instantiate in your app's class. That
doesn't help with other filters, though.

I would be curious to know if Paste Deploy has something to handle
dynamically created application instances. I did see references to a
factory in the docs, so I'm guessing that's the key... I'm just not
sure how the URL paths hook up.

3) Database configuration per webapp

Dave Warnock just brought this up: each application instance may want
its own database. This has some of the same configuration issues as
the static filter problem above, plus the added bonus of wanting to be
able to use tg-admin sql create to get your database(s) set up.

Assuming you're not dynamically creating Blog instances, it is
reasonable to have your site configuration file include database URLs
for each path that requires a different one.

There is the added complexity here that maybe you want to have
multiple blogs, but you want them to share a database. If the blogging
app itself wasn't designed for this, then you'd need to do something
like adding a table prefix... which is actually plausible, using
SQLObject.

Zope, while having some issues of its own, does make it pretty darn
easy to plug together sites because the storage moves along with the
application instance.


The tools available in TurboGears 0.8 make it possible to hook up
multiple *different* TurboGears apps in a single site pretty easily.
Even the database stuff is dealt with, because your site's model.py
can just do "from blog.model import *", so that a standard tg-admin
sql create works just fine.

Given that, I think I'll likely punt on the hard questions for a
moment to get TurboGears 0.8 out.

I love working with CherryPy, but we do need to answer these questions
so that everyone isn't forced to write their own blog :)

--
Kevin Dangoor
Author of the Zesty News RSS newsreader

email: [EMAIL PROTECTED]
company: http://www.BlazingThings.com
blog: http://www.BlueSkyOnMars.com

Reply via email to