[Grok-dev] Problem with Annotations

Ethan Jucovy ejucovy at gmail.com
Wed Sep 23 11:45:15 EDT 2009


On Wed, Sep 23, 2009 at 9:57 AM, Paul Wilson <paulalexwilson at gmail.com> wrote:
[snip]
>> About your problem, I'd rather use a namespace traverser as they are
>> elegant and readable:
>> url/to/object/++ns++name/rest/of/url
>>
>> But, your metadata issue sounds weird to me
>> Can you explain in more details ?
[snip]
> The states (and transitions) are in a nested hierarchy of containment
> (which is a state diagram), which lends itself naturally to models and
> containers. So the web client get a JSON representation of a state
> something like this:
>
> http://localhost/state_diagram/state1
>
> I've got this working nicely as it stands. But how to access meta
> data? I don't want metadata to be an intrinsic part of the
> statemachine code, rather it should be added through a series of
> plugins. So when a client requests:
>
> http://localhost/state_diagram/state1/positional
>
> I want "positional" to map _somehow_ to IPositionalAnnotation, such
> that I can adapt 'state1' to it, and then use it to serialize the
> object and return it to the agent. Like wise with PUT. The important
> thing here is that the rest code doesn't have hard coded knowledge of
> what annotations it is to support, and should instead retrieve it
> dynamically through plugged-in facilities.
>
> There are two problems I can see with this;
>
>  1) How do I prevent traversal thinking that state1 is actually a
> diagram, and that positional is a state in that diagram.
>  2) How do I get the interface from the "positional" string?
>
> Actually this has just given me an idea regarding 2) ...does Grok
> support named annotations? Looking at:
>
> http://svn.zope.org/grokcore.annotation/trunk/src/grokcore/annotation/tests/annotation/name.py?rev=104270&view=markup
>
> ...it looks like it does.
>
> Perhaps I could supply a custom traverser that does:
>
> availables_ann = IAnnotations(self.context)
> try:
>  ann_class = availables_ann[name]
> except: ...
>
> iface = list(providedBy(ann_class).flattened())[0]

I'm not sure I'm following fully, and it's been way too long since
I've used Grok at all, but ..

I think I'd do this with named adapters, and use the URL component as
the name.  It adds an extra layer of indirection, though, since you
wouldn't be adapting the content object directly to the
metadata/annotation interface -- instead to a generic metadata
provider interface.  Very shaky pseudocode:

class IMetadataProvider(Interface):
  def get_metadata():
    """ returns an IAnnotations """
  def put_metadata(**kw):
    """ hmm, what? """

class PositionalMetadataProvider(grok.Adapter):
  grok.context(ContentObject)
  grok.implements(IMetadataProvider)
  grok.name('positional')

class FolksonomyMetadataProvider(object):
  grok.context(ContentObject)
  grok.implements(IMetadataProvider)
  grok.name('tags')

And then in your traverser, `return
annotation_converted_to_response(IMetadataProvider(content_object,
name=name).get_metadata())`.

--- actually, having written that out, the named adapters look like
they are just views -- IMetadataProvider's get_metadata and
put_metadata could just interact with a browser request & response
directly, and each plugin would define a view that knows how to get
the right annotation.  Hand-waving furiously here, I think most of the
logic (looking up the annotation, de/serializing, error handling)
could be centralized in a base class.  Each plugged-in subclass could
then house all the knowledge about that plugin's URL component and
annotation key & format, and register itself as a view.

Not sure if this is making any sense, or is relevant to your problem.
:)  At any rate, good luck!

egj


More information about the Grok-dev mailing list