[Solved] Create Folders and Files with the id 'icon'


we need the possibility to create Folders and Files that can have the id icon. Unfortunately this seems not to be possible. Every attempt to create such a Folder results in the id icon-1. We found out that there is a method called icon in Products.CMFCore.DynamicType which seems to be the reason. Do you have any idea how we could possibly ignore that method?
Would it be an idea to inherit the Folder type and substitute the icon method with nothing? I did not test that up to now but maybe this would also lead into more trouble. Do you have any idea how to deal with that?

There is a real reason for this kind of check: Zope acquisition
While this check appears annoying, it often prevents unwanted and unexpected errors.
So things are as they are and you unlikely what to change this behavior.
If you need to map some requests with icon in the URL when use a RewriteRule for fixing the mapping.

Thank you, Andreas.
Is it possible to make the rewriting within Plone itself or do I need an external Proxy like Apache? On our production we definitely use Apache and load balancer but for local development it would nice to simply browse to localhost:8080 and the rewriting works there too.

Eventually you can do something with a "traversal hook" like zope.traversing.interfaces.IBeforeTraverseEvent - not sure if this will work. Maybe some other traversal hook could work.

If you are running Plone 5.2 on top of WSGI then some WSGI middleware might do the trick. A custom WSGI middleware would require a custom wsgi.ini file (which is usually generated by the zope2instance recipe. There is an option for zope2instance for providing your own custom wsgi.ini.

I am tinkering around with this code snippet:

from Products.CMFCore.interfaces import ISiteRoot
from zope.traversing.interfaces import IBeforeTraverseEvent
import zope.component

def check_redirect(site, event):
    request = event.request

    print(request.get('TraversalRequestNameStack', []))
    #import pdb; pdb.set_trace()

    return request.response.redirect("http://localhost:8080/", lock=True)

gsm = zope.component.getGlobalSiteManager()
gsm.registerHandler(check_redirect, (ISiteRoot, IBeforeTraverseEvent))

But I do not understand how to modify the request to answer with a response I want.

For example if somewhere in the path is icon then change the request to icon-1 without letting the browser notice it. So the call should be transparent for the browser. It should think it really gets icon but in reality it is icon-1.
In my example I tried to force a redirect but this is only one of the ideas I had. I am sure somewhere is the right way but I can not find it.

One way is to modify TraversalRequestNameStack. It is a list and contains the traversal steps still to be performed (when I remember right in reverse order). You can modiiy this list to control the traversal process, e.g. replace icon by icon-1.

Note that those modifications will be reflected in the URL (and friends), e.g. when you have replaced icon by icon-1, then icon-1 will arrive in request['URL'].

1 Like

Modifying TraversalRequestNameStack was the thing to do. I am now able to create Folders and Files with any name and map the incoming request to safe Plone id, in case the original path is not compatible with Plone. icon was only one example. Now it works with everything. Very cool!