Rethinking Plone theming in 2019

Piero Nicolli

Nicola Zambello

Piero Nicolli

Frontend developer @ RedTurtle

@pieronicolli

pnicolli

Nicola Zambello

Frontend developer @ RedTurtle

@nicolazambello

nzambello

THE PROBLEM

THE OTHER PROBLEM

THE FIRST SOLUTION

REFACTOR ALL THE THINGS!

...AND ADD WEBPACK PLEASE

GIT SUBMODULES

NO. NOT THIS TIME.

Go the
MOCKUP
way

THE ACTUAL THEME

# manifest.cfg

[theme]
# other config here

development-css = /++plone+mytheme.resources/dev/main.css
production-css = /++plone++mytheme.resources/prod/main.css
tinymce-content-css = /++plone++mytheme.resources/prod/main.css

development-js = /++plone++mytheme.resources/dev/main.js
production-js = /++plone++mytheme.resources/prod/main.js

[theme:parameters]
portal_url = python: portal.absolute_url()
env_mode = python:portal.restrictedTraverse('resources_support_view').get_env_mode()

THE ACTUAL THEME

<!-- rules.xml -->

<!-- BACKEND ONLY RULES -->
<rules css:if-not-content="body.viewpermission-view, body.viewpermission-none">
  <!-- Include barceloneta's backend.xml for backend theming. -->
  <xi:include href="++theme++barceloneta/backend.xml"><xi:fallback /></xi:include>

  <after css:theme-children="head">
    <link rel="stylesheet"
          href="{$portal_url}/++plone++mytheme.resources/{$env_mode}/backend.css" />
    <script
      src="{$portal_url}/++plone++mytheme.resources/{$env_mode}/backend.js"></script>
  </after>

  <!-- Other backend rules -->
</rules>

FEATURES

  • ES6 and newer
  • React
    • Widgets
    • Views
    • Tiles
    • ...
  • Less/Sass
  • Live Reload
  • Code Splitting (?)

WEBPACK CONFIG

module.exports = (webpackEnv, argv) => {
  const isProduction = argv.mode === 'production';
  const pkgDir = path.resolve(__dirname, './src/mytheme/resources/');
  const buildPath = isProduction
    ? path.resolve(pkgDir, './dist/prod')
    : path.resolve(pkgDir, './dist/dev');
  return {
    entry: {
      backend: path.resolve(pkgDir, './src/backend.js'),
      main: path.resolve(pkgDir, './src/main.js'),
    },
    output: {
      path: buildPath,
      filename: '[name].js',
    },
    plugins: [
      // more plugins
      ...(isProduction ? [] : [new webpack.HotModuleReplacementPlugin()]),
    ],
    devServer: {
      contentBase: buildPath,
      hot: !isProduction,
      port: 3000,
      writeToDisk: true,
    },
    // loaders, etc.
    externals: {
      jquery: 'jQuery',
    },
  };
};

PROBLEMS?

No more release problems

No more dev conflicts

  • Separate dev and prod files
  • Dev files are gitignored
  • Prod files are committed

CAN I HAZ DIS?

... ALMOST!

Check the addon_resources branch

in bobtemplates.plone

 

https://github.com/plone/bobtemplates.plone/tree/addon_resources