APPS 2 Customizing the Document Library
Post on 23-Nov-2014
124 Views
Preview:
Transcript
1
Mike HatfieldSenior Software Engineer, Alfresco
twitter: @mikehatfield
2
What We’ll Cover
• Architecture• Challenges to customization and extension
• Plans for improvement
• Case Study: the DoD 5015.2 Extensions• Extension Example
• Status Indicators• Custom Actions• Custom Metadata• Filters
3
4
Custom UICustom UI
Custom UICustom UI
Custom UICustom UI
New FiltersNew Filters
New FiltersNew Filters
New FiltersNew Filters
5
• Consolidate scattered action configuration• share-config-custom.xml instead of webscriptconfig• Still possible to restrict & specialise actions on details pages
• New actions via configuration where practicable• jar file for client-side UI assets, I18N• CSS and JS dependencies via config (see Forms & Header)
• Leverage Repository Actions & scripts• Custom Views
• Web-tier rendering• Open CMIS
6
7
Custom Actions
Numerous new and overridden actions to support the DoD requirements specification.
8
Custom Toolbar
Sensitive to current folder type. New and overridden actions.
Custom Filters
Removed unsuitable filters (user filters, tags). One static, one dynamic (populated from list of saved searches on the Repository).
9
“documentLibrary” container type determines components
10
11
documentlibrary.js
connector.get("/slingshot/doclib/container/" + siteId + "/" + containerId);"dod:filePlan"
model.doclibType = fromRepoType("dod:filePlan");“dod5015”
documentlibrary.js
connector.get("/slingshot/doclib/container/" + siteId + "/" + containerId);"dod:filePlan"
model.doclibType = fromRepoType("dod:filePlan");“dod5015”
documentlibrary.ftl
<@region id=doclibType+ "documentlist" scope="template" protected=true />
documentlibrary.ftl
<@region id=doclibType+ "documentlist" scope="template" protected=true />
Surf Component Binding
template.dod5015-documentlist.documentlibrary.xml
<url>/components/documentlibrary/dod5015/documentlist</url>
Surf Component Binding
template.dod5015-documentlist.documentlibrary.xml
<url>/components/documentlibrary/dod5015/documentlist</url>
12
DoD 5015.2 Method
documentlibrary.js
page = sitedata.getPage("site/" + siteId + "/dashboard");pageMeta = eval('(' + p.properties.pageMetadata + ')');contentType = doclibMeta.type;
connector.get("/slingshot/doclib/container/" + siteId + "/" + containerId+ “?type=“ + toRepoType(contentType));
”dod:filePlan”
documentlibrary.js
page = sitedata.getPage("site/" + siteId + "/dashboard");pageMeta = eval('(' + p.properties.pageMetadata + ')');contentType = doclibMeta.type;
connector.get("/slingshot/doclib/container/" + siteId + "/" + containerId+ “?type=“ + toRepoType(contentType));
”dod:filePlan”
presets.xml
<preset id="rm-site-dashboard"><page id="site/${siteid}/dashboard"><properties><pageMetadata>{"documentlibrary":{…, "type":"dod5015"}}</pageMetadata>
presets.xml
<preset id="rm-site-dashboard"><page id="site/${siteid}/dashboard"><properties><pageMetadata>{"documentlibrary":{…, "type":"dod5015"}}</pageMetadata>
13
Web QuickStart Method
LoadWebSiteDataGet.java
NodeRefdocLib = siteService.getContainer(siteId, COMPONENT_DOCUMENT_LIBRARY);
siteService.createContainer(siteId, COMPONENT_DOCUMENT_LIBRARY, WebSiteModel.TYPE_WEBSITE_CONTAINER, null);
ornodeService.setType(docLib, WebSiteModel.TYPE_WEBSITE_CONTAINER);
LoadWebSiteDataGet.java
NodeRefdocLib = siteService.getContainer(siteId, COMPONENT_DOCUMENT_LIBRARY);
siteService.createContainer(siteId, COMPONENT_DOCUMENT_LIBRARY, WebSiteModel.TYPE_WEBSITE_CONTAINER, null);
ornodeService.setType(docLib, WebSiteModel.TYPE_WEBSITE_CONTAINER);
dashlet
connector.get("/api/loadwebsitedata?site=" + siteId);
dashlet
connector.get("/api/loadwebsitedata?site=" + siteId);
14
YUI Helps
YUI developers added a number of helper functions to allow OO-style JavaScript modules.
• Notice:• constructor• superclass• extend• augment• etc…
15
• Full override / replacement control on all tiers.
• Your code can be almost completely independent of Alfresco’s.
Pros
• Mandatory component mapping , even for “native” components.
• Still have to copy/paste where <include> cannot be used, e.g. I18N.
• Repository folder type to component prefix issue.
• Not a 100% “clean” override mechanism.
Cons
16
Big Development Overhead
template.dod5015-actions-common.documentlibrary.xmltemplate.dod5015-documentlist.documentlibrary.xmltemplate.dod5015-file-upload.documentlibrary.xmltemplate.dod5015-fileplan.documentlibrary.xmltemplate.dod5015-flash-upload.documentlibrary.xmltemplate.dod5015-html-upload.documentlibrary.xmltemplate.dod5015-navigation.documentlibrary.xmltemplate.dod5015-savedsearch.documentlibrary.xmltemplate.dod5015-title.documentlibrary.xmltemplate.dod5015-toolbar.documentlibrary.xmltemplate.dod5015-tree.documentlibrary.xml…And that’s just the browse page!
17
• Overview • Customisations
• Status Indicators• Custom Metadata• New Filters• Custom Action
• Based on Alfresco Community 3.4.b• Need to use AMP on the Repository until refactoring work is complete• Share extensions via .jar and web-extension folder
18
Overview
19
20
Provide the user a quick indication of the current status of a folder or document, e.g. aspects applied.
Calculated in evaluator.lib.js
• Repository• evaluator.lib.js
• Share• I18N messages• Indicator images
21
/* Exif metadata */
if (node.hasAspect("exif:exif"))
{
status["exif"] = true;
}
/* Geographic */
if (node.hasAspect("cm:geographic"))
{
status["geographic"] = true;
}
22
1. share.jar!/org/springframework/extensions/surf/custom-slingshot-geographic-context.xml
<bean id="geographic.custom.resources" class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent">
<property name="resourceBundles">
<list>
<value>alfresco.messages.geographic</value>
</list>
</property>
</bean>
1. share.jar!/alfresco/messages/geographic.properties
tip.geographic=Geo Location
tip.exif=EXIF Metadata
23
status[”exif"] = true;
status["geographic"] = true;
share.jar!/META-INF/components/documentlibrary/images
1.exif-indicator-16.png
2.geographic-indicator-16.png
24
Rendered entirely by the web browser from JSON data.
• Repository• item.lib.ftl• Maybe also JavaScript logic
• Share• I18N messages• Override cell renderer
25
1. alfresco.amp!/WEB-INF/classes/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/item.lib.ftl
<#if node.hasAspect("cm:geographic")>“geolocation”:{ "latitude": ${(node.properties["cm:latitude"]!0)?c}, "longitude": ${(node.properties["cm:longitude"]!0)?c}},</#if>
<#if node.hasAspect(”exif:exif")>“exif”:{ …},</#if>
26
1. shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary/actions-common.get.head.ftl
<@script type="text/javascript" src="${page.url.context}/res/components/geographic/geographic-extension.js"></@script>
27
1. Override fnRenderCellDescription
share.jar!/META-INF/components/geographic/geographic-extension.js
YAHOO.util.Event.onContentReady("alf-hd", function(){ if (Alfresco.DocumentList) {Alfresco.DocumentList.prototype.fnRenderCellDescription = function
DL_fnRenderCellDescription() { … if (record.exif) {desc += scope.msg(“detail.exposure”) + record.exif.exposureTime; } … } }}
28
Allow easy filtering by any Repository logic, most commonly a Lucene or Alfresco FTS search query.
• Repository• filters.lib.js
• Share• I18N messages• Filter webscriptconfig
29
1. shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary/filter.get.config.xml
<filters>
…
<filter id="geo" label="link.geo-located" />
<filter id="exif" label="link.exif" />
…
</filters>
30
1. alfresco.amp!/WEB-INF/classes/alfresco/templates/webscripts/org/alfresco/slingshot/documentlibrary/filters.lib.js
case "geo":filterQuery = "+PATH:\"" +parsedArgs.rootNode.qnamePath + "//*\"";filterQuery += "+ASPECT:\"cm:geographic\"";filterParams.query = filterQuery break;
case "exif":filterQuery = "+PATH:\"" +parsedArgs.rootNode.qnamePath + "//*\"";filterQuery += "+ASPECT:\"exif:exif\"";filterParams.query = filterQuery break;
31
Can be configured to only appear if a folder or document is in a particular state and/or the user has the correct permission(s) and/or the page is within a Site context and/or the action is on the browse or details page.
• Repository• evaluator.lib.js• Action processing (optional)
• Share• I18N messages• Action configuration• Client-side logic & images
32
/* Geographic */
if (node.hasAspect("cm:geographic"))
{
status["geographic"] = true;
permissions["geographic"] = true;
}
33
1. shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary/documentlist.get.config.xml
2. shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/document-details/document-actions.get.config.xml
3. etc…
<actionSet id="document">
…
<action type="simple-link" id="onActionGeographic" permission="geographic" href="{geographicUrl}" label="actions.document.geographic" />
</actionSet>
34
1. shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary/actions-common.get.head.ftl
<@link rel="stylesheet" type="text/css" href="${page.url.context}/res/components/geographic/geographic-extension.css" />
2. share.jar!/META-INF/components/geographic/geographic-extension.css
.doclist .onActionGeographica{ background-image: url(pin.png) !important;}
35
var override = Alfresco.DocumentList || Alfresco.DocumentActions;
// Store reference to getActionUrls() function to allow extension.
vargetActionUrls_geographic = override.prototype.getActionUrls;
override.prototype.getActionUrls = function(recordData)
{
varactionUrls = getActionUrls_geographic.apply(this,
arguments);
actionUrls["geographicUrl"] = Alfresco.util.siteURL(
"geographic-map?nodeRef=" + recordData.nodeRef);
return actionUrls;
};
36
37
38
• Consolidate scattered action configuration• New actions via configuration where practicable• Remove references to non-core Share code• Leverage Repository Actions & scripts• Custom Views
39
• Feedback
40
wiki.alfresco.com/wiki/Shareblogs.alfresco.com/wp/mikeh/
top related