latest share customization techniques
Post on 25-Feb-2016
200 Views
Preview:
DESCRIPTION
TRANSCRIPT
Latest Share Customization Techniques
Dave Draper (@_DaveDraper)
Session Agenda
• (Very quick) overview of Share/Surf• Review of customization enhancements
• What Share customization was like before version 4.0• What was added for Share version 4.0
• An explanation of the Surf Extensibility Model• What’s New in version 4.2• What’s next for Share
Key Things To Know
• Share is built on Surf• Surf is an extension to Spring MVC
“Is Surf moving backing Alfresco?”
History• 2007
• WebScripts • 2008
• Surf• Share 3.0 and 3.1
• 2009• Share 3.2• Surf and WebScripts contributed to Spring
• 2010• Share 3.4• I joined Alfresco
• 2011• Surf converted to extensibility model (Share 4.0)
What Was Life Like Back in 2007
• No iPhone (not until June anyway)• No Android• jQuery only just released (version 1.0, Aug 2006)• Movies were still in 2D• HD-DVD was still a viable option• The global economy was still stable• Spain were still rubbish at football
RegionChrome
Anatomy of a Surf PagePage
Template-Instance
FreeMarker Template
Regions Components
Component Chrome
WebScripts
Share Customization Prior to Version 4.0
• Copy and paste to “web-extension” path• Maintenance problems
Share Customization in version 4.0
• Extensibility Model introduced into Surf• Extension Module configuration• Sub-Components• Customizations• SurfBug• Document Library specific extension points
Document Library Extension Points
• Well defined, common, fine-grained use-cases• No Surf changes• Separate development effort
Extension Modules
• Three deployment modes:• “auto” • “enable-auto-deploy-modules” • “manual”
• Evaluated once per request• Default evaluation configuration can be overridden
during manual deployment
Sub-Component extensions
• Addressed the problem of 1-1 mapping of Regions to Components
• Automatically generated from “legacy” Component configuration
• Allow default (Sub-)Components to be removed or replaced and for new Sub-Components to be added before or after
• Sub-Component evaluations allow for finer control of rendering
WebScript/Template Customizations
• Allows additions and overrides to i18n properties• Allows model created by JavaScript controller to be
manipulated• Allows <@region> and <@markup> directives in
FreeMarker templates to be replaced or removed• Allows new <@region> and <@markup> directives
to be added before or after existing directives
Please request for the <@markup>
directives that YOU need to be added to
the Share WebScripts!!!
JavaScript Controller Customizations
• Run after default controller• An opportunity to alter the model passed to
template
Localization Customizations
• Update default WebScript properties for each request
• Most specific locale “wins”
Configuration Customization
• Configuration can be added to a module using <configurations> element
• Generates a custom configuration model for each request
• Uses underlying ConfigService implementation• Available in 4.0 service packs
<extension> <modules> <module> <id>Site_Conditional_Flash</id> <evaluator type="site.module.evaluator"> <params> <sites>noflash</sites> <sitePresets>.*</sitePresets> </params> </evaluator> <configurations> <config evaluator="string-compare" condition="DocumentLibrary" replace="true"> <file-upload> <adobe-flash-enabled>false</adobe-flash-enabled> <in-memory-limit>262144000</in-memory-limit> </file-upload> </config> </configurations> </module> </modules> </extension>
Example taken from:http://blogs.alfresco.com/wp/ddraper/2012/03/05/share-configuration-extensibility/
The Surf Extensibility Model
• An in-memory buffer (a linked list of elements)• FreeMarker directives manipulate elements• A new model is opened for each FreeMarker
template• The following directives use the model:
• <@region>• <@markup> (can be nested)• <@outputCSS>• <@outputJavaScript>• <@script>• <@link>• <@relocateJavaScript>• <@standalone>
Unbound
Unbound
Open
Content
Close
<!– This is the start a template-->
<@markup id=“MARKUP_1”>
<span>Some text</span>
</@>
<!– End of a template -->
How Extensibility Model is Built Up
Adding ContentUnbound
Unbound
Open
Content
Close
<@markup id=“add”
target=“MARKUP_1”
action=“after”>
<span>Some MORE text</span>
</@>
Open
Content
Close
“MARKUP_1”
Unbound
Unbound
Open
Content
Close
Writer
ExtensibilityModelflush()
write()
Unbound
Unbound
Open
Content
Close
OutputStream flush()
The Problem:
• Only coarse grained customizations were possible
The Solution:
• Make it easier to customize client-side JavaScript
How Client-Side Widgets Were Instantiated
• Region/Component• WebScript
• Descriptor• Controller• “head” file• FreeMarker template• Localization Properties
• JavaScript resource• CSS resource
Double Pass WebScript Processing
head.get.head.ftl
head.get.html.ftl
WebScripts
body1.get.head.ftl
body1.get.html.ftl
body2.get.head.ftl
body2.get.html.ftl
Styles1.css
Functions1.js
Styles2.css
Functions2.js
${head}
Unbound
Unbound
Open
Content
Close
ExtensibilityModel
JavaScript / CSS importDeferred
Open
Close
render()
<@outputJavaScript/><@outputCSS/>
<@link/><@script/>
Old Widget Instantiation
Share WebScript Refactor
• Conversion to a common “boiler-plate” template• Client-side JavaScript widget definition moved into
JavaScript controller• All logic moved from FreeMarker template to
JavaScript controller• All JavaScript and CSS resource import statements
moved into FreeMarker template• Deprecation of *.head.ftl files
The “Boilerplate”
<@markup id=“css”> <@link href=“…” group=“…”/></@><@markup id=“js”> <@script src=“…” group=“…”/></@><@markup id=“widgets”> <@inlineScript group=“…”/> <@createWidgets group=“…”/> <@inlineScript group=“…”/></@><@markup id=“html”> <@uniqueIdDiv/> … </@></@>
Controller Model “widgets” Elements
Object attributes:• “id”• “name” (required)• “initArgs” (defaults to region id)• “useOptions” (defaults to “true”)• “options”• “useMessages” (defaults to “true”)• “assignTo”
New Widget Instantiation
Why Refactor?
• Consistency between WebScripts• Easier to instantiate custom client-side JavaScript
widgets• A step towards performance improvements
• Moving towards disabling Surf Chrome and WebScript Head processing by default
• Moving towards JavaScript and CSS resource aggregation by default
Using JavaScript Extension Mechanism
• Create custom JavaScript widget that extends Alfresco version• Use YAHOO.extend() function• Override default functions
• Extend WebScript • Customize FreeMarker template to add import for file containing
custom widget• <@markup id=“myWidgetSrc” target=“js” action=“after”>
• Customize JavaScript controller to replace widget instantiation object
• Use widgetUtils.findObject(model.widgets , “id”, <id>)• Change “name” attribute to reference new JavaScript widget
Module<module> <id>Custom DocumentList Widget</id> <customizations> <customization> <targetPackageRoot> org.alfresco.components.documentlibrary </targetPackageRoot> <sourcePackageRoot> blog.demo.customization </sourcePackageRoot> </customization> </customizations></module>
Example taken from:http://blogs.alfresco.com/wp/ddraper/2012/05/22/customizing-share-javascript-widget-instantiation-part-1/
Custom JavaScript// Declare namespace... if (typeof Blog == undefined || !Blog) { var Blog = {}; } if (!Blog.custom) { Blog.custom = {}; }
(function() { // Define constructor... Blog.custom.DocumentList = function CustomDocumentList_constructor(htmlId) { Blog.custom.DocumentList.superclass.constructor.call(this, htmlId); return this; };
// Extend default DocumentList... YAHOO.extend(Blog.custom.DocumentList, Alfresco.DocumentList, { onFilterChanged: function CustomDL_onFilterChanged(layer, args) { // Call super class method... Blog.custom.DocumentList.superclass.onFilterChanged.call(this, layer,args); // Pop-up a message... Alfresco.util.PopupManager.displayMessage({ text: "Filter Changed!" }); } }); })();Example taken from:http://blogs.alfresco.com/wp/ddraper/2012/05/22/customizing-share-javascript-widget-instantiation-part-1/
Custom FreeMarker template
<@markup id="custom-documentlist-dependencies" target="js" action="after" scope="global"> <@script src="${url.context}/res/doclib/extension/custom-documentlist.js" group="documentlibrary"/></@markup>
Example taken from:http://blogs.alfresco.com/wp/ddraper/2012/05/22/customizing-share-javascript-widget-instantiation-part-1/
Custom JavaScript controller
// Find the default DocumentList widget and replace it with the custom widget for (var i=0; i<model.widgets.length; i++) { if (model.widgets[i].id == "DocumentList") { model.widgets[i].name = "Blog.custom.DocumentList"; } }
Surf Configuration Settings
• “use-checksum-dependencies”• “aggregate-dependencies”• “calculate-webscript-dependencies”• “generate-css-data-images”
Checksum Dependencies
• Processed by the “dependency.handler” Spring bean• org.springframework.extensions.surf.DependencyHandler
• Default Spring bean definition can be overridden to change debug and production suffices or the checksum digest (defaults to MD5)
• Production suffices:• “-min”• “-minified”• “”
• Debug suffices• “”• “_src”• “-debug”
Resource Aggregation
• Currently disabled by default (Share can be run with it enabled)• Enabling may break 3rd party extensions
• Improves performance by reducing the number of HTTP requests
• Includes inline JavaScript• Removes all JavaScript from HTML source
Calculate WebScript Dependencies
• Still enabled by default• Can be disabled if you don’t want to use Rich Media AMP• Will be disabled by default in some future release
• Required for legacy extensions• Empty *.head.ftl files are still processed so that extension versions
are detected• Please try to phase out the use of *.head.ftl files !
Generate CSS Data Images
• An alternative to CSS spriting• Too consuming a task to convert Share to CSS sprites• Use of CSS sprites would most likely break 3rd party customizations
• Handles CSS @import statements• All CSS @imports must appear first in the file• Relative paths are generated when image cannot be found
• Enabled by default
Dojo Support in Surf
• Surf now includes support for Dojo applications• Programmatic implementations only• Dojo version 1.7 applications or greater
• Uses existing resource aggregation capabilities to simulate Dojo build layers
• Dynamic dependency analysis • Supports 3rd party extensions
Why Have We Done This?
• Investigating future possibilities for developing Share
• YUI 2 is no longer being developed• Simplify page development• Move from coarse-grained, tightly-coupled “flat”
widget structure to fine-grained, decoupled, nested widgets
• Improve customization/extensibility
Why Dojo?
• AMD (Asynchronous Module Definitions)• Simple widget construction• Excellent inheritance patterns• Pub/Sub model• Unit testing framework• Comprehensive & consistent widget library• Accessibility support• Backed by big companies
2012 Summary
• Configuration customization support added• Share WebScript refactoring• Repository Extensibility Container• Dynamic extension module support• Surf Maven Archetype• Dojo (1.7+) support in Surf
What Next For Share?
• It WON’T be replaced• It WILL still be based on Surf• It WILL feature new pages built on an improved
client-side framework
Key Messages and Actions
• Performance and extensibility are key objectives for Share
• Share is going to continue to move forward• Read the blogs• Use the forums
• Ask questions• Request extension points
• Raise bugs/feature requests on JIRA• Come along to the Share Customization Live!
session to see this in action
Questions?
FIN
FreeMarker Directive Factory
• Directive Factory defines the directives that are created (bean id: “directive.factory”)
• ProcessorModelHelper creates the directives (bean id: “processor.model.helper”)
• Custom directives can be written and provided to FreeMarker templates:• Override default bean definitions to reference custom beans• Override .populateTemplateModel() in ProcessorModelHelper to
add additional FreeMarker directives• Lots of interfaces and abstract classes that can be
implemented/extended• This approach is used for Alfresco Cloud service
top related