Resource Registry
Demystified


Johannes Raggam
@ Plone Conference 2017, Barcelona

Who am I

  • Johannes Raggam
  • Graz / Austria
  • programmatic
  • BlueDynamics Alliance Memeber
  • Plone Framework Team Member

What is the resource registry?

  • Register and deploy JS and CSS resources
  • Organize dependencies
  • Optimize resources and requests
  • Same purpose and goals in Plone 4 and 5

The resource registry in Plone 4

SCREENSHOT

Concatenation and minification in defined order

Pros

  • Simple architecture
  • Addons can easily register their resources
  • Resources are immediately available
  • Automatic cache management

Cons

  • No formally defined dependencies
  • Hard to manage dependencies
  • Hard to keep requests optimized

The resource registry in Plone 5

SCREENSHOT

Based on plone.registry, RequireJS, LESS and gulp (CLI)

Pros

  • Formally defined dependencies
  • Easier to manage dependencies
  • Better CSS code organization
  • Better request optimization
  • Support for "legacy scripts" like in Plone 4
  • Automatic cache management

Cons

  • Precompiled bundles needed
  • Higher complexity
  • Hard to debug
  • Some technologies obsolete

A praise for the resource registry

  • It works quite well
  • A huge improvement for JS and CSS management
  • It's magic.

Resource and Bundle definitions

Products.CMFPlone/Products/CMFPlone/interfaces/resources.py
Products.CMFPlone/Products/CMFPlone/profiles/dependencies/registry.xml
mockup/mockup/js/config.js
mockup/mockup/patterns/formautofocus/pattern.js
Products.CMFPlone/Products/CMFPlone/static/plone.js

legacy resources



  False

      
Products.CMFPlone/Products/CMFPlone/resources/browser/cook.py
Products.CMFPlone/Products/CMFPlone/resources/browser/scripts.pt

LESS variable expansion

Products.CMFPlone/Products/CMFPlone/static/plone.less
Products.CMFPlone/Products/CMFPlone/resources/browser/mixins.py

Examples

Custom ``plone`` and ``plone-logged-in`` bundles





  
    ++plone++myproject/plone.js
    
      ++plone++myproject/plone.less
    
  

  
    ++plone++myproject/plone-compiled.min.js
    ++plone++myproject/plone-compiled.min.css
    
      plone
    
  


      
Create empty stub resources first!

Immediate Plug and Play experience

collective.lazysizes/src/collective/lazysizes/profiles/default/registry.xml

Deploy resources only for specific pages

Products.CMFPlone/Products/CMFPlone/resources/__init__.py

# -*- coding: utf-8 -*-
from plone.tiles import Tile
from Products.CMFPlone.resources import add_bundle_on_request
from Products.CMFPlone.utils import get_top_request

class FilterTile(Tile):

    def __init__(self, context, request):
        top_request = get_top_request(request)
        add_bundle_on_request(top_request, 'aaf-jsapp')
      

Deploy a bundle only for IE <= 11

In the bundle definition for your registry.xml:


  
  lte IE 11

      

Build a bundle


./bin/plone-compile-resources --help
usage: plone-compile-resources [-h] [-i INSTANCE] [-s SITE_ID] [-b BUNDLE]
                               [--compile-dir COMPILE_DIR] [-d BASE_DIR] [-G]
                               [-I] [-C]

Generate and setup Grunt infrastructure, then compile JS/LESS bundles for
Plone.

optional arguments:
  -h, --help            show this help message and exit
  -i INSTANCE, --instance INSTANCE
                        path to instance executable. If not provided, will
                        look in bin this was executed from for instance or
                        client1 (default: None)
  -s SITE_ID, --site-id SITE_ID
                        ID of the Plone site to fetch the configuration from.
                        Used only while Gruntfile generation. (default: Plone)
  -b BUNDLE, --bundle BUNDLE
                        Name of bundle to compile. Used while compile step.
                        (default: all)
  --compile-dir COMPILE_DIR
                        Output directory for the compiled bundle files. Used
                        only while Gruntfile generation. If not given the
                        directory is looked up from Plone registry. (default:
                        )
  -d BASE_DIR, --base-dir BASE_DIR
                        Base directory for this script (by default current
                        working directory). (default: .)
  -G, --skip-generate-gruntfile
                        Skip generation of Gruntfile.js (default: False)
  -I, --skip-npm-install
                        Skip npm install step (default: False)
  -C, --skip-compile    Skip compile step (running grunt) (default: False)
       

./bin/plone-compile-resources -b plone
      
Add this to your buildout:

[buildout]
parts += compileresources

[compileresources]
recipe = zc.recipe.egg
eggs =
    ${buildout:eggs}
scripts =
    plone-compile-resources
      

Future

Webpack

PLIP: Resource Registry Improvements

PLIP 1955

PLIP: Restructure CMFPlone static resources

PLIP 1653

Thank You!

Questions?