[Zope] DTMLFile question -- half solution

tomas@fabula.de tomas@fabula.de
Thu, 15 Aug 2002 14:37:16 +0200


Hi,

just in case someone is interested in how it's turning out.

As a reminder: My aim was to use DTML methods on a product without
`declaring' them `by hand' in the product class definition. That
is, instead of having:

  | class CMSResource(...):
  | 
  |   ...
  |   manage_workspace = DTMLFile("dtml/CMSResource/workspace",  globals())
  |   manage_main      = DTMLFile("dtml/CMSResource/main",  globals())
  |   manage_edit      = DTMLFile("dtml/CMSResource/edit",  globals())
  |   ...

  ad nauseam,

I'd have a class method `render(name, ...)' which would lookup a dtml
matching `name' (in whatever application-specific way) and instantiate
it. (Of course, it might make sense caching this instantiation in some
way).

My approach now is to dynamically create the DTML class methods, like
so:

  | def component(self, name, ...):
  |   if not self.__class__.__dict__.has_key(name):  # FIXME: elegance?
  |     # Add this attribute to the class as a DTML method.
  |     # The Python Gods will surely punish me [REST CENSORED]
  |     self.__class__.__dict__[name] = \
  |         DTMLFile("dtml/CMSResource/components/" + name, globals())
  |   return eval("self.%s(self.REQUEST)" % name) # FIXME Anything better than eval?

It works -- in a way. The thing finds the right file in the directory
given, transforms it into a DTML method and this gets called alright.
That is, invoking res.component("foo") will render the DTML in file
`dtml/CMSResource/components/foo.dtml' -- but the name space is gone:
that's to say the dtml code within this file doesn't `see' the things
I'd expect it to (e.g. CMSResource's methods and that).

Comments? Ideas? Is there a better way to achieve this? Am I totally
crazy?

Regards
-- tomas