Re: [Webware-discuss] templating: request review

At 02:32 PM 4/30/2001 -0700, Mike Orr wrote:
>$foo is certainly easy to type and has the advantage of consistency with
>other languages. However, what about $fooNOTFOO (the placeholder being
>immediately followed by a letter). Are the parentheses/braces optional?
I just started focusing on $(foo bar) because that's where issues arose.
The deal is that $foo is fine. You use $(foo) when you need to add args or
there is a period following (as you mentioned later). Examples:
$foo
$foo.bar
$(foo.bar)baz
$(foo.bar).baz
$(foo width=20)
>I may be willing to switch the default syntax of Plow from {braces} to
>$(whatever_we_decide), depending.
I think that would be good. More compatibility out of the box.
Interestingly, webmacro uses $() and Velocity uses ${}.
(sigh)
er, I mean
{sigh}
no (sigh)
If compatibility with these other packages is desireable, I would vote for
supporting both. Something I rarely vote for.
>??? What does "taking precedence over the object" mean? Taking precedence
>over what? Over 'valueContainers[0]'?
Woops. Garbage from the previous RNV, although I don't see it in my current
docs on disk.
>OK, but the explanation could be a bit clearer. How about:
>unknownValue - a format string used if a named value cannot be found.
>The string may contain the substring "%(name)s", which will be replaced by
>the missing name, using the normal %-operator semantics.
OK.
-Chuck

Thread view

I want to provide a slightly more advanced ReplaceNamedValues,
incorporating Tavis' idea of using a function (as well as a mix-in and a
wrapper) and also the syntax from Velocity.
That idea is to provide an extremely lightweight template package whose
$foo.bar syntax is simple and a strict subset of more advanced systems like
Tavis'.
This would go in Webware.MiscUtils. We can then use this for things like
the 404 message in WebKit and such.
Developers can use it for simple templating and then later upgrade to a
more advanced package without having to modify the templates they already have.
So the point I'm leading up to is that here is my function interface and
doc string. I'd appreciate it if you could review it and point out any
flaws or problems you see.
def replaceNamedValues(string, valueContainers, unknownValue=NoDefault,
noneValue=None, regEx=None):
'''
Returns a new version of the string replaced with named values that come
from the valueContainers.
The point here is to provide a more powerful version of Python's
dictionary strings:
format % dict # such as:
'%(foo)s %(bar)s' % dict
The first improvement is syntax:
'$foo $bar'
This is easier to type. Note that $ followed by a digit, as in $1, is not
a legal identifier and not interpreted. Also, $$ and \$ yield a single $.
Another advantage to this syntax is that more advanced templating packages
like Tavis Rudd's TemplateServer, Velocity and webmacro use this same
syntax. That means you can later upgrade your templating solution without
having to modify any of your existing templates.
The next improvement is dotted notation. This function uses
NamedValueAccess.valueForName(), so you can traverse an object graph
(including dictionaries) using dotted notation: $department.manager.lastName
Parameters:
string - The formatted string such as "Hello, %(name)s!"
valueContainers - a list of objects that will be searched in order for
particular named value.
args - Optional dictionary of args takes precedence over the object
unknownValue - The string value to use if a named value cannot be found.
If not specified, an exception will be raised. Note that unknownValue is %
with a dictionary contain the key 'name'. So for example, you could pass
unknownValue='<span class=unknownValue> %(name)s </span>'.
noneValue - The string value to use if a named value results in Python's
None. If unspecified, "None" will actually show up in the resulting string.
regEx - The regular expression used to match the names for substitution
in the string.
@@ 2001-04-29 ce: Provide a filterValueFunc argument which defaults to
None and is invoked for all values:
if filterValueFunc: value = filterValueFunc(name, value)
Is that a useful hook?
'''

Sounds very worthwhile, and I like your compatible
subset/superset idea!
> This would go in Webware.MiscUtils. We can then use this
> for things like the 404 message in WebKit and such.
I like this, but wouldn't extend it to include logging as
that could be a major performance drag.
> So the point I'm leading up to is that here is my
> function interface and doc string. I'd appreciate it if
> you could review it and point out any flaws or problems
> you see.
> Another advantage to this syntax is that more advanced
> templating packages like Tavis Rudd's TemplateServer,
> Velocity and webmacro use this same syntax. That means
> you can later upgrade your templating solution without
> having to modify any of your existing templates.
I'd suggest just using a wrapper around TemplateServer to
do this. The entire design is modular so all the
directives you don't want (#for, #if, #set, #stop, etc.)
can be turned off easily.
Advantages of using a wrapper around TemplateServer:
- it would take less than 1/2 hr to do it
- efficient code reuse
- less chance of interface divergence
- debugging efforts would benefit all uses of $interpolation
- it would encourage further testing/debugging of the core
functionality of TemplateServer.
Disadvantages:
- TemplateServer's more complex codebase could obscure bugs
that would be spotted quickly in a smaller codebase
By the way, I think the code reviews and template
comparisons you've been making are excellent, and
appreciate the effort you put into open communication and
encouraging collaboration!
Cheers,
Tavis

At 09:07 PM 4/29/2001 -0700, Tavis Rudd wrote:
>I'd suggest just using a wrapper around TemplateServer to
>do this. The entire design is modular so all the
>directives you don't want (#for, #if, #set, #stop, etc.)
>can be turned off easily.
[snip]
I agree that this could work, but then if RNV is used in WebKit (which is
my plan) then WebKit would rely on a new, pretty big chunk of code
(TemplateServer). I want to avoid *requiring* any more big packages for
WebKit, otherwise we will slowly approach the bloat we found in Zope.
Also, people want to inevitable run packages on small platforms like the
Palm or Terrel's computer science lab machines. :-)
I'm not even comfortable that it requires TaskKit. I would like to see it
do something simple minded if TaskKit were absent, such as ping managers
every X minutes (where X is a setting).
Regarding quality, I think our test suites for both RNV and the other
templating kits will eventually grow to the point where there will be no
concern or backsliding.
>By the way, I think the code reviews and template
>comparisons you've been making are excellent, and
>appreciate the effort you put into open communication and
>encouraging collaboration!
Thanks. I saw so many people cranking on templates I felt it would be
useful to support all that with reviews, indexes, etc. instead of spewing
more of my own code.
-Chuck

On Sun, Apr 29, 2001 at 10:21:26PM -0400, Chuck Esterbrook wrote:
> def replaceNamedValues(string, valueContainers, unknownValue=NoDefault,
> noneValue=None, regEx=None):
> '''
> Returns a new version of the string replaced with named values that
> come from the valueContainers.
>
> The point here is to provide a more powerful version of Python's
> dictionary strings:
> format % dict # such as:
> '%(foo)s %(bar)s' % dict
>
> The first improvement is syntax:
> '$foo $bar'
Somewhere the posts switched from talking about this syntax to $(foo), ${foo},
$(foo align=left). Or are we talking about two different packages.
$foo is certainly easy to type and has the advantage of consistency with
other languages. However, what about $fooNOTFOO (the placeholder being
immediately followed by a letter). Are the parentheses/braces optional?
> Another advantage to this syntax is that more advanced templating
> packages like Tavis Rudd's TemplateServer, Velocity and webmacro use
> this same syntax. That means you can later upgrade your templating
> solution without having to modify any of your existing templates.
Not having to upgrade your templates every time you change the engine would
be a very nice feature.
Plow and (last time I looked) TemplateServer both used a single regular
expression with a group to find the placeholders, so the syntax can be
switched easily. If each kit can ship with optional expressions to match
the syntaxes of the other kits, that would be a plus.
I may be willing to switch the default syntax of Plow from {braces} to
$(whatever_we_decide), depending.
> The next improvement is dotted notation. This function uses
> NamedValueAccess.valueForName(), so you can traverse an object graph
> (including dictionaries) using dotted notation: $department.manager.lastName
What about a sentance ending with $name. And then another sentance.
Would it be smart enough to know a period is not part of the name if
it's followed by whitespace?
> Parameters:
>string - The formatted string such as "Hello, %(name)s!"
>valueContainers - a list of objects that will be searched in
> order for particular named value.
>args - Optional dictionary of args takes precedence over the
> object
??? What does "taking precedence over the object" mean? Taking precedence
over what? Over 'valueContainers[0]'?
> unknownValue - The string value to use if a named value
> cannot be found.
> If not specified, an exception will be raised. Note that unknownValue is %
> with a dictionary contain the key 'name'. So for example, you could pass
> unknownValue='<span class=unknownValue> %(name)s </span>'.
OK, but the explanation could be a bit clearer. How about:
unknownValue - a format string used if a named value cannot be found.
The string may contain the substring "%(name)s", which will be replaced by
the missing name, using the normal %-operator semantics.
> @@ 2001-04-29 ce: Provide a filterValueFunc argument which defaults to
> None and is invoked for all values:
> if filterValueFunc: value = filterValueFunc(name, value)
> Is that a useful hook?
I don't see a need.
--
-Mike (Iron) Orr, iron@... (if mail problems: mso@...)
http://mso.oz.net/ English * Esperanto * Russkiy * Deutsch * Espan~ol

At 02:32 PM 4/30/2001 -0700, Mike Orr wrote:
>$foo is certainly easy to type and has the advantage of consistency with
>other languages. However, what about $fooNOTFOO (the placeholder being
>immediately followed by a letter). Are the parentheses/braces optional?
I just started focusing on $(foo bar) because that's where issues arose.
The deal is that $foo is fine. You use $(foo) when you need to add args or
there is a period following (as you mentioned later). Examples:
$foo
$foo.bar
$(foo.bar)baz
$(foo.bar).baz
$(foo width=20)
>I may be willing to switch the default syntax of Plow from {braces} to
>$(whatever_we_decide), depending.
I think that would be good. More compatibility out of the box.
Interestingly, webmacro uses $() and Velocity uses ${}.
(sigh)
er, I mean
{sigh}
no (sigh)
If compatibility with these other packages is desireable, I would vote for
supporting both. Something I rarely vote for.
>??? What does "taking precedence over the object" mean? Taking precedence
>over what? Over 'valueContainers[0]'?
Woops. Garbage from the previous RNV, although I don't see it in my current
docs on disk.
>OK, but the explanation could be a bit clearer. How about:
>unknownValue - a format string used if a named value cannot be found.
>The string may contain the substring "%(name)s", which will be replaced by
>the missing name, using the normal %-operator semantics.
OK.
-Chuck