SlideShare a Scribd company logo
Resource Registries 
Ramon Navarro Bosch & Rob Gietema
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

Beyond PrettyFaces - Einführung in Rewrite
Beyond PrettyFaces - Einführung in RewriteBeyond PrettyFaces - Einführung in Rewrite
Beyond PrettyFaces - Einführung in Rewrite
Christian Kaltepoth
 
Web Components
Web ComponentsWeb Components
Web Components
Nikolaus Graf
 
Web Components and Modular CSS
Web Components and Modular CSSWeb Components and Modular CSS
Web Components and Modular CSS
Andrew Rota
 
Hdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed SolutionsHdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed Solutions
woutervugt
 
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface
 
Preparing your web services for Android and your Android app for web services...
Preparing your web services for Android and your Android app for web services...Preparing your web services for Android and your Android app for web services...
Preparing your web services for Android and your Android app for web services...
Droidcon Eastern Europe
 
AJAX - An introduction
AJAX - An introductionAJAX - An introduction
AJAX - An introduction
Eleonora Ciceri
 
Introduction about-ajax-framework
Introduction about-ajax-frameworkIntroduction about-ajax-framework
Introduction about-ajax-framework
Sakthi Bro
 
Angularjs & REST
Angularjs & RESTAngularjs & REST
Angularjs & REST
Corley S.r.l.
 
Zk doc1
Zk doc1Zk doc1
Zk doc1
Rupalli Das
 
HTML5 - An introduction
HTML5 - An introductionHTML5 - An introduction
HTML5 - An introduction
Eleonora Ciceri
 
Even faster django
Even faster djangoEven faster django
Even faster django
Gage Tseng
 
Node.js introduction
Node.js introductionNode.js introduction
Node.js introduction
Parth Joshi
 
Effective TDD - Less is more
Effective TDD - Less is moreEffective TDD - Less is more
Effective TDD - Less is more
Ben Lau
 
WebApp #3 : API
WebApp #3 : APIWebApp #3 : API
WebApp #3 : API
Jean Michel
 
WebApp / SPA @ AllFacebook Developer Conference
WebApp / SPA @ AllFacebook Developer ConferenceWebApp / SPA @ AllFacebook Developer Conference
WebApp / SPA @ AllFacebook Developer Conference
AllFacebook.de
 
Go Fullstack: JSF for Public Sites (CONFESS 2012)
Go Fullstack: JSF for Public Sites (CONFESS 2012)Go Fullstack: JSF for Public Sites (CONFESS 2012)
Go Fullstack: JSF for Public Sites (CONFESS 2012)
Michael Kurz
 
Mule esb
Mule esbMule esb
Mule esb
Khan625
 
003. ReactJS basic
003. ReactJS basic003. ReactJS basic
003. ReactJS basic
Binh Quan Duc
 
AJAX
AJAXAJAX

What's hot (20)

Beyond PrettyFaces - Einführung in Rewrite
Beyond PrettyFaces - Einführung in RewriteBeyond PrettyFaces - Einführung in Rewrite
Beyond PrettyFaces - Einführung in Rewrite
 
Web Components
Web ComponentsWeb Components
Web Components
 
Web Components and Modular CSS
Web Components and Modular CSSWeb Components and Modular CSS
Web Components and Modular CSS
 
Hdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed SolutionsHdv309 - Real World Sandboxed Solutions
Hdv309 - Real World Sandboxed Solutions
 
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
Uniface Lectures Webinar - Building Responsive Applications with Uniface: Dev...
 
Preparing your web services for Android and your Android app for web services...
Preparing your web services for Android and your Android app for web services...Preparing your web services for Android and your Android app for web services...
Preparing your web services for Android and your Android app for web services...
 
AJAX - An introduction
AJAX - An introductionAJAX - An introduction
AJAX - An introduction
 
Introduction about-ajax-framework
Introduction about-ajax-frameworkIntroduction about-ajax-framework
Introduction about-ajax-framework
 
Angularjs & REST
Angularjs & RESTAngularjs & REST
Angularjs & REST
 
Zk doc1
Zk doc1Zk doc1
Zk doc1
 
HTML5 - An introduction
HTML5 - An introductionHTML5 - An introduction
HTML5 - An introduction
 
Even faster django
Even faster djangoEven faster django
Even faster django
 
Node.js introduction
Node.js introductionNode.js introduction
Node.js introduction
 
Effective TDD - Less is more
Effective TDD - Less is moreEffective TDD - Less is more
Effective TDD - Less is more
 
WebApp #3 : API
WebApp #3 : APIWebApp #3 : API
WebApp #3 : API
 
WebApp / SPA @ AllFacebook Developer Conference
WebApp / SPA @ AllFacebook Developer ConferenceWebApp / SPA @ AllFacebook Developer Conference
WebApp / SPA @ AllFacebook Developer Conference
 
Go Fullstack: JSF for Public Sites (CONFESS 2012)
Go Fullstack: JSF for Public Sites (CONFESS 2012)Go Fullstack: JSF for Public Sites (CONFESS 2012)
Go Fullstack: JSF for Public Sites (CONFESS 2012)
 
Mule esb
Mule esbMule esb
Mule esb
 
003. ReactJS basic
003. ReactJS basic003. ReactJS basic
003. ReactJS basic
 
AJAX
AJAXAJAX
AJAX
 

Similar to Resource Registries: Plone Conference 2014

Resource registries plone conf 2014
Resource registries plone conf 2014Resource registries plone conf 2014
Resource registries plone conf 2014
Ramon Navarro
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
Eric Steele
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
Rob Bontekoe
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
Jennifer Bourey
 
Progressive downloads and rendering (Stoyan Stefanov)
Progressive downloads and rendering (Stoyan Stefanov)Progressive downloads and rendering (Stoyan Stefanov)
Progressive downloads and rendering (Stoyan Stefanov)
Ontico
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
Alive Kuo
 
前端概述
前端概述前端概述
前端概述
Ethan Zhang
 
BITM3730Week7.pptx
BITM3730Week7.pptxBITM3730Week7.pptx
BITM3730Week7.pptx
MattMarino13
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
Doris Chen
 
JavaScript performance patterns
JavaScript performance patternsJavaScript performance patterns
JavaScript performance patterns
Stoyan Stefanov
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on Java
Max Titov
 
Responsive WordPress workflow
Responsive WordPress workflowResponsive WordPress workflow
Responsive WordPress workflow
James Bundey
 
Progressive Downloads and Rendering
Progressive Downloads and RenderingProgressive Downloads and Rendering
Progressive Downloads and Rendering
Stoyan Stefanov
 
20190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React201920190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React2019
Makoto Mori
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
Eric Palakovich Carr
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on lab
NAVER D2
 
E3 appspresso hands on lab
E3 appspresso hands on labE3 appspresso hands on lab
E3 appspresso hands on lab
NAVER D2
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
crokitta
 
The new static resources framework
The new static resources frameworkThe new static resources framework
The new static resources framework
marcplmer
 
HTML 5 - Overview
HTML 5 - OverviewHTML 5 - Overview
HTML 5 - Overview
Marcelio Leal
 

Similar to Resource Registries: Plone Conference 2014 (20)

Resource registries plone conf 2014
Resource registries plone conf 2014Resource registries plone conf 2014
Resource registries plone conf 2014
 
Plone Interactivity
Plone InteractivityPlone Interactivity
Plone Interactivity
 
Building iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" DominoBuilding iPhone Web Apps using "classic" Domino
Building iPhone Web Apps using "classic" Domino
 
Rich Portlet Development in uPortal
Rich Portlet Development in uPortalRich Portlet Development in uPortal
Rich Portlet Development in uPortal
 
Progressive downloads and rendering (Stoyan Stefanov)
Progressive downloads and rendering (Stoyan Stefanov)Progressive downloads and rendering (Stoyan Stefanov)
Progressive downloads and rendering (Stoyan Stefanov)
 
[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC[Coscup 2012] JavascriptMVC
[Coscup 2012] JavascriptMVC
 
前端概述
前端概述前端概述
前端概述
 
BITM3730Week7.pptx
BITM3730Week7.pptxBITM3730Week7.pptx
BITM3730Week7.pptx
 
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
jQuery Makes Writing JavaScript Fun Again (for HTML5 User Group)
 
JavaScript performance patterns
JavaScript performance patternsJavaScript performance patterns
JavaScript performance patterns
 
Simple blog wall creation on Java
Simple blog wall creation on JavaSimple blog wall creation on Java
Simple blog wall creation on Java
 
Responsive WordPress workflow
Responsive WordPress workflowResponsive WordPress workflow
Responsive WordPress workflow
 
Progressive Downloads and Rendering
Progressive Downloads and RenderingProgressive Downloads and Rendering
Progressive Downloads and Rendering
 
20190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React201920190118_NetadashiMeetup#8_React2019
20190118_NetadashiMeetup#8_React2019
 
Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!Django Rest Framework and React and Redux, Oh My!
Django Rest Framework and React and Redux, Oh My!
 
E2 appspresso hands on lab
E2 appspresso hands on labE2 appspresso hands on lab
E2 appspresso hands on lab
 
E3 appspresso hands on lab
E3 appspresso hands on labE3 appspresso hands on lab
E3 appspresso hands on lab
 
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
Oracle Application Express & jQuery Mobile - OGh Apex Dag 2012
 
The new static resources framework
The new static resources frameworkThe new static resources framework
The new static resources framework
 
HTML 5 - Overview
HTML 5 - OverviewHTML 5 - Overview
HTML 5 - Overview
 

More from Rob Gietema

Van klimhal naar Big Wall: Bergsportdag 2024
Van klimhal naar Big Wall: Bergsportdag 2024Van klimhal naar Big Wall: Bergsportdag 2024
Van klimhal naar Big Wall: Bergsportdag 2024
Rob Gietema
 
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
Rob Gietema
 
How to Build a Site Using Nick
How to Build a Site Using NickHow to Build a Site Using Nick
How to Build a Site Using Nick
Rob Gietema
 
Nick: A Nearly Headless CMS
Nick: A Nearly Headless CMSNick: A Nearly Headless CMS
Nick: A Nearly Headless CMS
Rob Gietema
 
Van Klimhal naar Big Wall
Van Klimhal naar Big WallVan Klimhal naar Big Wall
Van Klimhal naar Big Wall
Rob Gietema
 
Van 0 naar 6000+
Van 0 naar 6000+Van 0 naar 6000+
Van 0 naar 6000+
Rob Gietema
 
How to create your own Volto site!
How to create your own Volto site!How to create your own Volto site!
How to create your own Volto site!
Rob Gietema
 
Volto Extensibility Story: Plone Conference 2018
Volto Extensibility Story: Plone Conference 2018Volto Extensibility Story: Plone Conference 2018
Volto Extensibility Story: Plone Conference 2018
Rob Gietema
 
Volto: Plone Conference 2018
Volto: Plone Conference 2018Volto: Plone Conference 2018
Volto: Plone Conference 2018
Rob Gietema
 
React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
Rob Gietema
 
React Native: React Meetup 3
React Native: React Meetup 3React Native: React Meetup 3
React Native: React Meetup 3
Rob Gietema
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXL
Rob Gietema
 
Four o Four: World Plone Day 2014
Four o Four: World Plone Day 2014Four o Four: World Plone Day 2014
Four o Four: World Plone Day 2014
Rob Gietema
 
Hackathon: Silicon Alley Lightning Talks
Hackathon: Silicon Alley Lightning TalksHackathon: Silicon Alley Lightning Talks
Hackathon: Silicon Alley Lightning Talks
Rob Gietema
 
Arnhem Sprint 2013: Plone Conference 2013
Arnhem Sprint 2013: Plone Conference 2013Arnhem Sprint 2013: Plone Conference 2013
Arnhem Sprint 2013: Plone Conference 2013
Rob Gietema
 
Plone 5: Nederlandse Plone Gebruikersdag 2014
Plone 5: Nederlandse Plone Gebruikersdag 2014Plone 5: Nederlandse Plone Gebruikersdag 2014
Plone 5: Nederlandse Plone Gebruikersdag 2014
Rob Gietema
 
Projectgroep Millennium GroenLinks Arnhem
Projectgroep Millennium GroenLinks ArnhemProjectgroep Millennium GroenLinks Arnhem
Projectgroep Millennium GroenLinks ArnhemRob Gietema
 
Deco UI: Plone Conference 2010
Deco UI: Plone Conference 2010Deco UI: Plone Conference 2010
Deco UI: Plone Conference 2010
Rob Gietema
 
Deco UI: DZUG Tagung 2010
Deco UI: DZUG Tagung 2010Deco UI: DZUG Tagung 2010
Deco UI: DZUG Tagung 2010
Rob Gietema
 
Deco UI: Nederlandse Plone Gebruikesdag 2010
Deco UI: Nederlandse Plone Gebruikesdag 2010Deco UI: Nederlandse Plone Gebruikesdag 2010
Deco UI: Nederlandse Plone Gebruikesdag 2010
Rob Gietema
 

More from Rob Gietema (20)

Van klimhal naar Big Wall: Bergsportdag 2024
Van klimhal naar Big Wall: Bergsportdag 2024Van klimhal naar Big Wall: Bergsportdag 2024
Van klimhal naar Big Wall: Bergsportdag 2024
 
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
Alpiene Cursussen van Bergsportreizen: Bergsportdag 2024
 
How to Build a Site Using Nick
How to Build a Site Using NickHow to Build a Site Using Nick
How to Build a Site Using Nick
 
Nick: A Nearly Headless CMS
Nick: A Nearly Headless CMSNick: A Nearly Headless CMS
Nick: A Nearly Headless CMS
 
Van Klimhal naar Big Wall
Van Klimhal naar Big WallVan Klimhal naar Big Wall
Van Klimhal naar Big Wall
 
Van 0 naar 6000+
Van 0 naar 6000+Van 0 naar 6000+
Van 0 naar 6000+
 
How to create your own Volto site!
How to create your own Volto site!How to create your own Volto site!
How to create your own Volto site!
 
Volto Extensibility Story: Plone Conference 2018
Volto Extensibility Story: Plone Conference 2018Volto Extensibility Story: Plone Conference 2018
Volto Extensibility Story: Plone Conference 2018
 
Volto: Plone Conference 2018
Volto: Plone Conference 2018Volto: Plone Conference 2018
Volto: Plone Conference 2018
 
React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15React Native: JS MVC Meetup #15
React Native: JS MVC Meetup #15
 
React Native: React Meetup 3
React Native: React Meetup 3React Native: React Meetup 3
React Native: React Meetup 3
 
React Router: React Meetup XXL
React Router: React Meetup XXLReact Router: React Meetup XXL
React Router: React Meetup XXL
 
Four o Four: World Plone Day 2014
Four o Four: World Plone Day 2014Four o Four: World Plone Day 2014
Four o Four: World Plone Day 2014
 
Hackathon: Silicon Alley Lightning Talks
Hackathon: Silicon Alley Lightning TalksHackathon: Silicon Alley Lightning Talks
Hackathon: Silicon Alley Lightning Talks
 
Arnhem Sprint 2013: Plone Conference 2013
Arnhem Sprint 2013: Plone Conference 2013Arnhem Sprint 2013: Plone Conference 2013
Arnhem Sprint 2013: Plone Conference 2013
 
Plone 5: Nederlandse Plone Gebruikersdag 2014
Plone 5: Nederlandse Plone Gebruikersdag 2014Plone 5: Nederlandse Plone Gebruikersdag 2014
Plone 5: Nederlandse Plone Gebruikersdag 2014
 
Projectgroep Millennium GroenLinks Arnhem
Projectgroep Millennium GroenLinks ArnhemProjectgroep Millennium GroenLinks Arnhem
Projectgroep Millennium GroenLinks Arnhem
 
Deco UI: Plone Conference 2010
Deco UI: Plone Conference 2010Deco UI: Plone Conference 2010
Deco UI: Plone Conference 2010
 
Deco UI: DZUG Tagung 2010
Deco UI: DZUG Tagung 2010Deco UI: DZUG Tagung 2010
Deco UI: DZUG Tagung 2010
 
Deco UI: Nederlandse Plone Gebruikesdag 2010
Deco UI: Nederlandse Plone Gebruikesdag 2010Deco UI: Nederlandse Plone Gebruikesdag 2010
Deco UI: Nederlandse Plone Gebruikesdag 2010
 

Recently uploaded

Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
davidjhones387
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
uehowe
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
uehowe
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
vmemo1
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
Toptal Tech
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
cuobya
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
zyfovom
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
AanSulistiyo
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
Trish Parr
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
ysasp1
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
cuobya
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
Paul Walk
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
bseovas
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
bseovas
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
ukwwuq
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
fovkoyb
 
Understanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdfUnderstanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdf
SEO Article Boost
 
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdfMeet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Florence Consulting
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
xjq03c34
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
Danica Gill
 

Recently uploaded (20)

Discover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to IndiaDiscover the benefits of outsourcing SEO to India
Discover the benefits of outsourcing SEO to India
 
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
办理毕业证(UPenn毕业证)宾夕法尼亚大学毕业证成绩单快速办理
 
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
办理毕业证(NYU毕业证)纽约大学毕业证成绩单官方原版办理
 
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
重新申请毕业证书(RMIT毕业证)皇家墨尔本理工大学毕业证成绩单精仿办理
 
Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!Ready to Unlock the Power of Blockchain!
Ready to Unlock the Power of Blockchain!
 
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
制作毕业证书(ANU毕业证)莫纳什大学毕业证成绩单官方原版办理
 
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
学位认证网(DU毕业证)迪肯大学毕业证成绩单一比一原版制作
 
Azure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdfAzure EA Sponsorship - Customer Guide.pdf
Azure EA Sponsorship - Customer Guide.pdf
 
Search Result Showing My Post is Now Buried
Search Result Showing My Post is Now BuriedSearch Result Showing My Post is Now Buried
Search Result Showing My Post is Now Buried
 
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
成绩单ps(UST毕业证)圣托马斯大学毕业证成绩单快速办理
 
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
假文凭国外(Adelaide毕业证)澳大利亚国立大学毕业证成绩单办理
 
Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?Should Repositories Participate in the Fediverse?
Should Repositories Participate in the Fediverse?
 
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
不能毕业如何获得(USYD毕业证)悉尼大学毕业证成绩单一比一原版制作
 
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
留学学历(UoA毕业证)奥克兰大学毕业证成绩单官方原版办理
 
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
制作原版1:1(Monash毕业证)莫纳什大学毕业证成绩单办理假
 
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
存档可查的(USC毕业证)南加利福尼亚大学毕业证成绩单制做办理
 
Understanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdfUnderstanding User Behavior with Google Analytics.pdf
Understanding User Behavior with Google Analytics.pdf
 
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdfMeet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
Meet up Milano 14 _ Axpo Italia_ Migration from Mule3 (On-prem) to.pdf
 
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
办理新西兰奥克兰大学毕业证学位证书范本原版一模一样
 
7 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 20247 Best Cloud Hosting Services to Try Out in 2024
7 Best Cloud Hosting Services to Try Out in 2024
 

Resource Registries: Plone Conference 2014

  • 1. Resource Registries Ramon Navarro Bosch & Rob Gietema
  • 2.
  • 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!!