Personal tools
You are here: Home Documentation Tutorials Macros with Grok Defining a simple macro

Defining a simple macro

In Grok macros are defined in usual views, where the associated page templates contain `metal`-statements to define the desired macros. Macros generally are attributes of the page template wherein they are defined, but to get them rendered, we usually use views.
Macros are a way to define a chunk of presentation in one template, and share it in others. Changes to the macro are immediately reflected in all of the places, that share it.
Page 2 of 6.

We define a view MyMacros the usual way in app.py:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
import grok

class Sample(grok.Application, grok.Container):
    pass

class Index(grok.View):
    pass # see app_templates/index.pt

class MyMacros(grok.View):
    """The macro holder"""
    grok.context(Sample) # The default model this view is bound to.

In the associated page template app_templates/mymacros.pt we define the macros we like to have available. You define macros with the METAL attribute:

metal:define-macro="<macro-name>"

and the slots therein with:

metal:define-slot=<slot-name>

Let's define a very plain page macro in app_templates/mymacros.pt:

<html metal:define-macro="mypage">
  <head></head>
  <body>
    The content:
    <div metal:define-slot="mycontent">
      Put your content here...
    </div>
  </body>
</html>

Here we defined a single macro mypage with only one slot mycontent.

If we restart our Zope instance (don't forget to put some index.pt into app_templates/) and have created our application as test, we now can go to the following URL:

http://localhost:8080/test/mymacros

and see the output:

The content:
Put your content here...

Allright.

 

A word of warning

Posted by Peter Bengtsson at May 04, 2008 06:07 AM
When you compose your simple macro, don't refer to "view" and expect the macro view. When the macro is referenced by another view, the "view" namespace is that of the referencing view, not the macro view.
The workaround, if you want to refer to attributes or something in the macro view is to reference by name. So, this is WRONG:

<html metal:define-macro="mypage">
  <head tal:attributes="name view/some_attribute">

...unless you define 'some_attribute' for all views that references this. To reference it by name do it this way:

<html metal:define-macro="mypage">
  <head tal:attributes="name context/@@mymacros/some_attribute">