gschlossnagle / json-template

Automatically exported from code.google.com/p/json-template
0 stars 0 forks source link

Formatters (and predicates) should be passed a stack of namespaces, rather than a single one #32

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
This is a design bug, but thankfully we can keep compatibility:

{"base-url": "http://foo",
  posts: [ { "relative-url": ... id1 },
           { "relative-url": ... id2 },
}

{.repeated section posts}
  {base-url}/{relative-url}   <-- Here we can access the "global" base-url
  {relative-url|format-with-base-url}  <-- The formatter has no access to it
  {section relative-url is-public?}  <-- Predicate needs access to it
{.end}

Original issue reported on code.google.com by gtempacc...@yahoo.com on 22 Sep 2009 at 6:19

GoogleCodeExporter commented 8 years ago
For clarification, the "stack of namespaces" is exactly what JS prototypes are,
although I don't think of the as "prototypes" because the attributes generally 
don't
overlap.

We could also change the JS implementation to actually use .prototype -- this 
would
probably make it a bit faster.

Original comment by gtempacc...@yahoo.com on 22 Sep 2009 at 4:49

GoogleCodeExporter commented 8 years ago
Note: This is a little problematic for compatibility.  The 'html' formatter is:

def HtmlEscape(s):  # s is a string from the JSON
  return cgi.escape(s)

If you need any other variables, it would have to be:

def HtmlEscape(context):
  DoSomethingWith(context.Lookup('other-name'))
  return cgi.escape(context.Lookup('@'))

Might have to distinguish between the 2 kinds of formatters/predicates.

{@|html}
{relative-url|$format-with-base-url}

Not sure I like $.  Likewise for the Plural predicate -- it may need to take an
integer as well as a context.

Another possibility is to distinguish formatters/predicates on atoms (strings,
numbers, bools) vs formatters/predicates on composites (lists, dictionaries).

Original comment by gtempacc...@yahoo.com on 25 Sep 2009 at 7:47

GoogleCodeExporter commented 8 years ago
Idea: formatters/predicates that begin with a lower case letter take atoms.  
Those
that begin with a capital letter take contexts.

Original comment by gtempacc...@yahoo.com on 25 Sep 2009 at 7:48

GoogleCodeExporter commented 8 years ago
I'm not a fan of having case change the meaning of things. Why not just always 
pass the context as the second 
parameter? Some formatters use it, some don't. In this case, the html formatter 
just ignores the second 
parameter and the format-with-base-url uses it.

Original comment by sroussey on 28 Sep 2009 at 12:52

GoogleCodeExporter commented 8 years ago
Well, that will break everyone's existing formatters.  And I like being able to 
do:

more_formatters={'html': cgi.escape}

rather than:

more_formatters={'html': lambda s, unused: cgi.escape(s)}

For functions that already exist.

I'm assuming here that nobody has formatters that start with non-lowercase 
char. 
It's a little unconventional but I think it's very simple and elegant.  Template
authors generally don't need to be aware of it.

Original comment by gtempacc...@yahoo.com on 28 Sep 2009 at 3:15

GoogleCodeExporter commented 8 years ago
Hmm... in Javascript and PHP, it won't break existing formatters. It breaks 
things in
Python, I guess, if you pass an unused parameter?

Original comment by sroussey on 28 Sep 2009 at 10:44

GoogleCodeExporter commented 8 years ago
Yup, in Python that breaks it.  Interesting that it doesn't in PHP and 
JavaScript.  I
suppose we could make the API different.  Not sure how I feel about that.

In general I want template-level compatibility.  I suppose this doesn't break
template compatibility, only API compatibility.  But the list of formatters is
supposed to cross-language.  So "AbsUrl" should do the same thing in all 
languages.

In Java it definitely matters.  Probably C# and Ruby do too... I think 
Javascript and
PHP are exceptional in this regard.

Original comment by gtempacc...@yahoo.com on 29 Sep 2009 at 2:56

GoogleCodeExporter commented 8 years ago
In Python, if you used named parameters, I think it can be more like JS and 
PHP. But
that might be a Python 3.x thing. I can't remember where I read that....

If there is to be a break for the other languages, it could be with four 
parameters:

formatter_function (data, context, formatter, argument_string)

data -- the same thing as always
context -- as you outline above
formatter -- the string as the user wrote it (this would seem overly redundant 
unless
you had several formatters mapped to the same formatter function)
argument_string -- whatever text the user wrote that came after the previous
formatter parameter (alternately, given the previous parameter is available, it 
could
be the entire string the user wrote -- if the function cared about the stuff 
after,
it could strip off the formatter name as given in the previous param).

You could conceivably have the call type (one param or four params) to 
formatters and
predicates be based on option, like meta characters are. In such a case, the 
user
would have to specifically ask for feature that might then break their code,
otherwise everything degrades to the current system.

Original comment by sroussey on 29 Sep 2009 at 4:16

GoogleCodeExporter commented 8 years ago
Reply in the group.  Implemented in Python as:

http://code.google.com/p/json-template/source/detail?r=9957eb309b019980d8ded3571
f2daebc7ee34eba

As mentioned this doesn't rule out the other idea, which is a more complex 
superset.

Original comment by gtempacc...@yahoo.com on 30 Sep 2009 at 6:00

GoogleCodeExporter commented 8 years ago

Original comment by gtempacc...@yahoo.com on 7 Nov 2009 at 9:19