When Multilingual is enabled and VHM is enabled too, serving any folderish's folder_contents
under a language folder as a top level domain name is currently broken (if en.site.com/archives
is VHMed to PloneSite/en/archives
then @@qsOptions
URL is /archives/@@qsOptions
instead of being /@@qsOptions
as it should be.
The fundamental problem is that the function get_top_site_from_url(...)
is failing to retrieve the actual top site because it can't find a site in the traversal structure, so it picks the last folderish as the site, which is obvs broken because /@@qsOptions
only works on site roots, not on folderish content.
This code makes it so that any site found in the structure is returned as the top site from the URL, but if no top site is found in that traversal, the actual site from getSite()
is returned instead, which is the correct behavior based on how the function is named, and actually fixes the /@@qsOptions
conundrum.
Reproducer
Odd intersection of circumstances to reproduce bug:
- Create classic
Plone
site.
- Enable Multilingual with
en-US
or some other language.
- Verify visiting
/Plone
redirects to Plone/en-US
or your language folder of choice.
- VHM your site so that
/Plone/en-US
is accessible as /
(a standard, supported Multilingual rewrite configuration typically used by Ploners for language-code subdomain hosting). Plone/en-US/VirtualHostRoot
is the relevant VHM rewrite.
- Visit the site. Verify that site is accessible as
/
.
- Create folder
xxx
on that location.
- Visit folder
xxx
on that location.
- Click on Folder contents in the editor toolbar.
- Verify that the folder contents screen for
xxx
loads, but the actual listing remains empty.
- Verify that there is an HTTP 404 for
@@qsOptions
in the network panel of your browser inspector.
Rationale
This code makes the method sometimes return a content object in some cases, rather than an actual site root.
Why?
All callsites (see below) need a "root object" from the perspective of the browser to compute a root and generate various URLs for their own purposes, because all their purposes are XHR browser stuff (fill lists of objects and search results, chiefly). This method I'm fixing determines the "root" used for that tree which is used in related items, image insertion, and folder contents browsing, and if that "root" is incorrect / does not correspond to what the browser sees as "root", nothing works.
Needless to say, this method should never be used to traverse anything server-side.
Quality control
Callsites
My omelette is big. There are not that many uses, and all its uses currently broken are fixed by this patch. I count two uses:
plone.app.content.browser.contents
:ContentsBaseAction
/ get_options
/ ContextInfo.call
plone.app.widgets
:get_relateditems_options
Unit and regression testing
All current unit tests pass now. I have added a test case to cover the "root URL object is not actually a site" case, which was never tested before. In addition to that, I have tested this with a local build (most up to date code) and here is what I can verify:
- Related items works now!
- Image insertion works as well.
- Browsing folders in folder contents works too.
So pretty much everything that was broken before, is no longer broken thanks to this modest change. And that is the complete manual regression test of all users of this code.