[ZPT] Problems with context and rendering and DTML and... a story of failure and puzzlement

steve steve@spvi.com
Wed, 20 Jun 2001 07:34:14 -0500


Hi ZPT folks,

DTML ways die hard.... 

I'm starting to get the hang of macros... but I'm still 10x more
productive in DTML than ZPT, mostly since I've been dtml'ing for years
and ZPT is still an embryonic skill for me. So.. I want to be able to
drop little DTML controls into a template, sorta like macros. As a quick
test of the concept I created a TinyTable(Plus) called 'biopsyTypes'
(this is for a medical sorta thingy) that contains options for a select
box. I then cook up a DTML method (called biopsyTypesControl) to display
the select box::

<select name="biopsyType">
<dtml-in biopsyTypes>
<option value="&dtml-name;">&dtml-displayName;</option>
</dtml-in>
</select>

I test it.. it works... easy enough.

Both of these objects (the TinyTable, and the DTML Method) are in a
Folder called 'Structures' (for managing simple structured data, for
pick lists and so on). 

I now attempt to include this dtml method in a PageTemplate like so:

<span tal:replace="here/Structures/biopsyTypesControl"/>

This fails, mostly because biopsyTypesControl need to have access to the
tiny table 'biopsyTypes' and it got no namespace from which to look it
up. After snooping the mailing list, and fiddling a bit I came to the
following invocation:

<span tal:replace="python:here.Structures.biopsyTypesControl(here.Structures)"/>

This works, after a fashion. I now get the DTML Method to render, but
the HTML comes back *quoted* so that rather than an actual control on
the page, I get the literal text:

<select name="biopsyType"> 
<option value="Brain">Human Brain</option> 
<option value="Muscle">Feline Muscle</option> 
<option value="Skin">More Skin</option> 
</select> 

Hmm.. I considered snooping around in the source to ZPT a bit to see
how/where this was happening, but feeling lazy this morning, I thought
I'd try the list. ;-). There is a follow-up question:

I finally resorted to making a ZPT object, called
'ptBiopsyTypesControl.html' with a macro to do this::

<html>
  <head>
    <title tal:content="template/title">The title</title>
  </head>
  <body>
  <form>
   <div metal:define-macro="biopsyTypesSelect">
	   <select name="biopsyType">
		   <option value="dummyValue"
                   tal:repeat="aType container/biopsyTypes"
                   tal:attributes="value aType/name"
                   tal:content="aType/name">A Dummy Option</option>
		</select>
   </div>
  </form>
  </body>
</html>

I tested it 'stand-alone' and it worked. Cool.

Now I try to invoke it from my template (in the folder above):

<span metal:use-macro="here/Structures/ptBiopsyTypesControl.html/macros/biopsyTypesSelect"/>

Ack.. the biopsyTypesSelect can't find the biopsyTypes TinyTable again!
What does 'container' mean? I expected it meant the container of the
template that defined the macro. Anyway... I decided that
'here/Structures/biopsyTypes should work in both places, so I changed it to:

tal:repeat="aType here/Structures/biopsyTypes"

and all was well. *But* I don't really love the notion that my control
macro needs to know the how it's going to be called so that it can find
it's stuff then. Am I missing something that should be obvious? (probably!)

thanks,
-steve