Accessing outer section

7 views
Skip to first unread message

George Moschovitis

unread,
Dec 11, 2009, 5:21:42 AM12/11/09
to JSON Template
I am wondering how the following use case could be implemented:

data = {
isAdmin: true,
topics: [
{title: "1st topic},
{title: "2nd topic}
]
}

template:

<ul>
{.repeated section topics}
<li>{title} {.section isAdmin}<a href="admin">admin</a>{.end}
{.end}
</ul>

this doesn't work (you cannot access the outer 'isAdmin' section from
within the 'topics' section. Is there a workaround or a better way to
structure the json data?

thank you,
-g.

Andy Chu

unread,
Dec 11, 2009, 11:09:05 AM12/11/09
to json-t...@googlegroups.com
So actually that was one of the discussions that led to predicates.
Unfortunately I haven't gotten around to documenting them other than
in the tests.

This is in jsontemplate_test.py:

@testy.no_verify('java', 'php')
def testContextPredicate(self):

# The Debug? predicate looks up the stack for a "Debug" predicate
t = testy.ClassDef(
B("""
{.repeated section posts}
Title: {title}
Body: {body}
{.Debug?}
Rendered in 3 seconds
{.end}
{.end}
"""))

And in _jsontemplate.py:


def _IsDebugMode(unused_value, context, unused_args):
try:
return bool(context.Lookup('debug'))
except UndefinedVariable:
return False

And I thought I had made a built-in predicate for this, which takes an
attribute argument, so you wouldn't have to write a custom predicate.
But apparently not. You should be able to do something like:

{.attr debug?}
{.end}

{.attr isAdmin?}
{.end}

without writing any code. I think I will add that -- any suggestions
on the name? Predicates can either end with ? or begin with ".if ".

This should work in Python and JS.

Andy

Andy Chu

unread,
Dec 11, 2009, 11:27:17 AM12/11/09
to json-t...@googlegroups.com

Oliver Oli

unread,
Dec 12, 2009, 6:01:25 AM12/12/09
to json-t...@googlegroups.com
2009/12/11 Andy Chu <an...@chubot.org>:
> And I thought I had made a built-in predicate for this, which takes an
> attribute argument, so you wouldn't have to write a custom predicate.
> But apparently not.  You should be able to do something like:
>
> {.attr debug?}
> {.end}
>
> {.attr isAdmin?}
> {.end}
>
> without writing any code.  I think I will add that -- any suggestions
> on the name?  Predicates can either end with ? or begin with ".if ".
>
> This should work in Python and JS.
>
> Andy

At this point I'm thinking json-template is less elegant than a
standard templating language. Wouldn't it be much easier to have
access to the global namespace / root elements?

like

{.section $admin}
{.end}

but I'm having the feeling that I'm missing something. Could you
explain for what we need predicates?

Andy

unread,
Dec 12, 2009, 7:54:21 PM12/12/09
to JSON Template
*** I thought I responded this morning -- the post isn't showing up in
Groups, but luckily I saved a copy ***

> At this point I'm thinking json-template is less elegant than a
> standard templating language. Wouldn't it be much easier to have
> access to the global namespace / root elements?
>
> like
>
> {.section $admin}
> {.end}
>
> but I'm having the feeling that I'm missing something. Could you
> explain for what we need predicates?

For the case of testing if "admin" is set at the root, it's possible
that could work.

But in general it doesn't work. There were some very long discussions
about this on the group. This might get you to them since Groups
search is also broken:
http://www.google.com/webhp?hl=en#hl=en&source=hp&q=predicates+json+template+site%3Agroups.google.com

The basic difference is that:

1. Sections test if a namespace exists and then *push* the current
context into it. So they do 2 things.

This leads to a fundamental asymmetry of sections -- the "main" block
is executed in a different context that the "or" block is.

2. Predicates are arbitrary tests. They can also test if a namespace
exists, but in general are user-specified.

The syntax of trying to put user-defined tests into sections was also
problematic, in addition to the semantic problems.

So I think if we just provide something as simple as {.section $admin}
it should be fine. The idioms just haven't been worked out yet. I
was propoing {.attr admin?} or it can also be spelled {.if attr
admin}.

Just plain {.admin?} or {.if admin} is possible and definitely looks
nicer, but it leads to some potential ambiguity. In any case, the
user can actually program this any way they want, but I would like to
make something standard to relieve them of thinking about it if they
don't want to.

Andy

Josh Taylor

unread,
Dec 18, 2009, 4:55:10 PM12/18/09
to JSON Template
I just ran into this issue as well. My attempted usage pattern is
along the lines of:

{.section inner} {foo} {.section outer} {@} {.or} Fail {.end}
{.end}

Using the following dictionary:

{ 'outer' : 'OUTER',
'inner' : { 'foo' : 'FOO', },
}

In this case, I'm trying to use .section as a conditional test. This
can be satisfied using the custom predicates you're talking about.
E.g.:

{.section inner} {foo} {.if outer?} {outer} {.or} Fail {.end}
{.end}

That's how I'm currently working around the problem. Though, as a
separate issue, neither FromString() and FromFile() take a
"more_predicates" parameter, which sort of breaks things. I think I
can double-workaround using the undocumented _constructor parameter,
but I haven't tried it yet.

However, I'm confused by the .section lookup logic. It seems like it
should be consistent with normal variable lookups. I think it can be
done by decoupling the name lookup traversal from the section stack.

For name lookup, think of the JSON structure as a tree and the current
context as a pointer to a node in the tree. A lookup starts at the
current context walks up the tree to the root until a match is found.
There would need to be a way to get each context's parent during the
lookup. This could be done either by injecting parent pointers into
the JSON tree or by keeping the path to the root on each context.

The section stack just keeps track of your current starting point for
lookups. Only the top element is directly used for any given lookup.
When you push a new section, you do a normal lookup from the current
context to find the new context, then push it on the stack.

Given the current limitations on sections, I believe the proposed name
lookup rule is the same for variables. What we get is generality on
sections. You can start a higher level section or even a nested
section (e.g {.section foo.bar}). It also handles the conditional
predicate usage.

-Josh


On Dec 12, 4:54 pm, Andy <a...@chubot.org> wrote:
> *** I thought I responded this morning -- the post isn't showing up in
> Groups, but luckily I saved a copy ***
>
> > At this point I'm thinking json-template is less elegant than a
> > standard templating language. Wouldn't it be much easier to have
> > access to the global namespace / root elements?
>
> > like
>
> > {.section $admin}
> > {.end}
>
> > but I'm having the feeling that I'm missing something. Could you
> > explain for what we need predicates?
>
> For the case of testing if "admin" is set at the root, it's possible
> that could work.
>
> But in general it doesn't work.  There were some very long discussions
> about this on the group.  This might get you to them since Groups

> search is also broken:http://www.google.com/webhp?hl=en#hl=en&source=hp&q=predicates+json+t...

Oliver Oli

unread,
Dec 19, 2009, 4:31:46 AM12/19/09
to json-t...@googlegroups.com
2009/12/18 Josh Taylor <joshua...@gmail.com>:

> For name lookup, think of the JSON structure as a tree and the current
> context as a pointer to a node in the tree.  A lookup starts at the
> current context walks up the tree to the root until a match is found.
> There would need to be a way to get each context's parent during the
> lookup.  This could be done either by injecting parent pointers into
> the JSON tree or by keeping the path to the root on each context.

This sounds a lot like Acquisition in Zope, which was one of the ideas
I really liked in Zope
(http://www.google.com/search?q=Zope+Acquisition). Could be very
powerful, but maybe it shouldn't be the default behaviour.

Andy

unread,
Dec 31, 2009, 2:20:13 AM12/31/09
to JSON Template

On Dec 18, 1:55 pm, Josh Taylor <joshua.tay...@gmail.com> wrote:
> I just ran into this issue as well.  My attempted usage pattern is
> along the lines of:
>
>     {.section inner} {foo} {.section outer} {@} {.or} Fail {.end}
> {.end}
>
> Using the following dictionary:
>
>     { 'outer' : 'OUTER',
>       'inner' : { 'foo' : 'FOO', },
>       }
>
> In this case, I'm trying to use .section as a conditional test.  This
> can be satisfied using the custom predicates you're talking about.
> E.g.:
>
>     {.section inner} {foo} {.if outer?} {outer} {.or} Fail {.end}
> {.end}
>
> That's how I'm currently working around the problem.  Though, as a

Sorry for the delay in responding.

Why is that a workaround? That is the intended usage of predicates.
(although I think that the if and ? are a bit redundant -- I may have
to tweak that)

> separate issue, neither FromString() and FromFile() take a
> "more_predicates" parameter, which sort of breaks things.  I think I
> can double-workaround using the undocumented _constructor parameter,
> but I haven't tried it yet.

That is a bug -- those should have a more_predicates arg. Maybe I'll
also take this opportunity to rename it to "predicates" (but preserve
backward compatibility with an alias).

> However, I'm confused by the .section lookup logic.  It seems like it
> should be consistent with normal variable lookups.  I think it can be
> done by decoupling the name lookup traversal from the section stack.

I've considered this but think it's a bit confusing. Right now
sections only take you toward the "child" end of the tree. If you
could go "backwards", it seems like it would lead to some weird
semantics. So far it looks like predicates cover all these cases.

> For name lookup, think of the JSON structure as a tree and the current
> context as a pointer to a node in the tree.  A lookup starts at the
> current context walks up the tree to the root until a match is found.
> There would need to be a way to get each context's parent during the
> lookup.  This could be done either by injecting parent pointers into
> the JSON tree or by keeping the path to the root on each context.

That's a correct model of the JSON structure. But that is already
done for substitutions. It just maintains a stack of parents every
time you push the context. (See the _ScopedContext implemenetation -
PushSection/Pop, etc.)

>
> The section stack just keeps track of your current starting point for
> lookups.  Only the top element is directly used for any given lookup.
> When you push a new section, you do a normal lookup from the current
> context to find the new context, then push it on the stack.
>
> Given the current limitations on sections, I believe the proposed name
> lookup rule is the same for variables.  What we get is generality on
> sections.  You can start a higher level section or even a nested
> section (e.g {.section foo.bar}).  It also handles the conditional
> predicate usage.

Well the predicates are a little more general because they chain like
switch/case. And also they are user-customizable like formatters. We
went through some long discussions about putting predicates directly
in sections, but in the end it was too complicated. Having them as
separate concepts is the cleanest thing.

I'll file some bugs on your feedback.

thanks,
Andy

Reply all
Reply to author
Forward
0 new messages