38
More Ways of Customizing Alfresco Share 1 Erik Winlöf UI Team, Alfresco twitter: @erikwinlof

More Ways of Extending Share

Embed Size (px)

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

Page 1: More Ways of Extending Share

1

More Ways of Customizing Alfresco Share

Erik WinlöfUI Team, Alfresco

twitter: @erikwinlof

Page 2: More Ways of Extending Share

2

What we’ll cover• Development tips, Customization concepts & Best practice• Use case: Acme Enterprises™• Future enhancements• (JavaScript tips)

Page 3: More Ways of Extending Share

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

Page 4: More Ways of Extending Share

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)

Page 5: More Ways of Extending Share

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)

Page 6: More Ways of Extending Share

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/

Page 7: More Ways of Extending Share

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™

Page 8: More Ways of Extending Share

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

Page 9: More Ways of Extending Share

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>

Page 10: More Ways of Extending Share

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

Page 11: More Ways of Extending Share

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>

Page 12: More Ways of Extending Share

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

Page 13: More Ways of Extending Share

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…

Page 14: More Ways of Extending Share

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

Page 15: More Ways of Extending Share

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

Page 16: More Ways of Extending Share

16

How a page is rendered…

URL: /share/page/site/engineering/document-details?nodeRef=…headertitlenavigationpath

document-actions

document-links

Page 17: More Ways of Extending Share

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>

Page 18: More Ways of Extending Share

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>

Page 19: More Ways of Extending Share

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>

Page 20: More Ways of Extending Share

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

Page 21: More Ways of Extending Share

21

Acme’s ”Marketing” sites

• Custom dashboard (like above)• Calendar renamed to ”Marketing Events”• New ”Event Statistics” page• No blog, wiki links in navigation

Page 22: More Ways of Extending Share

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>

Page 23: More Ways of Extending Share

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>

Page 24: More Ways of Extending Share

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>

Page 25: More Ways of Extending Share

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;

Page 26: More Ways of Extending Share

26

The ”Event Statistics” page

titlenavigation

component-{i}

Page 27: More Ways of Extending Share

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></@>

Page 28: More Ways of Extending Share

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>

Page 29: More Ways of Extending Share

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>

Page 30: More Ways of Extending Share

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>

Page 31: More Ways of Extending Share

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... }});

Page 32: More Ways of Extending Share

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

Page 33: More Ways of Extending Share

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!

Page 34: More Ways of Extending Share

34

JavaScript tips

Alfresco.Location Alfresco.util.DragAndDrop

Alfresco.util.DataTable Alfresco.module.DataPicker

Page 35: More Ways of Extending Share

35

Learn Morewiki.alfresco.comforums.alfresco.comtwitter: @AlfrescoECM

Page 36: More Ways of Extending Share

36

Shape & Color Pallette

Normal Text

Normal TextNormal Text

Page 37: More Ways of Extending Share

37

Page 38: More Ways of Extending Share

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>