Customizing the Document Library
Upcoming SlideShare
Loading in...5
×
 

Customizing the Document Library

on

  • 9,303 views

The Share Document Library provides a number of out-of-the-box default actions and displays basic, essential metadata for documents and folders. This session will show you how to add custom metadata ...

The Share Document Library provides a number of out-of-the-box default actions and displays basic, essential metadata for documents and folders. This session will show you how to add custom metadata and status indicators, modify the available actions and wire-up new filters. We'll also look at how the Document Library was extended for the DoD 5015.2 Records Management Fileplan browser. You will need to be familiar with basic Surf concepts as well as JavaScript and Freemarker to follow the webscript customization. Familiarity with YUI 2.x and CSS will aid understanding during this session.

Statistics

Views

Total Views
9,303
Views on SlideShare
9,302
Embed Views
1

Actions

Likes
10
Downloads
205
Comments
1

1 Embed 1

https://twitter.com 1

Accessibility

Categories

Upload Details

Uploaded via as Microsoft PowerPoint

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel

11 of 1

  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
  • Customizing Alfresco Share is such a mess.. Worst practices are taken from PHP.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment
  • If you have any specific questions or need me to show you how to do something just come and find me

Customizing the Document Library Customizing the Document Library Presentation Transcript

  • Customizing the Document Library
    1
    Mike Hatfield
    Senior Software Engineer, Alfresco
    twitter: @mikehatfield
  • Customizing the Document Library
    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
  • Architecture
    3
  • Architecture
    4
    Heavy Use of YUI for “Web 2.0” Experience
    • Many JavaScript frameworks evaluated
    Only YUI had a full-time staff, full API documentation, supported UI widgets
    • Many YUI widgets and modules used
    DataTable
    Treeview
    Buttons, Menus, Containers
    History Manager for “AJAX back button” support
    XHR wrappers, JSON parser
    • Most HTML rendering performed client-side
    • yuilibrary.com is your friend!
  • Architecture
    5
    Initial Page Load
    • Create all YUI controls
    • Register event handlers
    • Extract URL arguments
    • Bubbling Event  “changeFilter”
    • onChangeFilter: updateDocList()
    • Webscript URL (via proxy)  YUI DataSource
    • Repository webscripts execute for given filter & params
    • Bubbling Event  “filterChanged”
    • Render JSON response using DataTable cell renderers
  • Architecture
    6
    Subsequent Navigations (e.g Folder)
    • Bubbling Event  “changeFilter” [new filter params]
    • onChangeFilter: Build data webscript URL
    • History Manager  multiNavigate()
    • onHistoryManagerFilterChanged: updateDocList()
    • Webscript URL (via proxy)  YUI DataSource
    • Repository webscripts execute for given filter & params
    • Bubbling Event  “filterChanged”
    • Render JSON response using DataTable cell renderers
  • Architecture
    7
    YUI DataTable Renderers
    • One renderer per data column
    Selected file / folder
    Status indicator
    Thumbnail / icon
    Metadata description
    Actions
    • Render XSS-safe HTML from parsed JSON
    elCell.innerHTML = “<div>…</div>”
    • YUI wraps output in <table><tr><td> tags
  • Architecture
    8
    Actions
    • Currently defined in webscript config xml files
    Separate configs for browse page, details pages
    • Action Sets based on repository business logic
    evaluator.lib.js
    “document”, “folder”, “locked”, “workingCopyOwner”, etc.
    • Two action types
    “simple-link” URL via getActionUrls()
    {downloadUrl}, {viewUrl}, {folderDetailsUrl}
    “action-link” JavaScript function  “id” attribute
    • ID attribute defines action icon and JavaScript function
  • Architecture
    9
    Actions
    • Permissions
    Comma-separated list
    User AND asset must have ALL permissions for action to appear
    “Virtual” permissions as well as role-based
    create, edit, delete, permissions, cancel-checkout
    inline-edit, simple-approve, googledocs-edit
    Negative permission via tilde (~)
    ~filter-path, ~portlet, ~googledocs-edit
    • Label attribute for I18N message
  • Current Extension Points
    10
    Custom UI
    New Filters
    New Actions
    Custom UI
    New Filters
    New Actions
    Custom UI
    New Actions
    New Actions
    New Filters
  • Plans for Improvements
    11
    • 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
  • Case Study: DoD 5015.2 Extensions
    12
  • Case Study: DoD 5015.2 Extensions
    13
    Custom Actions
    Numerous new and overridden actions to support the DoD requirements specification.
  • Case Study: DoD 5015.2 Extensions
    14
    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).
  • Case Study: DoD 5015.2 Extensions
    15
    “documentLibrary” container type determines components
  • Case Study: DoD 5015.2 Extensions
    16
  • Template: documentlibrary
    17
    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 />
    Surf Component Binding
    template.dod5015-documentlist.documentlibrary.xml
    <url>/components/documentlibrary/dod5015/documentlist</url>
  • Creating the Container
    18
    DoD 5015.2 Method
    presets.xml
    <preset id="rm-site-dashboard">
    <page id="site/${siteid}/dashboard">
    <properties>
    <pageMetadata>{"documentlibrary":{…, "type":"dod5015"}}</pageMetadata>
    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”
  • Creating the Container
    19
    Web QuickStart Method
    dashlet
    connector.get("/api/loadwebsitedata?site=" + siteId);
    LoadWebSiteDataGet.java
    NodeRefdocLib = siteService.getContainer(siteId, COMPONENT_DOCUMENT_LIBRARY);
    siteService.createContainer(siteId, COMPONENT_DOCUMENT_LIBRARY,
    WebSiteModel.TYPE_WEBSITE_CONTAINER, null);
    or
    nodeService.setType(docLib, WebSiteModel.TYPE_WEBSITE_CONTAINER);
  • Case Study: DoD 5015.2 Extensions
    20
    YUI Helps
    YUI developers added a number of helper functions to allow OO-style JavaScript modules.
    • Notice:
    constructor
    superclass
    extend
    augment
    etc…
  • Component Replacement Approach
    21
    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
  • Mandatory Component Mapping
    22
    Big Development Overhead
    template.dod5015-actions-common.documentlibrary.xml
    template.dod5015-documentlist.documentlibrary.xml
    template.dod5015-file-upload.documentlibrary.xml
    template.dod5015-fileplan.documentlibrary.xml
    template.dod5015-flash-upload.documentlibrary.xml
    template.dod5015-html-upload.documentlibrary.xml
    template.dod5015-navigation.documentlibrary.xml
    template.dod5015-savedsearch.documentlibrary.xml
    template.dod5015-title.documentlibrary.xml
    template.dod5015-toolbar.documentlibrary.xml
    template.dod5015-tree.documentlibrary.xml

    And that’s just the browse page!
  • Extension Example
    23
    • 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
  • Extension Example: Photography
    24
    Overview
  • DemoOut-of-the-box Share
    25
  • Extension: Status Indicators
    26
    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
  • Repository: Override evaluator.lib.js
    27
    /* Exif metadata */
    if (node.hasAspect("exif:exif"))
    {
    status["exif"] = true;
    }
    /* Geographic */
    if (node.hasAspect("cm:geographic"))
    {
    status["geographic"] = true;
    }
  • Share: Indicator images
    28
    status[”exif"] = true;
    status["geographic"] = true;
    share.jar!/META-INF/components/documentlibrary/images
    exif-indicator-16.png
    geographic-indicator-16.png
  • Share: Add I18N messages
    29
    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>
    share.jar!/alfresco/messages/geographic.properties
    tip.geographic=Geo Location
    tip.exif=EXIF Metadata
  • Extension: Custom Metadata
    30
    Rendered entirely by the web browser from JSON data.
    • Repository
    • item.lib.ftl
    • Maybe also JavaScript logic
    • Share
    • I18N messages
    • Override cell renderer
  • Repository: Override item.lib.ftl
    31
    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>
  • Share: Reference extension JavaScript
    32
    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>
  • Share: Override cell renderer
    33
    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;
    }

    }
    }
    }
  • Extension: New Filter
    34
    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
  • Share: Filter webscriptconfig
    35
    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>
  • Repository: Filter webscript override
    36
    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;
  • Extension: Custom Action
    37
    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
  • Repository: Override evaluator.lib.js
    38
    /* Geographic */
    if (node.hasAspect("cm:geographic"))
    {
    status["geographic"] = true;
    permissions["geographic"] = true;
    }
  • Share: Action configuration
    39
    shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary/documentlist.get.config.xml
    shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/document-details/document-actions.get.config.xml
    etc…
    <actionSet id="document">

    <action type="simple-link" id="onActionGeographic" permission="geographic" href="{geographicUrl}" label="actions.document.geographic" />
    </actionSet>
  • Share: CSS and JS dependencies
    40
    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" />
    share.jar!/META-INF/components/geographic/geographic-extension.css
    .doclist .onActionGeographica
    {
    background-image: url(pin.png) !important;
    }
  • Share: Proxy JavaScript function
    41
    var override = Alfresco.DocumentList || Alfresco.DocumentActions;
    // Store reference to getActionUrls() function to allow extension.
    vargetActionUrls_geo = override.prototype.getActionUrls;
    override.prototype.getActionUrls = function(recordData)
    {
    varactionUrls = getActionUrls_geo.apply(this, arguments);
    actionUrls["geographicUrl"] = Alfresco.util.siteURL(
    "geographic-map?nodeRef=" + recordData.nodeRef);
    return actionUrls;
    };
  • DemoNew Extensions
    42
  • The End Result
    43
  • Roadmap
    44
    • Consolidate scattered action configuration
    • New actions via configuration where practicable
    • Remove references to non-core Share code
    • Leverage Repository Actions & scripts
    • Custom Views
  • Q & A
    45
    • Feedback
  • Learn More
    46
    wiki.alfresco.com/wiki/Share
    blogs.alfresco.com/wp/mikeh/