I know there are ways to do this without too much problem, I just thought
that since so much is changing it might be a good idea to come up with a
"sensible default" way of doing it, and add whatever support was necessary
to make it dead simple.

This question has come up on the ML multiple times and it seems a good "pain
point" to address.  Haven't had much use for it myself.

Kevin Horn

On 5/31/07, Jorge Godoy <[EMAIL PROTECTED]> wrote:
>
> Another option is using Genshi and its xinclude tag.  With that and some
> parametrization you can achieve what you want (I do that sharing the same
> code and templates for several modules of my main application and using two
> different layouts from specific client's designs).
>
> It isn't hard and I believe there are recipes on Genshi's wiki.
>
> On 5/25/07, Elvelind Grandin <[EMAIL PROTECTED] > wrote:
> >
> >
> > well. using a template form another project is simple since we are
> > using the dot notation (project.templates.file). however, you can do
> > .template.file and it will look in the current project. adding an
> > config option for that would be a no brainer.
> >
> > On 5/25/07, Kevin Horn < [EMAIL PROTECTED]> wrote:
> > > Has anyone considered how to support multiple apps sharing the same
> > > templates?  This would make it easier to combine multiple apps and get
> > the
> > > same "look and feel".  I have seen this requested several times on the
> > TG
> > > MLs.
> > >
> > > Could we make the templates directory a configurable option in the
> > config
> > > file, which defaults to the standard templates directory?  I haven't
> > thought
> > > the full implications of this through, but it seems like a
> > (relatively)
> > > simple option that might get us moving towards achieving this goal.
> > >
> > > Any major problems with this strategy?
> > >
> > > Kevin Horn
> > >
> > >
> > > On 5/24/07, Alberto Valverde <[EMAIL PROTECTED] > wrote:
> > > >
> > > >
> > > > On May 22, 2007, at 11:07 PM, Alberto Valverde wrote:
> > > >
> > > > >
> > > > >
> > > > > On May 21, 2007, at 10:53 PM, Ian Charnas wrote:
> > > > >
> > > > >>
> > > > >> So are we still on for a TurboGears sprint this upcoming
> > saturday?
> > > > >> How do we do this?  Do we all jump on IRC at a certain time and
> > > > >> decide
> > > > >> what to do?
> > > > >
> > > > >   It'll be probably be good to open up a page in the docs.tg.orgwiki
> > > > > to make some planning...
> > > > >
> > > > > I'll be in to work on a new test infrastructure to eventually port
> > > > > all failing controller tests to put TG back in the "green" zone.
> > The
> > > > > other big task needing work is poring the config module to CP3's
> > new
> > > > > config system . Some coordination between my work and the "config
> > > > > team" is needed since a pre-requisite to my part is to have a TG
> > app
> > > > > nicely wrapped in a WSGI app (possibly with a paste.app_factoryentry-
> > > > > point implemented) since I'm planning to use paste fixture for the
> > > > > testing.
> > > > >
> > > > > Some notes + brainstorming:
> > > > >
> > > > > CP3 uses the Application object to create the mentioned WSGI app
> > > > > which receives the app's config as a constructor's parameter so
> > we'll
> > > > > have to agree on how we create initialize this object. Maybe
> > > > > something like this:
> > > > >
> > > > > - add a new wsgiapp.py module inside quickstarted apps which
> > > > > implements the paste.app_factory entrypoint to return a TG/CP3
> > app.
> > > > > This module uses some helper functions inside TG's startup.py (or
> > > > > even a TGWSGIApp Application subclass) to initialize and stack
> > TG's
> > > > > specific middleware (none ATM, expect EvalException, but we need
> > to
> > > > > leave room for future growth).
> > > > >
> > > > > - This entrypoint could be called by PasteScript's paster passing
> > a
> > > > > paste.deploy config file which would override config parameters
> > > > > defined in well knownt app.cfg et al. tg-admin should grow a new
> > > > > "serve" commad (which delegates to paster serve) which loads a TG
> > app
> > > > > with no paste.deploy config and mounts it at /. This new "serve "
> > > > > commands deprecates good 'ol start-myapp.py (which can be left as
> > a
> > > > > backwards compatibility artifact which simply delegates to
> > tg-admin
> > > > > serve).
> > > > >
> > > > > A quick mental topological sort leaves tasks in this way:
> > > > >
> > > > > 1) wrap TG apps with CP3's Application object
> > > > > 1.5) (at this point I can start migrating the testing framework)
> > > > > 2)  this Application object receives an app config dict so...
> > adapt
> > > > > current config.py so it can load TG' config and pass it to the
> > > > > Application constructor. The "config" team could work on a rewrite
> > of
> > > > > the config module so it produces a properly formatted config dict
> > to
> > > > > feed to Appliaction)
> > > > > 3) implement the paste.app_factory entry point which can receive a
> > > > > *possible* paste.deploy config or a dummy one that points to
> > app.cfg
> > > > > and returns this WSGI app object. The possible paste.deploy config
> > > > > should override values in app.cfg if present.
> > > > > 4) implement the tg-admin "serve" command
> > > > > 5) glue all this together so "tg-admin serve my.config" launches a
> > TG
> > > > > app and start-myapp delegates to this
> > > > >
> > > > > Sorry for my poor communication of this ideas.... I'm speaking
> > from
> > > > > memory and it has been months since other work has displaced this
> > > > > task from the foreground of my badly multi-tasking brain ;)
> > > >
> > > >
> > > > Yesterday I comitted some changes on the trunk implementing these
> > > > ideas. Some comments:
> > > >
> > > > - turbogears.config is now a paste.config.DispatchingConfig which
> > > > provides conetxtual config for each TG app mounted in the same
> > > > process. It preserves the original inteface (update_config, update,
> > > > get) plus, being a proxy to a dict, has now other useful methods
> > like
> > > > items, __getitem__, __setitem__, etc ("items" will be specially
> > > > useful in view.load_engines to dump all available template engine
> > > > options to each engines, no need to "cherry-pick" them one by one.
> > > > It's structure is something like this:
> > > > {"/": {config options for the current app, this key is accessible at
> >
> > > > cherrypy.request.config during a request},
> > > >   "tg_widgets": {tools.staticdir.on: True, tools.staticdir.dir:
> > > > "some_dir"},
> > > >   ....}
> > > >
> > > > The preferred method of accessing app configuration is through
> > > > turbogears.config which proxies to the dict that was merged with the
> > > > apps config at the app factory. cherrypy will use each path's key
> > > > when calclating which tools to apply depending on the path.
> > > >
> > > > - The WSGI app is built inside the users app at
> > > > myapp.wsgiapp:WSGIApp.app_factory.
> > > >
> > > > This is the paste.app_factory entry point. Most work is done in the
> > > > superclass (defined in turbogears.wsgi) but, being the final
> > subclass
> > > > available inside the users app it allows for easy customization, eg:
> > > > * __call__ can be overriden to execute per-request actions, branch
> > to
> > > > other wsgi apps, etc... This function has the WSGI app signature
> > > > (environ, start_response) so the full flexibility of WSGI is
> > > > available at this point.
> > > > * app_factory can be extended to further wrap the app in middleware
> > > > between the resuting TG app (and all its middleware) and the server
> > > >
> > > > def app_factory(self, global_conf, root=None, full_stack=None,
> > > > **app_conf):
> > > >         app = super(...).app_factory(....)
> > > >         app = MyMiddleWare(app, ...)
> > > >         .....
> > > >         return app
> > > >
> > > > Note that middleware stacked here will be outside TG's context
> > > >
> > > > * __init__ can be overriden to stack middleware below the TG app.
> > > > This middleware will be inside the context of the TG app:
> > > >
> > > > def __init__(self, root=None):
> > > >         super(....).__init__(root)
> > > >         self.wsgiapp = MyMiddleware( self.wsgiapp, ....)
> > > >
> > > > Note that this middleware can also be declared in the CP3 config
> > file
> > > >
> > > > - There are some architectural changes needed to allow for multiple
> > > > apps per process:
> > > >
> > > > * We're making heavy use of module globals for customization
> > > > (view.variable_providers, view.loadBases, scheduler, database.engine
> > ,
> > > > etc...) This should be modified because these globals will be shared
> >
> > > > by all instances of TG apps used in the same process, extension
> > > > authors should pay special attention to this...
> > > >   The solution I've comed up with is to provide a proxy at
> > > > turbogears.globals which proxies to app.globals (a globals object
> > > > bound to the WSGI app that wraps the root controller). This way all
> > > > these globals will be in the context of the WSGI app that configured
> >
> > > > them during a request. I've implemented view.engines this way (so
> > > > each app can have it's own kid.defaultoutput, etc...) but others
> > > > still need to be ported/rewritten (database.engine , scheduler, etc)
> > > >
> > > > - Since the app_factory ep is implemented, paster can already be
> > used
> > > > to launch a TG app. I've made the changes needed to the quickstarted
> > > > template so you can try it out like this:
> > > >
> > > > $ paster serve depoly_cfg.ini
> > > >
> > > > Which should have the same effect as calling start-myapp.py (I've
> > > > rewritten start_turbogears so 1.0 startup scripts remain
> > compatible).
> > > > start-myapp.py should be deprecated so all apps are loaded using the
> > > > paste.deploy API. Since the minimal deploy ini config file is so
> > > > simple, "tg-admin serve" could emulate what it does when no
> > > > deployment config is specified, so when you run "tg-admin serve"
> > > > inside a projects egg it should start up the app automatically. If a
> > > > deployment config is passed as a parameter, it should use that
> > > > instead. Some cool things you can already do with this:
> > > >
> > > > [DEFAULT]
> > > > [server:main]
> > > > use= egg:PasteScript#cherrypy
> > > > host = 0.0.0.0
> > > > port = 8080
> > > >
> > > > [composite:main]
> > > > use = egg:Paste#urlmap
> > > > / = app1
> > > > /app2 = app2
> > > >
> > > > [app:app1]
> > > > use = egg:TestApp
> > > > app_id = app1
> > > > tg.config_file = %(here)s/dev.cfg
> > > >
> > > >
> > > > [app:app2]
> > > > use = egg:TestApp
> > > > tg.config_file = %(here)s/dev.cfg
> > > > app_id = app2
> > > > kid.encoding = iso-8859-1
> > > > kid.outputformat= xhtml
> > > >
> > > > This will mount the same TG app at / and /app2 but with different
> > > > configuration settings (they could even use different dev.cfg and
> > > > dev2.cfg) and serve it with CP3's wsgi server (swap it with Paste's
> > > > if you feel inclined to for didactical purposes)
> > > >
> > > > Please note that multiple apps per process is still broken since we
> > > > use so many module globals. I haven't tested it yet but, for
> > example,
> > > > I believe both apps would share the same db engine... this needs to
> > > > be sorted out.
> > > >
> > > > Some low hanging fruit we need need to address:
> > > >
> > > > * rewrite view.load_engines so it all template plugin confg options
> > > > can be used. Maybe even replace the whole view module and implement
> > > > it as a class we can instantiate and bind to turbogears.globals so
> > > > each app has it's own configured set of engines. This is implemented
> > > > in TW as the EngineManager... maybe we can take ideas from there,
> > or,
> > > > better still, factor it out into an independent egg both TW and TG
> > > > can share.
> > > > * Move the scheduler to turbogears.globals, so each app has it's own
> > > > scheduler
> > > > * Ditto with database.engine
> > > > * more I'm failing to recall....
> > > >
> > > > Some more complex stuff:
> > > >
> > > > * Move all module globals: view.variable_providers,
> > > > turbogears.call_on_startup, etc so they're bound to each app. This
> > > > will require a change to the extensions API to work properly,
> > > > however, a proxy can be left at the original location for backwards
> > > > compatibility. This allows for a smooth degradation: non conforming
> > > > extension will still work in a single app per process scenario, but
> > > > will break when multiple TG apps cohabitate the same process....
> > this
> > > > will put some pressure on extension authors to upgrade them ;)
> > > > * Write the new testutils using paste fixture to port all TG
> > > > controller tests.
> > > > * more I'm failing to recall....
> > > >
> > > > Well, gotta run now...  comments welcomed :)
> > > >
> > > > Alberto
> > > >
> > > > PS: Looks like Saturday's sprint is going to be lots of fun! :)
> > > >
> > > > > >
> > > >
> > >
> >
> >
> > --
> > cheers
> >     elvelind grandin
> >
> >
> >
> >
>
>
> --
> Jorge Godoy     <[EMAIL PROTECTED]>
> >
>

--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"TurboGears Trunk" 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/turbogears-trunk?hl=en
-~----------~----~----~----~------~----~------~--~---

Reply via email to