Resource registries: automatic building of a bundle during installation of add-on/Plone site

I have this bundle with just one CSS file.

Right now I need to build the bundle manually through the resource registries control panel manually after installing a site with the add-on or during the add-on into an existing site. Am I missing something for the bundle to be build automatically during installation?

-aj

Hi,

Bundles must be compiled by the add-on developer (the way he/she prefers, and doing it with the resource registry is a very valid way).
The compiled bundle must be stored in the add-on sources and must be specified in registry.xml:
<value key="csscompilation">++resource++xmldirector.dropbox/styles-compiled.min.css</value>

But in your case, it does not really make sense to compile your unique css in a unique css bundle (it would make more sense if you have a bunch of .less or .scss files to compile in a unique css bundle).

So what you should do is to declare your CSS file directly as a bundle:

  • remove your first registry entry,
  • change the second one like this:
<records prefix="plone.bundles/xmldirector-dropbox"
              interface='Products.CMFPlone.interfaces.IBundleRegistry'>
      <value key="csscompilation">++resource++xmldirector.dropbox/styles.css</value>
      <value key="enabled">True</value>
      <value key="compile">False</value>
      <value key="depends">plone</value>
    </records>```
And that's it, no complation needed.
3 Likes

If csscompilation is a required setting then it should be verified and an error should be raised...just saying.

-aj

You can have a bundle with just JS or just CSS, so none of them are required.

1 Like

The documentation lacks significant information about the compilation process.

http://docs.plone.org/adapt-and-extend/theming/resourceregistry.html#bundles

  • Compile the bundle Through-The-Web and store it in the ZODB
  • Compile the bundle from the command line

Irrelevant for integrators..we are working on the file-system and configure the JS/CSS as part of our add-on and not in the context of a particular Plone site.

  • Use your own compilation chain

The Plone 5 Resource Registry can be used with your favorite build system. Use the tool you prefer create a compiled version of your bundle. Your bundle registration must provide a URL for the "jscompilation" and "csscompilation" options. Your compiled files must be in the filesystem locations that are indicated by these values.

I do not have a favorite build system and in particular I don't have an overview over all tools on the market. This section should be updated in order to reflect which common tools can be used for JS and CSS. Some examples are missing here.

-aj

Let's get back to a more general case.

Assuming you write an add-on 'my.addon' using two third-party JS modules 'foo' and 'bar' . From each JS module we need

foo1.js, foo2.js, foo1.css, foo2.css
bar1.js, bar2.js, bar1.css, bar2.css

This is not an uncommon setup. Beside a core JS/CSS you often need to include additional JS files e.g. for I18n or plugin functionality and additional CSS for theming.

So a related resource/bundle configuration would look like this?

So we need 4 different resources because a single resource can hold only one JS files but multiple CSS files, right?

So for the bundle I need to specify the compiled CSS and JS files..which tools do I have to use to generate both files from the files given above? So if I have to compile the files myself, why do I have to configure the single input files as resources?

So what is the typical integrators workflow here (assuming that I want to use existing JS add-ons (e.g. Fancytree, Datatables, JSGrid, agGrid)...in my own add-own:

  • I create a 'resources' directory in my addon and register it as browser:resourceDirectory
  • I fetch the distribution packages of the JS add-ons and unpack them inside the resources folder
  • "somehow" I need to compile JS and CSS files from the given third-party add-ons on the file system - HOW?
  • is it really necessary to specify all files as resources? Isn't it sufficient to define a bundle with the compiled files only?

How about conditional CSS/JS includes? The old resource registries support a TALES condition for conditional loading of CSS or JS (e.g. for a particular content-type, for a particular language etc.). What is the story here?

-aj

There should be a way to programmatically do the same thing as clicking "build" TTW right? Ideally setting a toggle in registry.xml would do this as a very handy use case for integrators like Andreas, but you could at least put some code in setuphandlers.py

I am not entirely sure what this code should be though. Maybe something along the lines of this? The underlying machinery is quite complex so I would appreciate if someone with more experience could point to a best practices.

request.form['bundle'] = 'my.addon'
rcp = getMultiAdapter((portal, request), name='resourceregistry-controlpanel')
rcp.save_js_build()
rcp.save_less_build()

Declaring separated resources is only useful if you wnat to re-use those resources independently in different cases or add-ons.
You are not supposed to create a resource for each js file involved in your add-on.
A resource should correspond to a feature, for instance if your add-on has a dashboard based on Datatables and D3js, and a map based on Leaflet, then you will have only 2 resources: "dashboard" and "map". A bundle allows to put all your resources together (just like the old JS registry/CSS registry bundles). So most part of time you only have one unique bundle by add-on (or maybe two, if you provide different ersources for logged-in or anonymous).

Now, if we do not have resources for third party lib, how do we provide them to the system?
They will be just dependencies of our resources.
So to create your dashboard.js, you have 2 approaches:

  • put your third-party libs in your resources folder, and in dashboard.js, load them with require:
    require(['++resource++my.addon/d3.min.js', '++resource++my.addon/datatables.min.js], function(d3, DataTables) { // your code });
    That's runtime dependency (by the way, you might perfer to not put your libs in your add-on and just use CDN urls in require, it works fine).

  • create a dedicated NPM folder (probably not in your egg ./src folder, but up to you), with a package.json listing your dependencies (and their versions), and either Gulp, Grunt or WebPack to load those dependencies and package them with your custom code to create a dashboard.js file containing the all thing.

Regarding conditional CSS/JS includes: this is handled by using add_resource_on_request (see http://docs.plone.org/adapt-and-extend/theming/resourceregistry.html?highlight=merge_with#controlling-resource-and-bundle-rendering ).