Resource Registries 
Ramon Navarro Bosch & Rob Gietema
Resource registries plone conf 2014
Ramon Navarro Bosch 
• Iskra.CAT 
• Member Plone Foundation 
• FWT member
Rob Gietema 
• Four Digits 
• Plone Foundation Member
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
Limitations 
• JS & CSS have evolved 
• Dependency management 
• Precompiling (LESS / SASS) 
• Versioning 
• Mockup
RequireJS 
<!DOCTYPE html> 
<html> 
<head> 
<script data-main="app" src="lib/require.js"></script> 
</head> 
<body> 
<h1>Hello World</h1> 
</body> 
• Include require.js </html> 
// 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']); 
• Add all your dependencies 
in Javascript 
• Async loading of files and 
modules
GRUNT 
module.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
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
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
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
Design of the Solution 
BUNDLE 
RESOURCE 
BOWER 
COMPONENT 
MOCKUP 
COMPONENT 
STANDALONE 
FILES 
DIAZO 
STATIC 
HTML REGISTRY
Bundles 
• Dependency 
• Compilation 
• Enabled 
<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> 
<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>
Resources 
• js 
• export/init 
• css 
• url 
<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> 
<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>
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>
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>
Development & Production 
<record name="plone.resources.development"> 
<field type="plone.registry.field.Bool"> 
<title>Frontend development mode</title> 
</field> 
<value>true</value> 
</record> 
• 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
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" />
Views: config.js 
requirejs.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 
});
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"', 
…}};
plone.less 
… 
@import url("@{mockup-patterns-upload}"); 
@import url("@{plone-patterns-toolbar}"); 
@import url("@{mockup-patterns-tinymce}"); 
@import "@{bowerPath}bootstrap/less/dropdowns.less"; 
…
plone.js 
require([ 
'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' 
…
TTW customization 
• Fully customizable trough the web 
• Controlpanel in Plone
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>
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
Are you able to do 
"console dev" ? 
• generate_gruntfile.py -> creates Gruntconfig.js
Demo
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
Questions ? 
• Additional info at: 
• https://www.nathanvangheem.com/news/plone-5- 
resource-registries
SPRINT 
• Static CSS/JS for mockups / CDN 
• Cooking on production 
• Mockup issues 
• Write documentation!! 
• Write tests!!

More Related Content

PDF
How containers helped a SaaS startup be developed and go live
PDF
Plone 5 and machine learning
PDF
HTTP For the Good or the Bad
PDF
Challenges when building high profile editorial sites
PDF
HTML5 JavaScript APIs
PDF
Forget the Web
PDF
2020-02-20 - HashiTalks 2020 - HashiCorp Vault configuration as code via Hash...
PDF
HTTP Caching and PHP
How containers helped a SaaS startup be developed and go live
Plone 5 and machine learning
HTTP For the Good or the Bad
Challenges when building high profile editorial sites
HTML5 JavaScript APIs
Forget the Web
2020-02-20 - HashiTalks 2020 - HashiCorp Vault configuration as code via Hash...
HTTP Caching and PHP

What's hot (20)

PPTX
cache concepts and varnish-cache
PDF
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
PDF
Php on Windows
PPTX
Drilling deeper with Veil's PowerTools
PDF
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
PDF
실시간 서비스 플랫폼 개발 사례
PDF
Nuts and Bolts of WebSocket Devoxx 2014
PDF
Automating complex infrastructures with Puppet
KEY
From Dev to DevOps - FOSDEM 2012
KEY
From Dev to DevOps - ApacheCON NA 2011
KEY
Puppet for Java developers - JavaZone NO 2012
PDF
Common Pitfalls for your Drupal Site, and How to Avoid Them
PDF
Amazon EC2 Container Service in Action
KEY
From Dev to DevOps - Apache Barcamp Spain 2011
PDF
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
PPTX
Kubernetes #4 volume &amp; stateful set
PDF
ApacheConNA 2015: What's new in Apache httpd 2.4
PDF
232 deview2013 oss를활용한분산아키텍처구현
PDF
Unity Makes Strength
PDF
High Performance Django
cache concepts and varnish-cache
DEVIEW - 오픈소스를 활용한 분산아키텍처 구현기술
Php on Windows
Drilling deeper with Veil's PowerTools
Deploying VMware vCloud Hybrid Service with Puppet - PuppetConf 2013
실시간 서비스 플랫폼 개발 사례
Nuts and Bolts of WebSocket Devoxx 2014
Automating complex infrastructures with Puppet
From Dev to DevOps - FOSDEM 2012
From Dev to DevOps - ApacheCON NA 2011
Puppet for Java developers - JavaZone NO 2012
Common Pitfalls for your Drupal Site, and How to Avoid Them
Amazon EC2 Container Service in Action
From Dev to DevOps - Apache Barcamp Spain 2011
How to Develop Puppet Modules: From Source to the Forge With Zero Clicks
Kubernetes #4 volume &amp; stateful set
ApacheConNA 2015: What's new in Apache httpd 2.4
232 deview2013 oss를활용한분산아키텍처구현
Unity Makes Strength
High Performance Django
Ad

Viewers also liked (20)

PDF
The Mountaineers: Scaling the Heights with Plone
PDF
PloneConf 2014 CDN terada
PDF
High-performance high-availability Plone
PPTX
Quality Manager Position
PPTX
guitars
PDF
Managing a shared_mysql_farm_phpday2011
PPT
Love Again, Or Never Love
PPT
Tutoria Màster
PPT
Gel Electrophoresis
PPT
KEY
Putfoot Rally
PPT
Mohenjo Daro
PPT
11.3 Research Report
KEY
PDF
Hybrid Cloud PHPUK2012
PDF
plone.app.multilingual
KEY
Anurag&Rupali
PPT
PPT
World Cultures. 114
The Mountaineers: Scaling the Heights with Plone
PloneConf 2014 CDN terada
High-performance high-availability Plone
Quality Manager Position
guitars
Managing a shared_mysql_farm_phpday2011
Love Again, Or Never Love
Tutoria Màster
Gel Electrophoresis
Putfoot Rally
Mohenjo Daro
11.3 Research Report
Hybrid Cloud PHPUK2012
plone.app.multilingual
Anurag&Rupali
World Cultures. 114
Ad

Similar to Resource registries plone conf 2014 (20)

PDF
Resource Registries: Plone Conference 2014
PDF
Javascript is your (Auto)mate
PDF
Building instant features with advanced Plone themes
PDF
Web development - technologies and tools
PDF
Quest for the Perfect Workflow for McrFRED
PDF
Npm scripts
PPTX
Modern Development Tools
PDF
What makes me "Grunt"?
PDF
JLPDevs - Optimization Tooling for Modern Web App Development
PDF
Grunt & Front-end Workflow
PDF
Plone 5 theming
PDF
Plone 5 theming
PDF
Hitchhiker's guide to the front end development
PDF
Let Grunt do the work, focus on the fun!
PDF
Automating Front-End Workflow
PDF
Grunt All Day
PDF
Let Grunt do the work, focus on the fun! [Open Web Camp 2013]
ODP
Plone Intranet under the hood
PDF
Get Grulping with JavaScript Task Runners (Matt Gifford)
PDF
Introducing RaveJS: Spring Boot concepts for JavaScript applications
Resource Registries: Plone Conference 2014
Javascript is your (Auto)mate
Building instant features with advanced Plone themes
Web development - technologies and tools
Quest for the Perfect Workflow for McrFRED
Npm scripts
Modern Development Tools
What makes me "Grunt"?
JLPDevs - Optimization Tooling for Modern Web App Development
Grunt & Front-end Workflow
Plone 5 theming
Plone 5 theming
Hitchhiker's guide to the front end development
Let Grunt do the work, focus on the fun!
Automating Front-End Workflow
Grunt All Day
Let Grunt do the work, focus on the fun! [Open Web Camp 2013]
Plone Intranet under the hood
Get Grulping with JavaScript Task Runners (Matt Gifford)
Introducing RaveJS: Spring Boot concepts for JavaScript applications

More from Ramon Navarro (9)

PDF
Guillotina
PDF
Pipelines for model deployment
PDF
Plone server
PDF
CI on large open source software : Plone & Plone 5 is here!
PDF
Pyramid
PDF
Multilingual sites in plone
PDF
Cafè amb web
PDF
Presentacio meetup Python BCN
PDF
WPD Barcelona 2008 Què és Plone ?
Guillotina
Pipelines for model deployment
Plone server
CI on large open source software : Plone & Plone 5 is here!
Pyramid
Multilingual sites in plone
Cafè amb web
Presentacio meetup Python BCN
WPD Barcelona 2008 Què és Plone ?

Recently uploaded (20)

PPTX
future_of_ai_comprehensive_20250822032121.pptx
PDF
“A New Era of 3D Sensing: Transforming Industries and Creating Opportunities,...
PPT
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
PDF
Data Virtualization in Action: Scaling APIs and Apps with FME
PDF
Auditboard EB SOX Playbook 2023 edition.
PDF
Lung cancer patients survival prediction using outlier detection and optimize...
PDF
giants, standing on the shoulders of - by Daniel Stenberg
PDF
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
PDF
Rapid Prototyping: A lecture on prototyping techniques for interface design
PDF
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
PDF
Enhancing plagiarism detection using data pre-processing and machine learning...
PDF
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
PDF
sbt 2.0: go big (Scala Days 2025 edition)
PDF
Comparative analysis of machine learning models for fake news detection in so...
PDF
The influence of sentiment analysis in enhancing early warning system model f...
PPTX
Microsoft User Copilot Training Slide Deck
PDF
Improvisation in detection of pomegranate leaf disease using transfer learni...
PPTX
Training Program for knowledge in solar cell and solar industry
PDF
The-2025-Engineering-Revolution-AI-Quality-and-DevOps-Convergence.pdf
PDF
NewMind AI Weekly Chronicles – August ’25 Week IV
future_of_ai_comprehensive_20250822032121.pptx
“A New Era of 3D Sensing: Transforming Industries and Creating Opportunities,...
Galois Field Theory of Risk: A Perspective, Protocol, and Mathematical Backgr...
Data Virtualization in Action: Scaling APIs and Apps with FME
Auditboard EB SOX Playbook 2023 edition.
Lung cancer patients survival prediction using outlier detection and optimize...
giants, standing on the shoulders of - by Daniel Stenberg
Produktkatalog für HOBO Datenlogger, Wetterstationen, Sensoren, Software und ...
Rapid Prototyping: A lecture on prototyping techniques for interface design
5-Ways-AI-is-Revolutionizing-Telecom-Quality-Engineering.pdf
Enhancing plagiarism detection using data pre-processing and machine learning...
Dell Pro Micro: Speed customer interactions, patient processing, and learning...
sbt 2.0: go big (Scala Days 2025 edition)
Comparative analysis of machine learning models for fake news detection in so...
The influence of sentiment analysis in enhancing early warning system model f...
Microsoft User Copilot Training Slide Deck
Improvisation in detection of pomegranate leaf disease using transfer learni...
Training Program for knowledge in solar cell and solar industry
The-2025-Engineering-Revolution-AI-Quality-and-DevOps-Convergence.pdf
NewMind AI Weekly Chronicles – August ’25 Week IV

Resource registries plone conf 2014

  • 1. Resource Registries Ramon Navarro Bosch & Rob Gietema
  • 3. Ramon Navarro Bosch • Iskra.CAT • Member Plone Foundation • FWT member
  • 4. Rob Gietema • Four Digits • Plone Foundation Member
  • 5. 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
  • 6. Limitations • JS & CSS have evolved • Dependency management • Precompiling (LESS / SASS) • Versioning • Mockup
  • 7. RequireJS <!DOCTYPE html> <html> <head> <script data-main="app" src="lib/require.js"></script> </head> <body> <h1>Hello World</h1> </body> • Include require.js </html> // 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']); • Add all your dependencies in Javascript • Async loading of files and modules
  • 8. GRUNT module.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
  • 9. 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
  • 10. 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
  • 11. 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
  • 12. Design of the Solution BUNDLE RESOURCE BOWER COMPONENT MOCKUP COMPONENT STANDALONE FILES DIAZO STATIC HTML REGISTRY
  • 13. Bundles • Dependency • Compilation • Enabled <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> <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>
  • 14. Resources • js • export/init • css • url <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> <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>
  • 15. 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>
  • 16. 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>
  • 17. Development & Production <record name="plone.resources.development"> <field type="plone.registry.field.Bool"> <title>Frontend development mode</title> </field> <value>true</value> </record> • 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
  • 18. 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" />
  • 19. Views: config.js requirejs.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 });
  • 20. 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"', …}};
  • 21. plone.less … @import url("@{mockup-patterns-upload}"); @import url("@{plone-patterns-toolbar}"); @import url("@{mockup-patterns-tinymce}"); @import "@{bowerPath}bootstrap/less/dropdowns.less"; …
  • 22. plone.js require([ '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' …
  • 23. TTW customization • Fully customizable trough the web • Controlpanel in Plone
  • 24. 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>
  • 25. 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
  • 26. Are you able to do "console dev" ? • generate_gruntfile.py -> creates Gruntconfig.js
  • 27. Demo
  • 28. 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
  • 29. Questions ? • Additional info at: • https://www.nathanvangheem.com/news/plone-5- resource-registries
  • 30. SPRINT • Static CSS/JS for mockups / CDN • Cooking on production • Mockup issues • Write documentation!! • Write tests!!