Description
static
In _scaffold and a few other example apps, the static folder is defined in settings.py like this:
py4web/apps/_scaffold/settings.py
Line 28 in e9f28a5
This setting is never used anywhere, and is completely skipped by the fact Reloader.import_app has a static path of <appname>/static/<path>
, hardcoded here:
Lines 1445 to 1450 in e9f28a5
templates
Theres no settings.py setting for templates yet. The template path is hardcoded by a combination of the Template.on_success method:
Lines 619 to 624 in e9f28a5
And the fact instances of Template are created based on a str in action.uses:
Line 969 in e9f28a5
This means using the normal way of adding templates, by using a str as an argument to action.uses, it's impossible to set the Template.path attribute. To change the Template base path, a user would have to explicitly create Template instances for each individual controller.
issues
Currently, py4web only seems to separate multiple apps by their routes in Reloader. Any global values py4web exposes are either utilizing thread locals scoped to the request, or are potentially shared between all apps. This means a simple global variable which the user can overwrite would change this variable for every app.
solution
One possible solution, which I quite like, would be a App
class which owns app-specific configuration. For new apps, this would be instantiated in common.py and passed the relevant information like static path, template path, and possibly other per-app config.
py4web could store instances of App
by app_name, where each App
instance stores its own routes, error handlers, and possibly other related data (ICECUPE
? a bottle application object?).
action
could then be a method or property of App
. For easier migration, users could set action = myapp.action
in common.py and import this instead of py4web.action
in controllers.
The App object could also define methods for Reloader
to use, like App.unload()
which removes this instances routes and maybe even unloads the modules, and App.load()
which implements some of what Reloader.import_app()
currently does, like registering the static route (this is one way the static path could be read from the App instance)
Doing reloading like this could allow for easily implementing a pre_unload callback, for apps to do their own clean-up before they're reloaded.
To maintain backwards compatibility without any user interaction, py4web could define action
using a (subclass) of App
containing the current default logic, then expose the normal action with action = default_app.action
.
A App
class like this with an instance per App, would also allow easily defining other utilities like global Template helpers which are currently made more difficult by the fact theres no way to store per-app data.