James Y Knight wrote:
On Mar 5, 2004, at 6:15 AM, Alex Martelli wrote:
So, won't every HTML construct coming from a template of some form such as:
<span nevow:data="bar"> etc, etc </span>
end up "compiled" into a "span(data=directive('bar'))[etc, etc]" anyway, leading me right back into subtle issues of "WHERE is this 'bar' going to be looked up, depending on phase of the moon etc"...? Or are there two different ways I should code that '<span nevow:data="bar">' in the on-disk template depending on whether I mean one thing or the other?
Welll, it doesn't depend on the phase of the moon. directives always get looked up on the first data it finds above it in the tree. I'm not sure exactly what your question is, but, is it the lack of being able to go back up the tree? e.g.:
I guess, essentiallly, that's it -- except that in my experience with the previous mechanism it appeared to me that sometimes (unpredictably) the lookup happened on the IData set by a "SISTER" tag, rather than on the data set by a "mother" / "grandmother" one. If now the lookup is always strictly "upwards" (towards the root of the tree without exceptions), that, at least, is progress, even though I'll still have to do lots of data fetching in renderers (mixing view and model). Basically, assuming that's how it always works now, I have to consider that putting a data fetch in a data directive "poisons the well" for a whole subtree -- there is no "going back", ever. If there is any possibility at all that the templates-author (a web designer separate from the programmer who codes the logic behind the templates) may want to get to such other data suppliers, "hidden" by the current mechanism, then I have to code render methods that know how to get their own data.
class MyPage: def data_foo(context, data): return {'bar':2, 'baz':3} def data_other(context, data): return 1 docFactory = xmlstr(""" <html> <span data="foo"> <span data="bar" render="string">This works fine.</span> <span data="other" render="string">This won't work because 'other' isn't a key in {'bar':2, 'baz':3}.</span> </span> </html>""")
Right. calling .get("other") on that dictionary returns None, and, that's it: the situation becomes irretrievable in the current scheme (even though in a much clearer way than it was in the previous one).
Anyway, if I understand correctly, I'll now get this "new behavior" with just a cvs up on the (stand-alone) Nevow CVS, which I intend to do at once, so I can experiment.
Yep.
I have indeed experimented, with my adapter still in place and print statements in said adapter to track when it's called; the number of occurrences has dropped from many dozens to just a couple in a typical rendering pass -- real progress, but still a LITTLE to go.
as "if the current IData remembrance is not adaptable to IContainer [and perhaps also if it is, but its .get raises?], just back off to 'external' IData remembrances until a satisfactory one is found" would be ... I dont think that's the right solution. Too magical. And, what if your data *is* a container but you still want to get to something outside it? One idea that's been proposed and that makes a lot of sense to me is a "../" syntax, so you could say data="../other" or "/other" in the example above. It just hasn't been implemented yet.
It seems to me that, while a syntax to explicitly access "overridden names" (of data suppliers) is helpful in some corner cases, the fundamental mechanism should still be "if a name has not been overridden it's still accessible" -- by analogy with OO programming, and also with CSS mechanics (the latter may be more accessible to my target audience -- template authors who are fundamentally web designers, rather than programmers). So, basically, I'm thinking of IData remembrances as being "in a stack". When a data directive lookup happens, it should walk up the stack, trying, for each different IData remembrance it meets, in order, to perform: new_data = IContainer(said_data).get('new_name') Instead of giving up if this raises, or binds new_data to None, such failures, it seems to me, should just mean one keeps walking up the stack. I don't see this as 'too magical' any more than I consider OO name lookups (and in a single-inheritance scenario, too, the very simplest!) to be so (CSS is more complicated and thus might be 'too magical' for some, yet web designers are mastering THAT complicated name-lookup scenario already...). Guess I'll try to play with these concepts in my copious spare time and see if I can grasp enough of the remembrance and lookup mechanisms to implement a sandbox version of this. Any suggestions of where to focus in the nevow sources? Thanks, Alex