Use the same view in multiple models¶
Author: | Peter Bengtsson |
---|
If you have multiple models each with their own views, perhaps you want all views to have access to one view in common.
Purpose¶
You want all views in all models of an application to have access to a view without having to redefine this view in each model. For example you have a master template that defines the viewlet managers or METAL
macros and you want all “sub views” to be able to use this.
Prerequisities¶
Suppose you have a simple Grok application up and running and you’ve defined another model other than the application one called Term
in a file called term.py
like this:
## app.py
class App(grok.Application, grok.Container):
pass
class Index(grok.View):
# see app_templates/index.pt
pass
class Master(grok.View):
# see app_templates/master.pt
pass
-------%<-----------------------------
## term.py
class Term(grok.Model):
pass
class Index(grok.View):
# see term_templates/index.pt
pass
Now, the App
model has two views: index
and master
. The Term
model has only one view: index
. In both files called index.pt
it says something like this on the very first line:
<html metal:use-macro="context/@@master/macros/page">
That works fine for app_templates/index.pt
but will give you a TraversalError
if you try to do the same in term_template/index.pt
.
Step by step¶
The solution is really simple. Basically, change the Master
view to this:
from zope.interface import Interface
class Master(grok.View):
grok.context(Interface)
With this you’ll be able to reach context/@@master
in any of the templates of your application which achieves the goal. Think of grok.context(...)
as a filter mechanism that attaches itself into the “namespace tree” of your application at a certain “branch”. By saying the context is Interface
you’re almost attaching the view to the trunk of the trunk.
Further information¶
An alternative solution would be to use a base class and attach the Master
view to that. Then you let all other models also subclass this base class and they get the shared functionality too. That approach has the advantage that it’s more “standard pythonic” but you’re then not using the powerful patterns that Grok offers plus you have to remember to add the base class on all other models which adds noise to the code.