migrationploneplone-5.x

Plone 5 resource registries merge compiled bundle in production


My colleagues and I are trying to adapt some add-ons we have developed for Plone 4.1 in order to migrate our Plone environment to Plone 5 later this year. In doing so, we had some trouble trying to adapt our code to the new Resources Registry policies. After investigating what was going on for a while, we decided to test a add-on with minimum code in a vanilla Plone environment to find out if we where doing something wrong.

The structure of the files in this add-on is as follows:

- my.package
  - my
    - package
      - profiles
        - default
          - metadata.xml
          - registry.xml
        - uninstall
          - registry.xml
      - static
        - css
          - style.less
      - __init__.py
      - configure.zcml
    - __init__.py
  - my.package.egg-info
  - setup.cfg
  - setup.py

The contents of my.package.configure.zcml are as follows:

<configure
    xmlns="http://namespaces.zope.org/zope"
    xmlns:five="http://namespaces.zope.org/five"
    xmlns:plone="http://namespaces.plone.org/plone"
    xmlns:genericsetup="http://namespaces.zope.org/genericsetup">

    <five:registerPackage package="." initialize=".initialize" />
    <plone:static
        directory="static"
        type="plone"
        name="my.package" />

    <genericsetup:registerProfile
        name="default"
        title="my.package"
        directory="profiles/default"
        description="Installs my.package"
        provides="Products.GenericSetup.interfaces.EXTENSION" />

    <genericsetup:registerProfile
        name="uninstall"
        title="my.package"
        directory="profiles/uninstall"
        description="Uninstalls my.package"
        provides="Products.GenericSetup.interfaces.EXTENSION" />
</configure>

The contents of my.package.profiles.registry.xml are as follows:

<registry>
    <records prefix="plone.resources/my-package" 
             interface='Products.CMFPlone.interfaces.IResourceRegistry'>
        <value key="css">
            <element>++plone++my.package/css/style.less</element>
        </value>
    </records>
    <records prefix="plone.bundles/my-package"
             interface='Products.CMFPlone.interfaces.IBundleRegistry'>
        <value key="resources">
            <element>my-package</element>
        </value>
        <value key="enabled">True</value>
        <value key="compile">True</value>
        <value key="merge_with">logged-in</value>
    </records>
</registry>

The contents of my.package.static.css.style.less are as follows:

.icon-controlpanel-resourceregistries:before { color: red; }

It seems to me that the contents of the other files are of no interest for this matter (please correct me if I'm wrong).

As you can see, this add-on tries to register a simple Bundle containing a single Resource made up of only one LESS file. (The LESS file is very simple: it only changes the color of the control panel Resource Registries's icon to red, so it should be really easy to see if the style is in effect by calling the @@overview-controlpanel view). Following the directives from http://docs.plone.org/adapt-and-extend/theming/resourceregistry.html, we tried to register our bundle in the 'logged-in' bundle aggregation, as to minimize the number of files sent to the client.

Everything worked fine in "Development Mode". Once we clicked to build our bundle, the bundle was successfully compiled (we confirmed that the value of the plone.bundles/my-package.csscompilation registry item was altered from None to ++plone++static/my-package-compiled.css).

However, once we switched to production mode, we noticed that our bundle wasn't being merged into the logged-in.css file and the icon in @@overview-controlpanel would no longer have its color changed to red. We have digged into the code in Products.CMFPlone to try to find out what was going on, and found that when writing the logged-in.css file in production mode, all bundles with the merge_with attribute set to logged-in and with some value set for the csscompilation attribute where merged into the file ( see Products.CMFPlone.resources.browser.combine.write_css). However, even though our bundle had the correct merge_with attribute, the csscompilation one was None, which explains why the merging didn't occur.

We tried a few alternatives, but none of them worked:

It seems that the request is storing the None value in its form attribute, for some unknown reason.

We tested our add-on first in a vanilla Plone 5.0.6 and then in a vanilla Plone 5.1a2. Both showed the same behavior.

Before summing things up, let me first emphasize that this was only a simple example to try to investigate if we were doing something wrong in our procedures. We know that in this specific scenario, it would be much easier to just use a CSS file instead of LESS and use the csscompilation attribute in our Generic Setup profile. However, we would like to be prepared for a scenario where we would have various LESS files that actually make use of the plone LESS variables in a bundle and that we could merge in production to the logged-in.css file (or the default.css file for that matter).

Anyway, we are wondering if we did anything wrong in our procedures or if this is a bug in Products.CMFPlone and we should open a ticket reporting it. Any comments or advice would be greatly appreciated!


Solution

  • Your add-on must provide a compiled version of your bundle CSS (because people who will install your add-on must be able to use it directly in prod mode without going to the Resource registry and compile it themselves).

    So compile your css (you can just copy the one you get when you compile it via Resource registry), put it in /static, and add to your bundle:

    <value key="csscompilation">++plone++static/my-package-compiled.css</value>