View
10.912
Download
0
Category
Preview:
DESCRIPTION
Having looked at basic theming, creating dashlets and Document Library customization, this session will dig deeper into Share extensions. Topics will include: overriding components, changing page layouts, adding new pages and advanced techniques with dashlets. It is assumed you have a basic understanding of Surf concepts as well as a working knowledge of JavaScript and Freemarker. Familiarity with YUI 2.x and CSS will aid understanding during this session.
Citation preview
1
More Ways of Customizing Alfresco Share
Erik WinlöfUI Team, Alfresco
twitter: @erikwinlof
2
What we’ll cover• Development tips, Customization concepts & Best practice• Use case: Acme Enterprises™• Future enhancements• (JavaScript tips)
3
A note about development
${TOMCAT_HOME}/shared/classes/alfresco/web-extension/share-config-custom.xml
• <client-debug> - un-minified javascript• <client-debug-autologging> - browser logging• <mode>development</mode> - fewer restarts & refreshes• Separate Share server - quicker restarts
http://blogs.alfresco.com/wp/kevinr/2010/04/07/developer-tips-for-alfresco-share-33/
• Client JS debugging: Firebug (FF), Inspector (Safari)• Server JS debugging: WebScript Javascript debugger
• http://localhost:8081/share/page/api/javascript/debugger
4
Old customisation concepts < v3.3
• Override (do NOT modify source files)
• ${TOMCAT_HOME}/shared/classes/alfresco• /web-extension• /web-extension/share-config-custom.xml• /web-extension/custom-slingshot-application-context.xml • /web-extension/site-webscripts • /site-webscripts - new webscripts
• ${TOMCAT_HOME}/webapps/share-extension.war
(.js, .css, .png etc)
5
New customisation concepts = v3.3
• Override (do NOT modify source files)
• ${TOMCAT_HOME}/shared/classes/alfresco • /web-extension• /web-extension/share-config-custom.xml• /web-extension/site-webscripts
• ${TOMCAT_HOME}/shared/lib - ONLY new stuff• .jar!/alfresco/web-extension/custom-slingshot-{module}-context.xml
• .jar!/alfresco/site-webscripts• .jar!/META-INF (.js, .css, .png etc)
6
New customisation concepts >= v3.4b
• In Share v3.4b all client side files are brought in using urls like “share/res/…”
• Which makes it possible to override .js, .css & .png etc in a .jar file’s META-INF directory
• No need anymore to override the templates that import the resources
• Ant project for building a share extension .jar• https://share-extras.googlecode.com/svn/trunk/Site Tags Dashlet/
7
Use case: ACME Enterprises™
• Running Alfresco Share v3.4b• Using collaboration sites for their core projects• Marketing needs sites with event statistics• Uses a 3rd party library: Flot Statistics™
8
What we are going to do….
ACME’s Share
• Configured header
• Changed column layout on “My Tasks”
• Replace “links” component on document details
• New “Marketing” site preset with a custom statistics page
9
Configure the header
web-extension/share-config-custom.xml
<config replace="true"> <header> <app-items> <!-- defaults: icon="{id}.png" label="header.{id}.label" description="header.{id}.description" --> <item type="link" id="acme-about">/acme-about</item> <item type="link" id="acme-news">/acme-news</item> <item type="js" id="sites">Alfresco.module.Sites</item> … </app-items> </header></config>
10
acme header messages & news icon
acme.jar!/alfresco/messages/acme.properties
header.acme-about.label=About Acmeheader.acme-about.description=About Acme Enterprisesheader.acme-news.label=Acme Newsheader.acme-news.description=News about the Acme Company
/share/res/components/images/header/acme-news.png
acme.jar!/META-INF/components/images/header/acme-news.png
11
Adding a resource bundle (acme.properties)
.jar!/alfresco/web-extension/custom-slingshot-acme-context.xml
<?xml version='1.0' encoding='UTF-8'?><!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'><beans> <bean id="flot.acme.resources" class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent"> <property name="resourceBundles"> <list> <value>alfresco.messages.acme</value> </list> </property> </bean></beans>
12
What we are going to do….
ACME’s Share
• Configured header
• Changed column layout on “My Tasks”
• Replace “links” component on document details
• New “Marketing” site preset with a custom statistics page
13
Override the My Task lists cell renderer
<#include "../component.head.inc"><!-- Common Workflow Actions --><@script type="text/javascript"
src="${page.url.context}/res/components/workflow/workflow-actions.js"></@script>
<!-- Task List --><@link rel="stylesheet" type="text/css"
href="${page.url.context}/res/components/workflow/task-list.css" /><@script type="text/javascript"
src="${page.url.context}/res/components/workflow/task-list.js"></@script><!-- Acme's Task List --><@script type="text/javascript"
src="${page.url.context}/res/acme/components/workflow/task-list.js"></@script>
web-extension/site-webscripts/org/alfresco/components/workflow/task-list.get.head.ftl
Make sure the custom code is used…
14
Override the My Task lists cell renderer
…and place the new method implementation in:
// Override "icon" column in My Tasks listAlfresco.component.TaskList.prototype.renderCellTaskInfo = function
Acme_TL_renderCellTaskInfo(elCell, oRecord, oColumn, oData){ elCell.innerHTML = <custom code goes here>;};
${TOMCAT_HOME}/shared/lib/acme.jar!/META-INF/acme/components/workflow/task-list.js
15
What we are going to do….
ACME’s Share
• Configured header
• Changed column layout on “My Tasks”
• Replace “links” component on document details
• New “Marketing” site preset with a custom statistics page
16
How a page is rendered…
URL: /share/page/site/engineering/document-details?nodeRef=…headertitlenavigationpath
document-actions
document-links
How a page is rendered…
17
URL: /share/page/site/engineering/{pageId}
pages/{pageId}.xml:<template-instance>{templateInstance}</template-instance>
template-instances/{templateInstance}.xml:<template>{template}</template><component> <region-id>{regionId}</region-id> <url>{webscriptURL}</url><component>
templates/…/{template}.ftl:
<html><@region id=“{regionId}” scope”{scope}”></html>
components/webscript.get.desc.xml:<url>{webscriptURL}</url>
18
… find the scope, region-id & template instance…
URL: /share/page/site/engineering/document-details
pages/document-details.xml:<template-instance>document-details</template-instance>
template-instances/document-details.xml:<template>document-details</template><component> <region-id>document-links</region-id> <url>/components/document-details/document-links</url><component>
templates/…/document-details.ftl:
<html><@region id=“document-links” scope”template”></html>
components/document-links.get.desc.xml:
<url>/components/document-details/document-links</url>
19
…and override the component binding
web-extension/site-data/components/template.document-links.document-details.xml
<?xml version='1.0' encoding='UTF-8'?><component> <url>/acme/components/document-details/document-syndication</url></component>
20
What we are going to do….
ACME’s Share
• Configured header
• Changed column layout on “My Tasks”
• Replace “links” component on document details
• New “Marketing” site preset with a custom statistics page
21
Acme’s ”Marketing” sites
• Custom dashboard (like above)• Calendar renamed to ”Marketing Events”• New ”Event Statistics” page• No blog, wiki links in navigation
22
web-extension/site-data/presets/presets.xml
<presets> <preset id="acme-marketing-preset"> <components><!-- Code to bind in dashlets (visible on the next slide) --> </components> <pages> <page id="site/${siteid}/dashboard"> <title>Marketing dashboard</title> <description>Dashboard for Marketing site</description> <template-instance>dashboard-2-columns-wide-right</template-instance> <authentication>user</authentication> <properties><!-- Arbitrary properties that may be read using: sitedata.getPage("site/" + siteId + "/dashboard").properties --> </properties> </page> </pages> </preset> </presets>
23
presets.xml – bind in the dashlets
<components> <!-- dashlets --> <component> <scope>page</scope> <region-id>component-1-1</region-id> <source-id>site/${siteid}/dashboard</source-id> <url>/components/dashlets/docsummary</url> </component> <component> <scope>page</scope> <region-id>component-2-1</region-id> <source-id>site/${siteid}/dashboard</source-id> <url>/components/dashlets/calendar</url> </component></components>
24
presets.xml – define the pages and their titles
<page id="site/${siteid}/dashboard"> <properties> <!-- Read by collaboration-navigation.get.js to render links --> <sitePages> [ {"pageId":"documentlibrary"}, {"pageId":"calendar"}, {"pageId":"flot-event-statistics"} ] </sitePages> <pageMetadata> { "calendar": { "titleId":"page.acme-marketing-calendar.title", "descriptionId":"page.acme-marketing-calendar.description” } } </pageMetadata> </properties></page>
25
Display new preset in create site dialog
web-extension/site-webscripts/org/alfresco/modules/create-site.get.js
var sitePresets = [{ id: "site-dashboard", name: msg.get("title.collaborationSite")},{ id: "acme-marketing-preset", name: msg.get("title.acme-marketing-site")}];model.sitePresets = sitePresets;
26
The ”Event Statistics” page
titlenavigation
component-{i}
27
templates/…/flot-grid.ftl<#include "org/alfresco/include/alfresco-template.ftl" /><@templateHeader "transitional"> <@script type="text/javascript" src="${url.context}/res/flot/js/flot.js"/> <@script type="text/javascript" src="${url.context}/res/flot/js/jquery.js"/> <@script type="text/javascript" src="${url.context}/res/flot/js/jquery.flot.js"/></@><@templateBody> <div id="alf-hd"> <@region id="header" scope="global" protected=true /> <@region id="title" scope="template" protected=true /> <@region id="navigation" scope="template" protected=true /> </div> <div id="bd"> <#list 1..9 as cid><div style="float: left;"> <@region id="${'component-' + cid}" scope="page" protected=true/> </div></#list> <div style="clear: both;"></div> </div></@><@templateFooter> <div id="alf-ft”><@region id="footer" scope="global" protected=true /></div></@>
28
template-instances/flot-collaboration-grid.xml<?xml version='1.0' encoding='UTF-8'?><template-instance> <template-type>flot-grid</template-type> <components> <component> <region-id>title</region-id> <url>/components/title/collaboration-title</url> </component> <component> <region-id>navigation</region-id> <url>/components/navigation/collaboration-navigation</url> </component> </components></template-instance>
29
pages/flot-event-statistics.xml<?xml version='1.0' encoding='UTF-8'?><page> <id>flot-event-statistics</id> <title>Event Statistics</title> <template-instance>flot-collaboration-grid</template-instance> <authentication>user</authentication> <components> <component> <region-id>component-1</region-id> <url>/flot/components/event-statistics</url> <properties> <title>flot.title.events-last-30-days</title> <days>-30</days> </properties> </component> <component> <region-id>component-2</region-id> <url>/flot/components/event-statistics</url> <properties> <title>flot.title.events-next-7-days</title> <days>7</days> </properties> </component> </components></page>
30
components/…/event-statistics.get.html.ftl<#assign el=args.htmlid?js_string><script type="text/javascript">//<![CDATA[ new Flot.component.EventStatistics("${el}").setOptions({ siteId: "${page.url.templateArgs.site!""}", days: ${args.days!7} }).setMessages( ${messages} );//]]></script><div id="${el}-body" class="flot-event-statistics"> <h1>${msg(args.title!"header")}</h1> <div id="${el}-chart" style="width: ${args.width!"500px"}; height: ${args.height!"500px"};"></div> <div id="${el}-control" class="control" style="width: ${args.width!"500px"};"></div> <div id="${el}-tooltip" class="tooltip theme-bg-color-2 theme-border-4" style="display: none;"></div></div>
31
event-statistics.js (client side)Flot.component.EventStatistics = function(htmlId){ Flot.component.EventStatistics.superclass.constructor.call (this, "Flot.component.EventStatistics", htmlId, ["button"]); return this;};YAHOO.extend(Flot.component.EventStatistics, Alfresco.component.Base,{ options: { days: null }, onReady: function () { // Create chart... }});
32
Best practice
• Place overrides in shared/classes/org/alfresco/web-extension. • If you need to override client side resources place them in a file named
share-extension.jar
• Prefix with “3rd party” name:• pages – flot-event-statistics.xml• templates – flot-grid.xml • template-instances – flot-collaboration-grid.ftl• css selectors - .flot-event-statistics
• Use packages where possible:• webscripts:
• /alfresco/site-webscripts/flot/components/event-statistics.get.desc.xml
• javascript:• /flot/components/events/event-statistics.js• Flot.component.EventStatistics
33
Future
• Move out all datatable renderers• Sweep of configuration possibilities & hookpoints• Scope overrides
• I.e “page” overrides “template” but also make “uri” override “template” and “page”. This makes it possible to have “site specific” components on pages.
• …and your suggestions in the forums!
34
JavaScript tips
Alfresco.Location Alfresco.util.DragAndDrop
Alfresco.util.DataTable Alfresco.module.DataPicker
35
Learn Morewiki.alfresco.comforums.alfresco.comtwitter: @AlfrescoECM
36
Shape & Color Pallette
Normal Text
Normal TextNormal Text
37
Summary…
38
URL: /share/page/site/{siteId}/flot-event-statistics
pages/flot-event-statistics.xml:<template-instance>flot-collaboration-grid</template-instance><component> <region-id>component-1</region-id> <url>/flot/components/event-statistics</url><component>
template-instances/flot-collaboration-grid.xml:<template>flot-grid</template><component> <region-id>title</region-id> <url>/components/title/collaboration-title </url><component>
templates/…/flot-grid.ftl:<@region id=“title” scope”template”><@region id=“component-1” scope”page”>
components/…/event-statistics.get.desc.xml:<url>/flot/components/event-statistics</url>
components/…/collaboration-title.get.desc.xml:<url>/components/title/collaboration-title</url>
Recommended