[albatross-users] Re: Python embedded like PHP

Dave Cole djc at object-craft.com.au
Tue Mar 26 05:16:55 EST 2002


>>>>> "Ian" == Ian Bicking <ianb at colorstudy.com> writes:

Ian> Well, you might be able to help the situation some if you create
Ian> a new scope for the macro, and have something like dtml-let --
Ian> that way you could do stuff like.  That way variable assignments
Ian> inside your macro will pass out of scope when the macro finishes,
Ian> and at least not overwrite things in the main scope.

That seems reasonable.  A simple way to do that would be use a special
tag to enclose the fragment of template which you wanted to be in a
local scope.

Ian> You can use some form of let to manipulate the namespace when it
Ian> doesn't match what the macro expects.  This is what DTML does,
Ian> and I assume ZPT uses the same mechanisms (it only seems to be a
Ian> change of syntax).

Ian> I don't like this at all, though, as there's all sorts of
Ian> problems that pop up when you start abstracting things more
Ian> deeply.  Also, I think macros are very important, and keeping
Ian> them python-like is a very nice.  Then you can define, inside a
Ian> single template, not only the full page style, but the style of
Ian> components of the page.  For instance, I create pages that create
Ian> headers with lists underneath them, all entirely dynamic.  If the
Ian> template can define what a header and what a list should look
Ian> like, then I have much more power over the look of the page.

Ian> I'd pass arguments like:

Ian> <al-somemacro arg1="value1" arg2="value2">

Ian> This seems pretty straight-forward, and also maps directly to
Ian> keyword arguments.  You could add the syntax:

Ian> <al-somemacro arg1 arg2="value2">

Albatross macros are a little bit more interesting and useful.  In one
of the samples (the sybase browser) there is a macro for drawing a box
around enclosed content.  The HTML for doing a box is a bit nasty and
non-obvious.  This is the macro:

<al-macro name="box">
<table border="0" cellpadding="1" cellspacing="1" bgcolor="black" width="97%">
<tr><td>
<table width="100%" border="0" cellspacing="1" cellpadding="2">
<tr><td bgcolor="white"><al-usearg></td></tr>
</table>
</td></tr>
</table>
</al-macro>

The interesting thing to note is the <al-usearg> tag.  This is where
content passed to the macro will be placed.  To enclose anything in a
box all you need to do is this:

<al-expand name="box">
Draw a box around me!
</al-expand>

This is what happens when you combine the two things:

>>> from albatross import SimpleContext, Template
>>> ctx = SimpleContext('.')
>>> t = ctx.load_template('macros.html')
>>> t.to_html(ctx)
>>> t = Template(ctx, '', '''<al-expand name="box">
... Draw a box around me!
... </al-expand>
... ''')
>>> t.to_html(ctx)
>>> ctx.flush_content()
<table border="0" cellpadding="1" cellspacing="1" bgcolor="black" width="97%">
<tr><td>
<table width="100%" border="0" cellspacing="1" cellpadding="2">
<tr><td bgcolor="white">Draw a box around me!
</td></tr>
</table>
</td></tr>
</table>

You can nest macros if you like:

>>> t = Template(ctx, '', '''<al-expand name="box">
... <al-expand name="box">
... Draw two boxes
... </al-expand>
... </al-expand>
... ''')
>>> t.to_html(ctx)
>>> ctx.flush_content()
<table border="0" cellpadding="1" cellspacing="1" bgcolor="black" width="97%">
<tr><td>
<table width="100%" border="0" cellspacing="1" cellpadding="2">
<tr><td bgcolor="white"><table border="0" cellpadding="1" cellspacing="1" bgcolor="black" width="97%">
<tr><td>
<table width="100%" border="0" cellspacing="1" cellpadding="2">
<tr><td bgcolor="white">Draw two boxes
</td></tr>
</table>
</td></tr>
</table>
</td></tr>
</table>
</td></tr>
</table>

There are lots of interesting things you can do with the macros.  The
above example used a single argument macro.  You can pass multiple
arguments simply by naming them.  The Albatross manual goes into quite
a bit more detail.

Ian> It should also be fairly easy to create Python functions that do
Ian> the same thing as the macro.

It is quite easy.  That would defeat the effort to separate the
presentation and implementation though.

Ian> Some people will still want to pass in entire namespaces... you
Ian> could use inclusion instead of macros in that case, or make
Ian> another form of macros.  You could also make another form of
Ian> setting variables, that sets them globally (perhaps as constants)
Ian> -- this is much cleaner than making every passing variable and
Ian> loop global.

I agree - there are lots of things that could be done.  Coming up with
some "simple" things which can be used for multiple purposes is the
challenge.  It is only by having our assumptions challenged that we
will be able to improve what we currently have.  Your constructive
criticism is making me revisit some of the early decisions and look
at them in a new light.

- Dave

-- 
http://www.object-craft.com.au



More information about the Python-list mailing list