Personal tools
You are here: Home Weblog How to call a Page Template macro from a script

How to call a Page Template macro from a script

Posted by Sean Fulmer at Aug 28, 2007 07:00 PM |
Filed under: ,

from the i-wish-i-didn't-have-to-do-this dept

One of my clients wants to, basically, present all of the content on his site on a single page. Obviously, this would be a huge page to load all at once, so it is organized into toggle-able sections. The content of each section is being pulled in, as JSON, with an AJAX call when that section is toggled.

Each section is somewhat different, so there are a lot of unique JS functions to build the HTML for each section. I'm using MochiKit, which goes a long way towards streamlining all of these DOM-building functions. The problem is that there are so many unique functions to build these various sections that, by the time this is all done, the Javascript used to build the page is going to be nearly as heavy as the page would be if it were loaded all at once without AJAX.

So, I'm thinking that it would be good to offload most of the DOM-building functions to page template macros, and just pull in rendered HTML instead of building everything with JS. I want to keep all of these various content sections as macros in a single page template, and call each macro from a script when I need it.

The problem is, as far as I can tell, you can't pass parameters to a specific macro from a script - you can only call the entire template, like:

   context.my_template(foo='a', bar='b')

So, after digging through mailing lists and APIs, I've concluded that the only way to call a specific macro from a script is to wrap the macro template in another template, and call the wrapper, specifying the macro name as one of the parameters.

Here's the macro template, named my_macros.pt:

      <metal:macro define-macro="macro_one">
        <div tal:content="options/foo" />
        <div tal:content="options/bar" />
      </metal:macro>

      <metal:macro define-macro="macro_two">
        <div tal:content="options/bar" />
        <div tal:content="options/foo" />
      </metal:macro>

And here's the wrapper, named call_my_macro.pt:

    <metal:wrapper 
      use-macro="python:path('here/my_macros/macros/'+options['macro'])" />

And you would call it from a script like so:

    result = context.call_my_macro(macro='macro_one',foo='foo',bar='bar')

Which would return macro_one rendered with the appropriate values for foo and bar:

    <div>foo</div>
    <div>bar</div>

So, in the end, I can do what I need to do - but I can't help thinking that I've missed a simpler way to do this. Surely there's a way to pass parameters to a ZPT macro from a script without wrapping it in another template, but so far I can't find it. Any ideas?

Comments (0)