[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