SlideShare a Scribd company logo
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

What's hot (20)

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

Viewers also liked (20)

PDF
The Mountaineers: Scaling the Heights with Plone
Jazkarta, Inc.
 
PDF
PloneConf 2014 CDN terada
Manabu Terada
 
PDF
High-performance high-availability Plone
Guido Stevens
 
PPTX
Quality Manager Position
Marni Sampair
 
PPTX
guitars
Mrs. McCabe
 
PDF
Managing a shared_mysql_farm_phpday2011
Combell NV
 
PPT
Love Again, Or Never Love
Mrs. McCabe
 
PPT
Tutoria Màster
Nuria Alart
 
PPT
Gel Electrophoresis
Ignatius Chen
 
PPT
story
Mrs. McCabe
 
KEY
Putfoot Rally
Mark Smith
 
PPT
Mohenjo Daro
Mrs. McCabe
 
PPT
11.3 Research Report
chrissienehrenberg
 
KEY
Poll
Mrs. McCabe
 
PDF
Hybrid Cloud PHPUK2012
Combell NV
 
PDF
plone.app.multilingual
Ramon Navarro
 
KEY
Anurag&Rupali
Mrs. McCabe
 
PPT
Food
Mrs. McCabe
 
PPT
World Cultures. 114
Mrs. McCabe
 
The Mountaineers: Scaling the Heights with Plone
Jazkarta, Inc.
 
PloneConf 2014 CDN terada
Manabu Terada
 
High-performance high-availability Plone
Guido Stevens
 
Quality Manager Position
Marni Sampair
 
guitars
Mrs. McCabe
 
Managing a shared_mysql_farm_phpday2011
Combell NV
 
Love Again, Or Never Love
Mrs. McCabe
 
Tutoria Màster
Nuria Alart
 
Gel Electrophoresis
Ignatius Chen
 
Putfoot Rally
Mark Smith
 
Mohenjo Daro
Mrs. McCabe
 
11.3 Research Report
chrissienehrenberg
 
Hybrid Cloud PHPUK2012
Combell NV
 
plone.app.multilingual
Ramon Navarro
 
Anurag&Rupali
Mrs. McCabe
 
World Cultures. 114
Mrs. McCabe
 
Ad

Similar to Resource registries plone conf 2014 (20)

PDF
Resource Registries: Plone Conference 2014
Rob Gietema
 
KEY
Plone Interactivity
Eric Steele
 
PPTX
BITM3730Week7.pptx
MattMarino13
 
PDF
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
KEY
[Coscup 2012] JavascriptMVC
Alive Kuo
 
PDF
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen
 
PDF
Rich Portlet Development in uPortal
Jennifer Bourey
 
PPTX
Progressive downloads and rendering (Stoyan Stefanov)
Ontico
 
PDF
20190118_NetadashiMeetup#8_React2019
Makoto Mori
 
PDF
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
PPTX
JavaScript performance patterns
Stoyan Stefanov
 
PDF
The new static resources framework
marcplmer
 
PDF
Progressive Downloads and Rendering
Stoyan Stefanov
 
KEY
前端概述
Ethan Zhang
 
PDF
Responsive WordPress workflow
James Bundey
 
PPTX
Simple blog wall creation on Java
Max Titov
 
PDF
E2 appspresso hands on lab
NAVER D2
 
PDF
E3 appspresso hands on lab
NAVER D2
 
PDF
HTML 5 - Overview
Marcelio Leal
 
PDF
HTML5 (and friends) - History, overview and current status - jsDay Verona 11....
Patrick Lauke
 
Resource Registries: Plone Conference 2014
Rob Gietema
 
Plone Interactivity
Eric Steele
 
BITM3730Week7.pptx
MattMarino13
 
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
[Coscup 2012] JavascriptMVC
Alive Kuo
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen
 
Rich Portlet Development in uPortal
Jennifer Bourey
 
Progressive downloads and rendering (Stoyan Stefanov)
Ontico
 
20190118_NetadashiMeetup#8_React2019
Makoto Mori
 
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
JavaScript performance patterns
Stoyan Stefanov
 
The new static resources framework
marcplmer
 
Progressive Downloads and Rendering
Stoyan Stefanov
 
前端概述
Ethan Zhang
 
Responsive WordPress workflow
James Bundey
 
Simple blog wall creation on Java
Max Titov
 
E2 appspresso hands on lab
NAVER D2
 
E3 appspresso hands on lab
NAVER D2
 
HTML 5 - Overview
Marcelio Leal
 
HTML5 (and friends) - History, overview and current status - jsDay Verona 11....
Patrick Lauke
 
Ad

More from Ramon Navarro (9)

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

Recently uploaded (20)

PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PDF
introduction to computer hardware and sofeware
chauhanshraddha2007
 
PDF
Brief History of Internet - Early Days of Internet
sutharharshit158
 
PPTX
Applied-Statistics-Mastering-Data-Driven-Decisions.pptx
parmaryashparmaryash
 
PDF
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
PDF
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
PDF
Researching The Best Chat SDK Providers in 2025
Ray Fields
 
PDF
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
PDF
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
PPTX
The Future of AI & Machine Learning.pptx
pritsen4700
 
PDF
State-Dependent Conformal Perception Bounds for Neuro-Symbolic Verification
Ivan Ruchkin
 
PPTX
AVL ( audio, visuals or led ), technology.
Rajeshwri Panchal
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
RAT Builders - How to Catch Them All [DeepSec 2024]
malmoeb
 
PDF
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
PDF
Per Axbom: The spectacular lies of maps
Nexer Digital
 
PPTX
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
PPTX
Agile Chennai 18-19 July 2025 | Emerging patterns in Agentic AI by Bharani Su...
AgileNetwork
 
PDF
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
PDF
OFFOFFBOX™ – A New Era for African Film | Startup Presentation
ambaicciwalkerbrian
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
introduction to computer hardware and sofeware
chauhanshraddha2007
 
Brief History of Internet - Early Days of Internet
sutharharshit158
 
Applied-Statistics-Mastering-Data-Driven-Decisions.pptx
parmaryashparmaryash
 
How ETL Control Logic Keeps Your Pipelines Safe and Reliable.pdf
Stryv Solutions Pvt. Ltd.
 
Make GenAI investments go further with the Dell AI Factory
Principled Technologies
 
Researching The Best Chat SDK Providers in 2025
Ray Fields
 
NewMind AI Weekly Chronicles – July’25, Week III
NewMind AI
 
The Future of Mobile Is Context-Aware—Are You Ready?
iProgrammer Solutions Private Limited
 
The Future of AI & Machine Learning.pptx
pritsen4700
 
State-Dependent Conformal Perception Bounds for Neuro-Symbolic Verification
Ivan Ruchkin
 
AVL ( audio, visuals or led ), technology.
Rajeshwri Panchal
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
RAT Builders - How to Catch Them All [DeepSec 2024]
malmoeb
 
Trying to figure out MCP by actually building an app from scratch with open s...
Julien SIMON
 
Per Axbom: The spectacular lies of maps
Nexer Digital
 
AI in Daily Life: How Artificial Intelligence Helps Us Every Day
vanshrpatil7
 
Agile Chennai 18-19 July 2025 | Emerging patterns in Agentic AI by Bharani Su...
AgileNetwork
 
Presentation about Hardware and Software in Computer
snehamodhawadiya
 
OFFOFFBOX™ – A New Era for African Film | Startup Presentation
ambaicciwalkerbrian
 

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!!