Referencing a simple macro

How to reference a simple macro?

In index.pt we now want to use the macro defined in mymacros.pt. Using a macro means to let it render a part of another page template, especially, filling the slots defined in mymacros.pt with content defined in index.pt. You call macros with the METAL attribute:

metal:use-macro="<macro-location>"

Our app_templates/index.pt can be that simple:

<html metal:use-macro="context/@@mymacros/macros/mypage">
</html>

Watching:

http://localhost:8080/test/index

should now give the same result as above, although we didn’t call mymacros in browser, but index. That’s what macros are made for.

When we fill the slots, we get different content rendered within the same macro. You can fill slots using:

metal:fill-slot="<slot-name>"

where the slot-name must be defined in the macro. Now, change index.pt to:

<html metal:use-macro="context/@@mymacros/macros/mypage">
  <body>
    <!-- slot 'mycontent' was defined in the macro above -->
    <div metal:fill-slot="mycontent">
      My content from index.pt
    </div>
  </body>
</html>

and you will get the output:

The content:
My content from index.pt

The pattern of the macro reference (the <macro-location>) used here is:

context/<view-name>/macros/<macro-name>

whereas context references the object being viewed, which in our case is the Sample application. In plain English we want Zope to look for a view for a Sample application object (test) which is called mymacros and contains a macro called mypage.

The logic behind this is, that views are always registered for certain object types. Registering a view with some kind of object (using grok.context() for example), means, that we promise, that this view can render objects of that type. (It is up to you to make sure, that the view can handle rendering of that object type).

It is not a bad idea to register views for interfaces (instead of implementing classes), because it means, that a view will remain usable, while an implementation of an interface can change. [FIXME: Is this a lie?] This is done in the section Defining ‘all-purpose’ macros.