[ZPT] Filling slots in METAL macros...

Evan Simpson evan@zope.com
Fri, 27 Jul 2001 11:37:45 -0400


Tony McDonald wrote:

> I guess I could do this
> <div metal:fill-slot="obox">
> <boxtitle metal:fill-slot="string: Hello World"/>
> (etc)
> </div>
> 
> And have the macro look something like this;
> <div metal:define-macro="obox">
> <table  border=0 cellpadding=0 cellspacing=0 width=600>
> <tr><td colspan=2><font size=-3>&nbsp;</font></td>
> <td rowspan=3 nowrap><boxtitle metal:define-slot="obox_title">title for
> Obox</boxtitle></td>


In this case, you would use the macro like this:
<div metal:use-macro="here/master.zpt/macros/obox">
<boxtitle metal:fill-slot="obox_title">Hello World</boxtitle>
</div>

I really need to add METAL to the ZPT tutorial, but in the meantime 
here's a quick rundown:

Macros are a way to share chunks of presentation, and have the shared 
stuff appear inline in the template.  You don't use them for plugging in 
data values; That's what tal:replace and tal:content are for.

Whenever a template that uses macros is rendered, all of the macros are 
plugged in just before TAL processing.  If you edited the page and 
removed all of the METAL attributes, *it would make no difference* as 
long as you didn't try to change any of the macro definitions.  TAL 
statements don't know where they "come from", they only care about the 
template they're being rendered in.  This means that "here", "template", 
"options", and all other variables are exactly the same inside macros as 
out.  You can tal:define a variable, then use it in an enclosed macro. 
You can tal:define a global variable in a macro, then use it below the 
macro.

You only need to use slots if you want to be able to override parts of a 
macro in templates that use it.  To do this, give a tag in the macro 
definition a slot name with metal:define-slot.  When you use this macro, 
the slot contents will be used normally along with the rest of the 
macro, unless you add a metal:fill-slot statement with the slot's name. 
   A metal:fill-slot statement tag completely replaces the slot tag from 
the macro definition, including the tag name and any attributes.

A single tag cannot have more than one METAL attribute on it.  While you 
can define a macro inside of another macro, or use a macro in a macro 
definition or a slot, you have to do it by placing the METAL statements 
on nested tags.  For example (after macro expansion):

<table metal:define-macro="M1">
   <tr>
     <td metal:define-slot="A">This will be replaced</td>
   </tr>
</table>

<p metal:define-macro="M2">
<span metal:define-slot="B">Dummy text</span>
</p>


<table metal:use-macro="template/macros/M1">
   <tr>
     <td metal:fill-slot="A">
<p metal:use-macro="template/macros/M2">
<h1 metal:fill-slot="B">Hello!</h1>
</p>
     </td>
   </tr>
</table>

> This didn't work;
> 
> <div metal:fill-slot="obox" metal:use-macro="here/obox_template/macros/obox">
> <b metal:fill-slot="obox_title"><span tal:content="template/title"></span></b>
> </div>


This looks like you just need to drop the 'metal:fill-slot="obox"'.

Cheers,

Evan @ Zope