Re: [Zope] Calling objects with arguments in a sequence
seb <sebbacon@email.com> wrote:
I'm using the Photo product, instances of which I can call, with arguments, like this:
<dtml-var "my_photo(display='thumbnail')">
However, I can't work out how to pass arguments to each sequence item when iterating over a sequence.
For example, I've tried:
<dtml-in objectValues(['Photo'])"> <dtml-var "_['sequence-item'](display='thumbnail')"> </dtml-in>
(..not that I expect that to work :)
And I get
Error Type: TypeError Error Value: call of non-function (type string)
I've tried various combinations of ways of calling the sequence-item, but they all return the same error. Could anyone suggest how I should do this? Thanks in advance...
You were very close -- the trick here is that 'objectValues' returns real objects, not IDs. Try this (untested):: <dtml-in "objectValues( [ 'Photo' ] )"> <dtml-let photo=sequence-item> <!-- alias so we can use in expr! --> <dtml-var "photo( display='thumbnail' )"> </dtml-let> </dtml-in> Tres. -- =============================================================== Tres Seaver tseaver@digicool.com Digital Creations "Zope Dealers" http://www.zope.org
Thanks very much for the reply, Tres. Unfortunately it didn't work. I've been puzzling about this for a while, and I'm lost. I thought I'd restate the problem in more generic terms in the hope that more people will have a look at it. If you do: <dtml-in "objectValues('Foo Thing')"> <dtml-let thing=sequence-item> <dtml-var "thing.id()"> </dtml-let> </dtml-in> You get TypeError: it claims thing is a string, so you can't perform any kind of function call against it. My understanding is that when the ZPublisher finds an object reference, it invokes its __str__ method. This returns a string. When Zope finds an object being called with parameters, it invokes its __call__ method, which also (usually) returns a string. I think that in the case of a sequence-item, the ZPublisher is invoking the __str__ method of the object, and _then_ applying arguments to the result, which is a string object. So, it fails. Is this a bug? Is Zope rendering the object too soon? I've thought and thought about this, but can't think of a logical reason for this behaviour of sequence-item. Surely sequence-item should be a reference to a normal object, and therefore behave like one? But then again, I'm a Zope / python newbie, so *please* shoot me down ;) With a furrowed brow, Seb.
<dtml-in "objectValues( [ 'Photo' ] )"> <dtml-let photo=sequence-item> <!-- alias so we can use in expr! --> <dtml-var "photo( display='thumbnail' )"> </dtml-let> </dtml-in>
seb <sebbacon@email.com> wrote:
I'm using the Photo product, instances of which I can call, with arguments, like this:
<dtml-var "my_photo(display='thumbnail')">
However, I can't work out how to pass arguments to each sequence item when iterating over a sequence.
For example, I've tried:
<dtml-in objectValues(['Photo'])"> <dtml-var "_['sequence-item'](display='thumbnail')"> </dtml-in>
(..not that I expect that to work :)
And I get
Error Type: TypeError Error Value: call of non-function (type string)
seb wrote:
If you do:
<dtml-in "objectValues('Foo Thing')"> <dtml-let thing=sequence-item> <dtml-var "thing.id()"> </dtml-let> </dtml-in>
You get TypeError: it claims thing is a string, so you can't perform any kind of function call against it.
Welcome to DTML... what's happening, I guess, is that when you do <dtml-let thing=sequence-item> sequence-item is called (and hence rendered to a string) which screws thigns up. try:
<dtml-in "objectValues('Foo Thing')"> <dtml-let thing="_.getitem('sequence-item',0)> <dtml-var "thing.id()"> </dtml-let> </dtml-in>
cheers, Chris
Waheyy! Thanks Chrises, the Withers solution worked a treat. I don't actually thing that sequence-item _is_ called when it's assigned. I tried inspecting it with all sorts of python and it's definitely a string as soon as you even mention it. It looks to me like it's rendered before you can access any of its attributes. I'm still a relative stranger to the Zope architecture, and I've got a deadline to meet, so I can't go look at the code right now. However, surely this behaviour _is_ a bug? I would expect sequence-item consistently to behave like the object to which it refers.
Welcome to DTML...
Sounds ominous ;) I've just starting actually using Zope in production, and I'm constantly surprised by it. I can spend about 5 hours on a little problem like this, and just when I start thinking "stupid system" and reach for mod_php + mysql, I suddenly find I've done something that would normally take me a couple of days to implement in about 10 minutes. Welcome to Zope, eh? Seb
what's happening, I guess, is that when you do <dtml-let thing=sequence-item>
sequence-item is called (and hence rendered to a string) which screws thigns up.
try:
<dtml-in "objectValues('Foo Thing')"> <dtml-let thing="_.getitem('sequence-item',0)> <dtml-var "thing.id()"> </dtml-let> </dtml-in>
cheers,
Chris
Seb wrote:
I don't actually thing that sequence-item _is_ called when it's assigned.
If my solution worked, then it is :P
I tried inspecting it with all sorts of python and it's definitely a string as soon as you even mention it.
Well, it probably seemed like that... If you do <dtml-var sequence-item>, it'll get called if you do <dtml-var "sequence-item">, you'll get NameErrors 'cos chances are sequence and item don't exist. If you do <dtml-var "_['sequence-item']">, it'll get called (real bitch of mine, that one :-( ) If you do <dtml-var "_.getitem('sequence-item',1)">, it'll get called... And, apparently, if you do <dtml-let thing=sequence-item>, it'll get called.... AFAIK, the way I mentioned is the only way you can ensure it isn't called... cheers, Chris
Ahh, now I understand...
If you do <dtml-var "_['sequence-item']">, it'll get called (real bitch of mine, that one :-( ) And, apparently, if you do <dtml-let thing=sequence-item>, it'll get called....
Are the above two points bugs, then? Or is there a legitimate reason for this behaviour? Seb
seb wrote:
Ahh, now I understand...
If you do <dtml-var "_['sequence-item']">, it'll get called (real bitch of mine, that one :-( ) And, apparently, if you do <dtml-let thing=sequence-item>, it'll get called....
Are the above two points bugs, then?
Probably not...
Or is there a legitimate reason for this behaviour?
illegitimate in that it makes some things easier, like showing an object when you don't know whether it's a function or a string (as with id, as ChrisM pointed out ;-) but bastardising python syntax to your own ends is probably a bad thing :-S cheers, Chris
If you do:
<dtml-in "objectValues('Foo Thing')"> <dtml-let thing=sequence-item> <dtml-var "thing.id()"> </dtml-let> </dtml-in>
You get TypeError: it claims thing is a string, so you can't perform any kind of function call against it.
Some id attributes of Zope objects are methods, some are strings. To account for every case: <dtml-in "objectValues('Foo Thing')"> <dtml-let thing=sequence-item> <dtml-try> <dtml-var "thing.id()"> <dtml-except TypeError> <dtml-var "thing.id"> </dtml-try> </dtml-let> </dtml-in> The need to do this will soon go away with the new "getId()" method mixed in to all Zope objects.
participants (4)
-
Chris McDonough -
Chris Withers -
seb -
Tres Seaver