Hi there, Since I hear Python scripts inside the Zope system are in their Inception phase now, I thought I'd contribute with some ideas. What I'm thinking about is how to emulate the DTML experience in Python. DTML is nice in that it provides a fairly simple interface into the Zope database, but less nice because fancy things tend to become extremely cumbersome and complicated in DTML while they wouldn't be so horrible in Python. Current ways to use Python tend to be even more cumbersome for various reasons (external methods not editable from the web, products are often overkill), however. One other reason why Python might still remain overkill even when it's editable from the web is the interfacing with Zope. This proof of concept tries to emulate DTML's way to use the Zope database in Python code. This way people won't have to learn two different systems and run into trouble when switching back and forth from DTML and Python documents. The proof of concept code does *not* tie into any Zope system, it's just an attempt to demonstrate my idea of DTML-like constructs in Python. There are various caveats, such as the HTML that's produced currently being all rendered to one line. That can be solved by adding \n in places, but perhaps there's a nicer way still. Enjoy reading the code. :) Regards, Martijn ---- The actual code ---- # Just a proof of concept only! Not based on any actual Zope code, just # tries to imitate it vaguely. :) from array import array class Error(Exception): """Simplistic error. """ pass class PyDocument: """A PyDocument is like a DTML document, but in reverse. Program logic with embedded HTML, instead of the other way around. The idea is not to replace current DTML documents, which work fine as a reporting language, but to provide a starting place for Python Script Documents in Zope. """ def var(self, name): """Like var tag, name attribute only. No expr attribute supported. """ obj = self.namespace.get(name, None) if obj != None: self.buffer.fromstring(obj(self.namespace)) else: raise Error, "The name %s does not exist in the namespace." % name def call(self, name): """Like call tag, name attribute only. """ obj = self.namespace.get(name, None) if obj != None: obj(self.namespace) else: raise Error, "The name %s does not exist in the namespace." % name def HTML(self, data): """A way to include HTML code. (or any text, perhaps rename this method to 'raw' or something). """ self.buffer.fromstring(data) def __call__(self, namespace): """Render this PyDocument. """ self.namespace = namespace self.buffer = array('c', "") self.script() return self.buffer.tostring() def script(self): """Override this method for the actual Python Document. """ pass class StringValue: """A var tag calls things to render them. This renders by just returning the string. """ def __init__(self, value): self.value = value def __call__(self, namespace): return self.value ##################################################################### # example code class standard_html_header(PyDocument): """A simple standard_html_header. """ def script(self): self.HTML('''<html><title>''') self.var(name="title") self.HTML('''</title><body>''') class standard_html_footer(PyDocument): """A simple standard_html_footer. """ def script(self): self.HTML('''</body></html>''') class SomePage(PyDocument): """Some other page. """ def script(self): self.var("standard_html_header") self.HTML('''<p>''') self.var("foo") self.HTML('''</p>''') self.var("standard_html_footer") def demo(): # construct a namespace namespace = { "foo": StringValue("FOO"), "title": StringValue("This is the title of the page"), "standard_html_header" : standard_html_header(), "standard_html_footer" : standard_html_footer(), } # create instance of SomePage class somepage = SomePage() # now call somepage with namespace to render it print somepage(namespace) def test(): demo() if __name__=="__main__": test()