AW: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Roger Ineichen
Hi Martin

 Betreff: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()
 
I just stumbled over something that utterly baffles me and 
 hope someone can point out the absolutely obvious to me.
 
I've got a view defined in a configure.zcml that points to this
 class:
 
  class MyView(BrowserView):
  def __call__(self):
  self.pt = ViewPageTemplateFile('empty.pt')
  data = self.pt()
  return data
 
That works fine. However, I don't really need pt as 
 instance variable, so I turned it into a local variable:
 
  class MyView(BrowserView):
  def __call__(self):
  pt = ViewPageTemplateFile('empty.pt')
  data = pt()
  return data

try this:
 
pt = ViewPageTemplateFile('empty.pt')
return pt(self)

Regards
Roger Ineichen

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Martin J. Laubach

 class MyView(BrowserView):
 def __call__(self):
 pt = ViewPageTemplateFile('empty.pt')
 data = pt()
 return data


try this:

pt = ViewPageTemplateFile('empty.pt')
return pt(self)


  Nope, same result:

AttributeError: 'str' object has no attribute 'other'

  Cheers,

mjl
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Albertas Agejevas
On Thu, Apr 10, 2008 at 03:22:33PM +0200, Martin J. Laubach wrote:
   That works fine. However, I don't really need pt as instance  
 variable,
 so I turned it into a local variable:
 
 class MyView(BrowserView):
 def __call__(self):
 pt = ViewPageTemplateFile('empty.pt')
 data = pt()
 return data

Well, it's called a *View*PageTemplate for a reason :-) If the file is
really empty and you do not need to pass any arguments to it (view,
context, request), use a plain PageTemplateFile
(zope.pagetemplate.pagetemplatefile.PageTemplateFile).

Albertas
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Martin J . Laubach
 Well, it's called a *View*PageTemplate for a reason :-) If the  
file is

 really empty and you do not need to pass any arguments to it (view,
 context, request), use a plain PageTemplateFile

  No, of course it's not empty and it needs the parameters. Nor does
the view really look as trivial as the example. That was the minimal
test case for the behaviour I could come up with.

   I still don't understand how the naming / storage of a variable
holding the page template can influence the page rendering process.

  Cheers,

mjl

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Albertas Agejevas
On Thu, Apr 10, 2008 at 04:08:43PM +0200, Martin J.Laubach wrote:
  Well, it's called a *View*PageTemplate for a reason :-) If the  
 file is
  really empty and you do not need to pass any arguments to it (view,
  context, request), use a plain PageTemplateFile
 
   No, of course it's not empty and it needs the parameters. Nor does
 the view really look as trivial as the example. That was the minimal
 test case for the behaviour I could come up with.
 
I still don't understand how the naming / storage of a variable
 holding the page template can influence the page rendering process.

ViewPageTemplate must be in the view's namespace, and it magically
fishes out the view, view's context and request, and makes them
available in the TAL namespace.  Otherwise you would have to pass
these arguments by hand.  When using PageTemplateFile you would have
to pass the args like this:

 pt = PageTemplateFile(file.pt)
 result = pt(arg1, arg2, arg3=value, arg4=value)

Then the positional args would be available in the TAL namespace as args,
and the keyword arguments would be available as options:

   tal:block define=arg1 python:args[0];
  arg2 python:args[1];
  arg3 options/arg3;
  arg4 options/arg4; /

Arguably, the keyword arguments are a bit less ugly.

HTH,
Albertas
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Marius Gedminas
Hi!

On Thu, Apr 10, 2008 at 03:22:33PM +0200, Martin J. Laubach wrote:
   I just stumbled over something that utterly baffles me and hope
 someone can point out the absolutely obvious to me.

Sure.

   I've got a view defined in a configure.zcml that points to this class:

 class MyView(BrowserView):
 def __call__(self):
 self.pt = ViewPageTemplateFile('empty.pt')
 data = self.pt()
 return data

   That works fine.

I'm actually surprised that this works.

The usual way in Zope 3 is

  class MyView(BrowserView):
  pt = ViewPageTemplateFile('empty.pt')
  def __call__(self):
  data = self.pt()
  return data

which can also be shortened to

  class MyView(BrowserView):
  __call__ = ViewPageTemplateFile('empty.pt')

 However, I don't really need pt as instance variable,
 so I turned it into a local variable:

 class MyView(BrowserView):
 def __call__(self):
 pt = ViewPageTemplateFile('empty.pt')
 data = pt()
 return data

   And that version throws an exception:

 Traceback (innermost last):
   Module ZPublisher.Publish, line 119, in publish
   Module ZPublisher.mapply, line 88, in mapply
   Module ZPublisher.Publish, line 42, in call_object
   Module mjl.example.browser.myform, line 31, in __call__
   Module Shared.DC.Scripts.Bindings, line 313, in __call__
   Module Shared.DC.Scripts.Bindings, line 348, in _bindAndExec
   Module Shared.DC.Scripts.Bindings, line 1, in ?
   Module Shared.DC.Scripts.Bindings, line 293, in _getTraverseSubpath

This does not look like Zope 3 to me.

 AttributeError: 'str' object has no attribute 'other'

Okay, I know why the code doesn't work, but I don't know why you get
this strange Zope 2 error.  I'll answer just the first part.


   Same if I just do the simpler return ViewPageTemplateFile('empty.pt')()
 of course.

   I simply do not understand why, what or who does care how I name my
 variables or where I put them? Please hit me hard with a cluebat. Twice.

You have encountered the magic of Python descriptors.  Feel free to skip
the detailed explanation if you're in a hurry:

ViewPageTemplateFile is a descriptor, which is a fancy way of saying
object that has a method named __get__.  When you access a descriptor
from an instance, Python silently calls __get__ for you, so 

  class MyView(BrowserView):
  pt = ViewPageTemplateFile('empty.pt')
  def __call__(self):
  pt = self.pt()

is more or less equivalent to

  class MyView(BrowserView):
  def __call__(self):
  pt = ViewPageTemplateFile('empty.pt')
  pt = pt.__get__(self, ViewPageTemplateFile)

ViewPageTemplateFile.__get__ returns a BoundPageTemplate object
(it's a bit like the difference between unbound and bound methods)
that knows which view it is bound to and can pass it via the view
name to your TALES expressions.

Now when you invoke ViewPageTemplateFile's __call__, you have to
pass the view as the first argument:

  class MyView(BrowserView):
  def __call__(self):
  pt = ViewPageTemplateFile('empty.pt')
  return pt(self)

but when you invoke BoundPageTemplate.__call__, it knows and
provides the view argument itself:

  class MyView(BrowserView):
  def __call__(self):
  pt = ViewPageTemplateFile('empty.pt')
  bound_pt = pt.__get__(self, ViewPageTemplateFile)
  return bound_pt()

which is more or less the same as

  class MyView(BrowserView):
  pt = ViewPageTemplateFile('empty.pt')
  def __call__(self):
  bound_pt = self.pt
  return bound_pt()

[End of explanation]

So, if you really want to use a local variable instead of a class
attribute, pass the view itself as the first argument to __call__

  class MyView(BrowserView):
  def __call__(self):
  pt = ViewPageTemplateFile('empty.pt')
  data = pt(self)
  return data

HTH,
Marius Gedminas
-- 
Anyone can do any amount of work provided it isn't the work he is supposed
to be doing at the moment.
-- Robert Benchley


signature.asc
Description: Digital signature
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Martin J . Laubach

 ViewPageTemplate must be in the view's namespace, and it magically
 fishes out the view, view's context and request, and makes them
 available in the TAL namespace.

  Ah, so there _IS_ heavy magic involved here. Thanks for
clarifying that, I was already doubting my sanity!

  Cheers,

mjl



___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Jim Fulton


On Apr 10, 2008, at 10:30 AM, Marius Gedminas wrote:


 I've got a view defined in a configure.zcml that points to this  
class:


   class MyView(BrowserView):
   def __call__(self):
   self.pt = ViewPageTemplateFile('empty.pt')
   data = self.pt()
   return data

 That works fine.


I'm actually surprised that this works.



It works because, unlike regular objects, ExtensionClass instances  
call descriptors when you get a descriptor as an attribute.  This is  
for backward compatibility with __of__ methods (which become __get__  
methods).


Jim


--
Jim Fulton
Zope Corporation


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Martin J. Laubach

 ViewPageTemplate must be in the view's namespace, and it magically
 fishes out the view, view's context and request, and makes them
 available in the TAL namespace.

 Ah, so there _IS_ heavy magic involved here. Thanks for
clarifying that, I was already doubting my sanity!



This is exactly the same magic that methods use. ViewPageTemplateFiles
are, like functions, meant to be used as methods and to be bound to
instances.


  Okay, then this leads me to the strong suspicion that what I'm
(mis)using ViewPageTemplateFiles for is the wrong way to attack
the problem.

  What I'm doing is something along the lines of

class MyView(BrowserView):
def __call__(self):
	pagename = somehow_compute_new_page_name(self.request,  
self.context)

pt = ViewPageTemplateFile(pagename)
return pt.__get__(self, self.__class__)()

  but quite obviously, that's not how it's meant to be used, is it...
Perhaps I need a radically different approach?

  Cheers,

mjl

___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Jim Fulton


On Apr 10, 2008, at 11:46 AM, Martin J.Laubach wrote:

 ViewPageTemplate must be in the view's namespace, and it magically
 fishes out the view, view's context and request, and makes them
 available in the TAL namespace.

 Ah, so there _IS_ heavy magic involved here. Thanks for
clarifying that, I was already doubting my sanity!



This is exactly the same magic that methods use.   
ViewPageTemplateFiles are, like functions, meant to be used as methods  
and to be bound to instances.


Jim

--
Jim Fulton
Zope Corporation


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Fred Drake
On Thu, Apr 10, 2008 at 2:59 PM, Martin J. Laubach [EMAIL PROTECTED] wrote:
  Perhaps I need a radically different approach?

Sounds like you want PageTemplateFile.


 -Fred

-- 
Fred L. Drake, Jr. fdrake at gmail.com
Chaos is the score upon which reality is written. --Henry Miller
___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users


Re: [Zope3-Users] Weird behaviour of ViewPageTemplateFile()

2008-04-10 Thread Jim Fulton


On Apr 10, 2008, at 2:59 PM, Martin J. Laubach wrote:

 ViewPageTemplate must be in the view's namespace, and it magically
 fishes out the view, view's context and request, and makes them
 available in the TAL namespace.

Ah, so there _IS_ heavy magic involved here. Thanks for
clarifying that, I was already doubting my sanity!



This is exactly the same magic that methods use.  
ViewPageTemplateFiles

are, like functions, meant to be used as methods and to be bound to
instances.


 Okay, then this leads me to the strong suspicion that what I'm
(mis)using ViewPageTemplateFiles for is the wrong way to attack
the problem.

 What I'm doing is something along the lines of

class MyView(BrowserView):
def __call__(self):
	pagename = somehow_compute_new_page_name(self.request,  
self.context)

pt = ViewPageTemplateFile(pagename)
return pt.__get__(self, self.__class__)()

 but quite obviously, that's not how it's meant to be used, is it...
Perhaps I need a radically different approach?


Need is too strong. You might prefer another approach based on what  
you now know. :)


Fred suggested using a page-template class that doesn't behave as a  
method.


Another option might be to create a bunch of methods and then have  
your function dispatch to those, depending, of course, on how many  
there are.


Jim

--
Jim Fulton
Zope Corporation


___
Zope3-users mailing list
Zope3-users@zope.org
http://mail.zope.org/mailman/listinfo/zope3-users