Integrating ToscaWidgets with a Web Framework

ToscaWidgets functions as WSGI middleware, so it can integrated into most WSGI frameworks with ease. There are a few points where closer integration is needed; this is handled by the tw.mods.base.HostFramework class. The middleware performs two main tasks:

  • Initialises a request-local storage area
  • Rewrites the generated HTML to include the required JS/CSS links

In most cases the middleware can do this correctly without assistance. However, the rewriting of generated HTML can interfere with framework features, such as cacheing. This is known to occur with Pylons, although there is a workaround. Also, the request-local storage assumes that each request is mapped to a thread. This is generally the case, but is not true for non-blocking frameworks, such as Twisted.

ToscaWidgets needs to be able to generate absolute URLs for resources (e.g. JavaScript or CSS files). Usually resources exist inside the /toscawidgets path. However, if the whole application has a prefix, this would be /myapp/toscawidgets. Currently, ToscaWidgets automatically does this correctly for TurboGears 1, but not for other frameworks.

Configuration

The middleware has several configuration parameters. The simplest approach is to hard-code these in Python code, which avoids framework-specific code. However, it is preferable to integrate with the framework’s configuration system. So far, configuration integration has only been deveoped for Pylons and TurboGears 1 and 2.

The most important configuration parameter is default_view - this is the name of the default templating engine that the framework uses. Root widgets (those with no parent) will be rendered so that they display correctly in the default templating engine.

Validation

When using tw.forms, the validation needs to be applied at some point. The simplest approach is for the developer to explictly call form.validate(params), and this avoids any framework-specific code. However, under some frameworks, there may be a more natural way to do this. For example, the natural TurboGears approach is to use the @validate decorator on the controller method. For Pylons and TurboGears 1 and 2, a suitable decorator is supplied to allow this pattern.

If there has been a validation error in the current request, a form widget is redisplayed with the original values, rather than the supplied values. This behaviour applies to all frameworks.

Potential Closer Integration

There are a few areas where the use of ToscaWidgets could be enhanced by closer integration. However, these are relatively rare use-cases, and ToscaWidgets aims to be framework independent, so the benefits do not justify the closer integration.

ToscaWidgets contains strings that are displayed to the user and so needs to support internationalisation. The current approach is that to enable this, the developer must manually specify a translator function. In principle, it could automatically detect this.

In the case that a page uses a non-default templating engine, it is necessary to manually override this using the displays_on argument to the root widget’s display method. In principle it would be possible to have ToscaWidgets detect this automatically.

Widgets are created in Python code and need to be passed into a template for display. The simplest, and recommended, approach is to use the same method as the framework provides for passing any variable into a template. There have been attempts to create a “widget registry”.

Implementation Notes

Under CherryPy 2 (and TurboGears 1), ToscaWidgets functions as a CherryPy filter. Under CherryPy 3 (and TurboGears 1.5), it functions as a CherryPy tool. This is necessary as CherryPy dispatches requests to a different thread to that in which the WSGI middleware was called, which would break the request-local storage.

ToscaWidgets versions prior to 0.3 worked in a different way and required closer integration with the framework.