Uuid traverser (plone.app.uuid)?

plone.app.uuid provides a @@redirect-to-uuid view, but afaik there is no view or traverser to access an object by uuid. I was going to file an issue suggesting this but plone.app.uuid has no tracker enabled. Could someone enable it? @esteele? @mauritsvanrees?

It would be useful to be able to access an object by its uuid, given uuids are permanent, and such mechanism would also be shorter and more convenient than using the full (sometimes loooong) path.

You can use plone.app.uuid.utils.uuidToObject or .uuidToCatalogBrain

Thanks, I presume those would be useful when developing a view or traverser. I think plone.api also has a method for getting object by uuid? Or maybe it was the other way around...?

Keep in mind that those will only resolve uuids if the current user has View permission on the object (since it does a restricted catalog query using the UID index). For some projects I use an unrestricted version which is implemented like this:

from zope.component.hooks import getSite
from Products.CMFCore.utils import getToolByName

def unrestricted_uuidToObject(uuid):
    """Less restricted version of plone.app.uuid

    "Given a UUID, attempt to return a content object. Will return
    None if the UUID can't be found."
    """
    site = getSite()
    if site is None:
        return None
    catalog = getToolByName(site, 'portal_catalog', None)
    if catalog is None:
        return None
    result = catalog.unrestrictedSearchResults(UID=uuid)
    if len(result) != 1:
        return None
    return result[0]._unrestrictedGetObject()

(Updating that to use plone.api functions where appropriate is left as an exercise...)

The plone.api docs say yes!
https://docs.plone.org/develop/plone.api/docs/api/content.html#plone.api.content.get
plone.api.content.get(UID=uuid)

And there's also resolveuid view, but that also does just redirects.

I have enabled the issue tracker on plone.app.uuid.

Actually, the utility functions provided by plone.app.uuid only seem to work on published content. They get the object by first querying the catalog thus: catalog(UID=<uuid>). I tried that and it only returns items in published state by default.

EDIT: oh my. I guess that was because I was calling them from within the traverser. I remember reading something about security context not being yet set up when a ITraversable adapter is called..?

There's now an issue for this at plone.app.uuid (thanks Maurits). I also wrote a draft uuid traverser; see the uuid_traverser branch.