[Grok-dev] JSON method/view name

Marc Rijken marc at rijken.org
Mon Oct 26 14:53:41 EDT 2009


Hi,

I have changed the grok.name directive and grok.JSONGrokker to make the 
suggestion of Martijn work.

I added the folowing to the grok.name declaration in grokcore/component.py:

      def __call__(self, func):
          # grok.name can be used both as a class-level directive and
          # as a decorator for methods.  Therefore we return a decorator
          # here, which may be used for methods, or simply ignored when
          # used as a directive.
          frame = sys._getframe(1)
          newName = frame.f_locals[self.dotted_name()]

          # delete the decorator from the class
          # so the decorator can be used more than once in the class
          del frame.f_locals[self.dotted_name()]

          self.set(func, newName)
          return func

I changed the JSONGrokker in grok/meta.py:

          adapts = (context, layer)

          newName = grok.name.bind().get(method)
          if newName:
              name = newName
              setattr(method.im_class, newName, method)
              #XXX Is it possible to remove the copy of the method with
              # the oldname from the class?
          else:
              name = method.__name__


And to make sure it works ok I added a test in grok/tests/json. See the
attached namedecorator.py.

Is this the way you want it?

Regards,

Marc

Martijn Faassen wrote:
> Hey,
> 
> Marc Rijken wrote:
>> I want to use 'getAccounts.json' in the url for a JSON view. Because the 
>> method name of a grok.JSON view class will be used as name of the json 
>> view and because a method name normally can not contain a dot, I had to 
>> make a work around. The work around is:
>>
>> class JSONApi(grok.JSON):
>>      grok.context(tmx.ITopicMapX)
>>
>>      def getAccounts(self):
>>          return { "status": "ok"}
>>
>>      getAccounts.__name__ = 'getAccounts.json'
>>
>> setattr(JSONApi, 'getAccounts.json', JSONApi.getAccounts)
>>
>> This work around works ok, but it looks uggly. Is this is preferred way 
>> to do so or do you have a better solution?
> 
> There's no official better solution. We should look into creating one, 
> possibly involving making @grok.name() a decorator that can be used in 
> this context.
> 
> For a temporary somewhat prettier solution you could make your own 
> decorator that sets __name__ and does the setattr too (though I think 
> the latter is difficult as you wouldn't have access to the class yet 
> unless you resorted to frame hacks, I think).
> 
> Alternatively you could create your own grok.View subclass that 
> implements its own render() method to handle JSON. You should then be 
> able to use grok.name().
> 
> Finally you could create an alternative baseclass along the lines of 
> grok.JSON and implement your own JSONGrokker that does the name inspection.
> 
> If you're up to the challenge you'd be more than welcome to try to get 
> this into Grok itself. This applies to anyone else too, of course! I 
> think the @grok.name() decorator could be used:
> 
>     @grok.name('getAccounts.json)
>     def getAccounts(self):
>          ....
> 
> Reusing a directive as a decorator is tricky however. We have a 
> precedent in grok.require, but it isn't the easiest thing to get going. 
> It'd be nice if we had more general infrastructure to accomplish this in 
> Martian.
> 
> Regards,
> 
> Martijn
> 
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> https://mail.zope.org/mailman/listinfo/grok-dev

-------------- next part --------------
A non-text attachment was scrubbed...
Name: namedecorator.py
Type: text/x-python
Size: 993 bytes
Desc: not available
Url : http://mail.zope.org/pipermail/grok-dev/attachments/20091026/dc6ceda9/attachment.py 


More information about the Grok-dev mailing list