resource registries plone conf 2014

30
Resource Registries Ramon Navarro Bosch & Rob Gietema

Upload: ramon-bosch

Post on 21-Jun-2015

721 views

Category:

Technology


0 download

DESCRIPTION

New resource registry in Plone 5! Plone Conference 2014. Using RequireJS/Bower/less integrated with Plone!

TRANSCRIPT

Page 1: Resource registries plone conf 2014

Resource RegistriesRamon Navarro Bosch & Rob Gietema

Page 2: Resource registries plone conf 2014
Page 3: Resource registries plone conf 2014

Ramon Navarro Bosch

• Iskra.CAT

• Member Plone Foundation

• FWT member

Page 4: Resource registries plone conf 2014

Rob Gietema

• Four Digits

• Plone Foundation Member

Page 5: Resource registries plone conf 2014

Current State<?xml version="1.0"?> <object name="portal_javascripts" meta_type="JavaScripts Registry"> <javascript compression="safe" authenticated="True" id="hello-world.js" insert-after="*" /> </object>

<?xml version="1.0"?> <object name="portal_css"> <stylesheet title="" id="hello-world.css" media="screen" rel="stylesheet" rendering="link" cacheable="True" compression="safe" cookable="True" enabled="1" expression="" insert-before="print.css" /> </object>

• JS Registry

• CSS Registry

• Tools

Page 6: Resource registries plone conf 2014

Limitations• JS & CSS have evolved

• Dependency management

• Precompiling (LESS / SASS)

• Versioning

• Mockup

Page 7: Resource registries plone conf 2014

RequireJS

// File: app.js // For any third party dependencies, like jQuery, place them in the lib folder.

// Configure loading modules from the lib directory, // except for 'app' ones, which are in a sibling // directory. requirejs.config({ baseUrl: 'lib', paths: { app: '../app' } });

// Start loading the main app file. Put all of // your application logic in there. requirejs(['app/main']);

<!DOCTYPE html> <html> <head> <script data-main="app" src="lib/require.js"></script> </head> <body> <h1>Hello World</h1> </body> </html>• Include require.js

• Add all your dependencies in Javascript

• Async loading of files and modules

Page 8: Resource registries plone conf 2014

GRUNTmodule.exports = function(grunt) {

grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), concat: { options: { separator: ';' }, dist: { src: ['src/**/*.js'], dest: 'dist/<%= pkg.name %>.js' } }, qunit: { files: ['test/**/*.html'] }, watch: { files: ['<%= jshint.files %>'], tasks: ['jshint', 'qunit'] } });

grunt.loadNpmTasks('grunt-contrib-qunit'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.loadNpmTasks('grunt-contrib-concat');

grunt.registerTask('test', ['jshint', 'qunit']);

grunt.registerTask('default', ['qunit', 'concat']);

};

• Task runner

• Run tests, concat, minimize, JSHint etc

Page 9: Resource registries plone conf 2014

NPM

npm install (with no args in a package dir) npm install <tarball file> npm install <tarball url> npm install <folder> npm install [@<scope>/]<name> [--save|--save-dev|--save-optional] [--save-exact] npm install [@<scope>/]<name>@<tag> npm install [@<scope>/]<name>@<version> npm install [@<scope>/]<name>@<version range> npm i (with any of the previous argument usage)

• Node.js package manager

• Dependencies

• Versioning

Page 10: Resource registries plone conf 2014

Bower

{ "name": "my-project", "version": "1.0.0", "main": "path/to/main.js", "ignore": [ ".jshintrc", "**/*.txt" ], "dependencies": { "<name>": "<version>", "<name>": "<folder>", "<name>": "<package>" }, "devDependencies": { "<test-framework-name>": "<version>" } }

• Javascript package manager

• Dependencies

• Versioning

Page 11: Resource registries plone conf 2014

LESS / SASS@base: #f938ab;

.box-shadow(@style, @c) when (iscolor(@c)) { -webkit-box-shadow: @style @c; box-shadow: @style @c; } .box-shadow(@style, @alpha: 50%) when (isnumber(@alpha)) { .box-shadow(@style, rgba(0, 0, 0, @alpha)); } .box { color: saturate(@base, 5%); border-color: lighten(@base, 30%); div { .box-shadow(0 0 5px, 30%) } }

.box { color: #fe33ac; border-color: #fdcdea; } .box div { -webkit-box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); box-shadow: 0 0 5px rgba(0, 0, 0, 0.3); }

• Precompiler for CSS

• Variables

• Nesting

• Macro's

Page 12: Resource registries plone conf 2014

Design of the SolutionBUNDLE

RESOURCE

BOWER COMPONENT

MOCKUP COMPONENT

STANDALONE FILES

DIAZO

STATIC HTML REGISTRY

Page 13: Resource registries plone conf 2014

Bundles

• Dependency

• Compilation

• Enabled <records prefix="plone.bundles/plone" interface='Products.CMFPlone.interfaces.IBundleRegistry'> <value key="resources"> <element>plone</element> </value> <value key="enabled">True</value> <value key="jscompilation">++plone++static/plone-compiled.js</value> <value key="csscompilation">++plone++static/plone-compiled.css</value> <value key="last_compilation">2014-08-14 00:00:00</value> </records>

<records prefix="plone.bundles/plone-legacy" interface='Products.CMFPlone.interfaces.IBundleRegistry'> <value key="resources" purge="false"> <element>plone_javascript_variables</element> <element>unlockOnFormUnload</element> <element>table_sorter</element> <element>inline-validation</element> <element>jquery-highlightsearchterms</element> <element>cookie_functions</element> </value> <value key="jscompilation">++plone++static/plone-legacy-compiled.js</value> <value key="csscompilation">++plone++static/plone-legacy-compiled.css</value> <value key="last_compilation">2014-08-14 00:00:00</value> <value key="compile">False</value> <value key="enabled">True</value> </records>

Page 14: Resource registries plone conf 2014

Resources

• js

• export/init

• css

• url <records prefix="plone.resources/mockup-patterns-structure" interface='Products.CMFPlone.interfaces.IResourceRegistry'> <value key="js">++resource++mockup/structure/pattern.js</value> <value key="url">++resource++mockup/structure</value> <value key="css"> <element>++resource++mockup/structure/less/pattern.structure.less</element> </value> </records>

<records prefix="plone.resources/tinymce" interface='Products.CMFPlone.interfaces.IResourceRegistry'> <value key="js">++plone++static/components/tinymce/tinymce.js</value> <value key="export">window.tinyMCE</value> <value key="init">function () { this.tinyMCE.DOM.events.domLoaded = true; return this.tinyMCE; }</value> <value key="css"> <element>++plone++static/components/tinymce/skins/lightgray/skin.min.css</element> <element>++plone++static/components/tinymce/skins/lightgray/content.inline.min.css</element> </value> </records>

<records prefix="plone.resources/mockup-patterns-select2" interface='Products.CMFPlone.interfaces.IResourceRegistry'> <value key="js">++resource++mockup/select2/patterns.js</value> <value key="css"> <element>++resource++mockup/select2/pattern.select2.less</element> </value> </records>

Page 15: Resource registries plone conf 2014

LESS Vars <!-- Mixins vars for less with the paths --> <record name="plone.lessvariables"> <field type="plone.registry.field.Dict"> <title>Less variables</title> <description>Variables that are going to be compiled on less</description> <key_type type="plone.registry.field.ASCIILine" /> <value_type type="plone.registry.field.TextLine" /> </field> <value> <element key="bowerPath">\"{site_url}/++plone++static/components/\"</element> <element key="mockupPath">\"{site_url}/++resource++mockup/\"</element> <element key="mockuplessPath">\"{site_url}/++resource++mockupless/\"</element>

<element key="plone-link-color">rgba(0,123,179,1)</element> <element key="plone-gray-lighter">lighten(#000, 80%)</element> <element key="plone-gray-light">lighten(#000, 46.5%)</element>

<element key="plone-toolbar-bg">rgba(0,0,0,.9)</element> <element key="plone-toolbar-submenu-bg">rgba(20,20,20,.9)</element> <element key="plone-toolbar-font-primary">'Roboto Condensed', sans-serif</element>

Page 16: Resource registries plone conf 2014

Pattern Options <record name="plone.patternoptions"> <field type="plone.registry.field.Dict"> <title>Patterns configuration</title> <description>Base pattern configuration options</description> <key_type type="plone.registry.field.ASCIILine" /> <value_type type="plone.registry.field.Text" /> </field> <value> <element key="pickadate">{"selectYears": 200}</element>

Page 17: Resource registries plone conf 2014

Development & Production

• Compile on browser on each reload using RequireJS / LESS

• Develop static HTML with compiled bundles

• Grunt using browser config.js/mixins.less

• Get the compiled css/js bundles

• Deployment with compiled css/js

<record name="plone.resources.development"> <field type="plone.registry.field.Bool"> <title>Frontend development mode</title> </field> <value>true</value> </record>

Page 18: Resource registries plone conf 2014

Diazo[theme] title = Barceloneta Theme description = Plone 5 theme rules = /++theme++barceloneta/rules.xml prefix = /++theme++barceloneta doctype = <!DOCTYPE html> enabled-bundles = barceloneta disabled-bundles =

<!-- CSS --> <after theme-children="/html/head" content="/html/head/link" /> <!-- Script --> <after theme-children="/html/head" content="/html/head/script" />

Page 19: Resource registries plone conf 2014

Views: config.jsrequirejs.config({ baseUrl: 'http://localhost:8080/Plone', paths: {

'tinymce-save': ‘++plone++static/components/tinymce/plugins/save/plugin', 'mockup-patterns-accessibility': ‘++resource++mockup/accessibility/pattern’, 'mockup-patterns-tinymce-url': '++resource++mockup/tinymce' … 'mockup-patterns-formautofocus': '++resource++mockup/formautofocus/pattern', 'bootstrap-tooltip': '++plone++static/components/bootstrap/js/tooltip', 'resource-plone-app-event-portlet_calendar-js': '++resource++plone.app.event.portlet_calendar', 'dropzone': '++plone++static/components/dropzone/downloads/dropzone-amd-module'},

shim: { 'tinymce-save': {deps: ['tinymce']}, 'mockup-router': {}, 'tinymce-spellchecker': {deps: ['tinymce']}, 'jquery.event.drop': {exports: '$.drop', deps: ['jquery']}, 'tinymce-autosave': {deps: ['tinymce']}, … 'bootstrap-tooltip': {deps: ['jquery']}},

optimize: 'uglify', wrapShim: true });

Page 20: Resource registries plone conf 2014

Views: less-variables.js window.less = { env: "development", logLevel: 2, async: false, fileAsync: false, errorReporting: window.lessErrorReporting || 'console', poll: 1000, functions: {}, relativeUrls: true, dumpLineNumbers: "comments", globalVars: {

sitePath: '"http://localhost:8080/Plone"', isPlone: 'true', isMockup: 'false', 'plone-toolbar-font-primary': "'Roboto Condensed', sans-serif", 'plone-gray-lighter': "lighten(#000, 80%)", 'mockuplessPath': "\"http://localhost:8080/Plone/++resource++mockupless/\"", 'bowerPath': "\"http://localhost:8080/Plone/++plone++static/components/\"", 'plone-toolbar-internally-published-color': "rgb(136,61,250)", 'mockupPath': "\"http://localhost:8080/Plone/++resource++mockup/\"", … 'plone-toolbar-private-color': "rgb(196,24,60)", 'plone-screen-xs-max': "(@plone-screen-sm-min + 1)", 'plone-toolbar-bg': "rgba(255,0,0,.9)", 'plone-gray-light': "lighten(#000, 46.5%)", 'barceloneta': ‘"http://localhost:8080/Plone/++plone++barceloneta/less/barceloneta.plone.less"', … 'picker_time': '"http://localhost:8080/Plone/++plone++static/components/pickadate/lib/themes/classic.time.css"', 'picker': '"http://localhost:8080/Plone/++plone++static/components/pickadate/lib/themes/classic.css"', 'plone-patterns-toolbar': '"http://localhost:8080/Plone/++plone++static/patterns/toolbar/src/css/toolbar.plone.less"', 'plone': '"http://localhost:8080/Plone/++plone++static/plone.less"', …}};

Page 21: Resource registries plone conf 2014

plone.less… @import url("@{mockup-patterns-upload}"); @import url("@{plone-patterns-toolbar}"); @import url("@{mockup-patterns-tinymce}");

@import "@{bowerPath}bootstrap/less/dropdowns.less"; …

Page 22: Resource registries plone conf 2014

plone.jsrequire([ 'jquery', 'mockup-registry', 'mockup-patterns-base', 'mockup-patterns-select2', 'mockup-patterns-pickadate', 'mockup-patterns-relateditems', 'mockup-patterns-querystring', 'mockup-patterns-tinymce', 'plone-patterns-toolbar', 'mockup-patterns-accessibility', 'mockup-patterns-autotoc', 'mockup-patterns-formunloadalert', 'mockup-patterns-preventdoublesubmit', 'mockup-patterns-formautofocus', 'mockup-patterns-modal', 'mockup-patterns-structure', 'bootstrap-dropdown', 'bootstrap-collapse', ‘bootstrap-tooltip' …

Page 23: Resource registries plone conf 2014

TTW customization

• Fully customizable trough the web

• Controlpanel in Plone

Page 24: Resource registries plone conf 2014

Legacy Plone

• cssregistry.xml and jsregistry.xml still work

• Legacy bundle

• Not all attributes are supported

<?xml version="1.0"?> <object name="portal_javascripts" meta_type="JavaScripts Registry"> <javascript compression="safe" authenticated="True" id="hello-world.js" insert-after="*" /> </object>

<?xml version="1.0"?> <object name="portal_css"> <stylesheet title="" id="hello-world.css" media="screen" rel="stylesheet" rendering="link" cacheable="True" compression="safe" cookable="True" enabled="1" expression="" insert-before="print.css" /> </object>

Page 25: Resource registries plone conf 2014

Standard resources

• Mockup

• Bower components

accessibility autotoc backdrop eventedit filemanager formautofocus formunloadalert modal moment pickadate preventdoublesubmit querystring relateditems resourceregistry select2 sortable structure tablesorter texteditor thememapper tinymce toggle tooltip tree upload

Page 26: Resource registries plone conf 2014

Are you able to do"console dev" ?

• generate_gruntfile.py -> creates Gruntconfig.js

Page 27: Resource registries plone conf 2014

Demo

Page 28: Resource registries plone conf 2014

Migration• Resources defined as pattern and less file

• Always generate production bundle

• Move jsregistry and cssregistry to registry.xml

• On/live jquery 1.11 modifications

• Never loose hope

Page 29: Resource registries plone conf 2014

Questions ?

• Additional info at:

• https://www.nathanvangheem.com/news/plone-5-resource-registries

Page 30: Resource registries plone conf 2014

SPRINT• Static CSS/JS for mockups / CDN

• Cooking on production

• Mockup issues

• Write documentation!!

• Write tests!!