Más contenido relacionado La actualidad más candente (20) Similar a Resource Registries: Plone Conference 2014 (20) Resource Registries: Plone Conference 20145. 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'
…
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
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!!