Appendix C. Repository FreeMarker Template API

Templates are widespread throughout Alfresco: They are used within the repository core to generate emails and activities, in the Explorer client to build custom views, at the remote REST API layer, and also as the default rendering mechanism for the Web Script and Surf Frameworks.

Alfresco provides a number of ways to process templates; REST-style URL, Web script components, and JSF UI components. In addition, AVM repository data can be processed in templates.

Multiple template engines are supported, with FreeMarker as the default. The template engine is not tied to any output file format: Templates can output entire HTML files as well as snippets of HTML, XML, JSON, or any other format desired. This makes them extremely flexible and appropriate for developing all kinds of solutions with Alfresco.

TEMPLATE FILES

Templates can be stored either on the classpath (for example, in alfresco/config/templates) or in the repository store.

Each template file will be specific to a particular template engine. The template service will pick the appropriate engine based on the file extension. By default, FreeMarker template files will be used. In the case of the Web Script and Surf Frameworks, FreeMarker is always selected as the template engine.

TEMPLATE MODELS

A model consists of a number of objects or a hierarchy of objects from which a template file retrieves values that can be used to dynamically generate the output. The model is like the API for the template page: It provides the objects from which properties, values, and further objects can be accessed. The Alfresco repository provides a "default" model that is always available when rendering templates via the JSF template component and the template servlet. The Web Script Framework provides additional model objects relevant to processing output for remote APIs. Programmatically it is also possible to define a custom model that can be merged into the default model to provide additional model objects. Custom Java objects can be configured via Spring to make them available to template models within the repository and/or the Web Script Framework.

Default Model

The default model provides a number of common objects useful for most templates. Most of the objects wrap the notion of an Alfresco Node (such as a space or document in the repository) and are known as TemplateNode objects. This provides a rich OO layer to make it easy to display common Alfresco concepts, such as node properties, aspect values, and content.

If you are accessing a template through the Explorer client UI Template component (this is the common case when developers use this component directly), the following named objects are provided by default at the root of the model. Note that Web scripts hosted within the Alfresco repository tier also have access to the following template root objects. Web scripts hosted within the presentation tier (that is, within Alfresco Surf) have their own extras, as described in Appendix B.

  • companyhome — The Company Home template node

  • userhome — The current user's Home Space template node

  • person — The node representing the current user's Person object

  • template — The node representing the template itself

When accessing a template through the Explorer Web client using a custom view for a space, the Preview In Template action, or a URL using the template servlet, the following named object is also provided:

  • space — The current space template node

When accessing a template through the Explorer Web client using a custom view for a document, the Preview In Template action, or a URL using the template servlet, the following named object is also provided:

  • document — The current document template node

The companyhome, userhome, person, template, space and document objects are all TemplateNode objects. A TemplateNode object represents a node in the Alfresco repository and has its own rich API for accessing common Alfresco concepts, such as properties, aspects, associations, and content.

If accessing a template via the template servlet, the following object is also available:

  • args — A map of any URL parameters passed via the template content servlet. This is a neat way to pass additional parameters to your template. FreeMarker has built-in methods to parse integers and check for the existence of values that can be used to make your template even more interactive and powerful. For example, you can output the names of the arguments passed to a template:

    <#assign keys = args?keys>
    <#list keys as arg>
       ${arg}
    </#list>

Various other root objects are also available to provide a full set of rich functional objects to the template developer:

  • session — Session-related information providing a single value session.ticket for the current authentication ticket; useful when generating some Alfresco URLs for accessing outside of the Web client.

  • classification — Read access to classifications and root categories.

  • url — Provides a single property url.context that can be used to retrieve the Alfresco container context path, such as /alfresco; useful when generating URL links to objects. This is not available when using the template as a custom view on a space.

  • workflow — Read access to information on workflow objects and the currently executing workflows for a user.

The various default model objects can be accessed directly from the root of a model in your template. For example, you could use the following to display the name property of the userhome object:

${userhome.properties.name}

The Alfresco node model is built dynamically as you access it, enabling you to write statements such as:

${userhome.children[1].children[0].children[2].name}

Note

It should be noted that the FreeMarker template engine is very strict on the access of empty or null values. Unlike many templating or scripting languages that display empty values or assume FALSE as a default value for a missing property, the FreeMarker engine will instead throw an exception and abort the rendering of the template. To help you build stable templates, most of the TemplateNode API calls provided by the default model that return maps or sequences (lists) of items will return empty maps and sequences instead of null. Also if a null value may be returned by a call (for instance, from accessing a map to find a value by name), you should use the FreeMarker built-in exists method or, preferably, the shortened form of ?? to check for null first. Therefore:

<#if mynode??>
<#if mynode.assocs["cm:translations"]??>
     ${mynode.assocs["cm:translations"][0].content}
</#if>
</#if>

checks for the existence of mynode and then checks for the existence of a translation association before attempting to access the translation.

TemplateNode Model API

TemplateNode objects and any subsequent child node objects provide access to the common Alfresco concepts, such as properties, aspects, and associations. The following template API is provided:

  • properties — A map of the properties for the node, such as userhome.properties.name

    Properties may return several different types of objects. This depends entirely on the underlying property type in the repository. If the property is multi-value, the result will be a sequence that can be indexed like any other sequence or array. If the result is an unknown or unsupported type, the toString() result is generally used; therefore, the result will mostly be a String type. If the property can potentially contain a null value, take care when accessing it and use the exists FreeMarker built-in method to check for null values before accessing the property.

    Date and Boolean property values should be handled carefully. The FreeMarker built-in methods is_date and is_boolean can be used to check the property value type if the page developer is unsure of it. These values can then be formatted as appropriate.

    If the type of the property is a NodeRef object (d:noderef in the content model), the template model will automatically convert the property type into another TemplateNode object. This means the template developer can continue to dynamically walk the object hierarchy for that node. For example, if a document node has a NodeRef property called locale, you could execute the following to retrieve the name of the node the property references:

    ${document.properties.locale.properties.name}

    If a property is of the datatype d:content, additional API methods are available on the returned object. Methods are provided to retrieve the content, mimetype, displayMimetype, encoding, size, and url for the content property. For example:

    ${document.properties.content.mimetype}
    ${document.properties.content.content}

    As most document nodes are derived from the default Content Model type cm:content, shortcut APIs to access properties on the default cm:content content property are supplied directly on the TemplateNode object.

    Helper methods to perform some simple textual operations on the content properties are also provided:

    • content.getContentMaxLength(length)—Returns content up to a maximum length

    • content.getContentAsText(length)—Converts binary content (such as Word and PDF) to text, up to a maximum length

  • children — A sequence (list) of the child nodes. For example:

    mynode.children[0]
  • assocs — A map of the target associations for the node. Each entry in the map contains a sequence of the Node objects on the end of the association. For example:

    mynode.assocs["cm:translations"][0]
  • sourceAssocs — A map of the associations to this node. Each entry in the map contains a sequence of the Node objects for the given association that reference this node. For example:

    mynode.sourceAssocs["cm:avatarOf"][0]
  • childAssocs — A map of the child associations for the node. Each entry in the map contains a sequence of the Node objects on the end of the child association. For example:

    myforumnode.childAssocs["fm:discussion"][0]
  • aspects — A sequence of the aspects (as QName strings) applied to the node.

  • hasAspect(String aspectName) — A function that returns true if a node has the specified aspect. For example:

    <#if userhome.hasAspect("cm:templatable")>...</#if>
  • isContainer — If the node is a folder node, this is true; otherwise, it is false.

  • isDocument — If the node is a content node, this is true; otherwise, it is false.

  • isCategory — If the node is a category node, this is true; otherwise, it is false.

  • content — Returns the content for the default content property of the node as a string.

  • url — The URL to the content stream for the default content property for this node.

  • downloadUrl — The URL to the content stream for the default content property for this node as an HTTP1.1 attachment object.

  • displayPath — The display path to this node; constructed from the cm:name property of each parent node in the hierarchy.

  • webdavUrl — The WebDAV URL to the node, based on the cm:name-based path to the content for the default content property.

  • icon16 — The small icon image for this node.

  • icon32 — The large icon image for this node.

  • icon64 — The extra-large icon image for this node.

  • mimetype — The MIME type encoding for content for the default content property attached to this node.

  • displayMimetype — The human-readable version of the MIME type encoding for the content attached to this node.

  • encoding — The character encoding for content attached to the node from the default content property.

  • size — The size, in bytes, of content attached to this node for the default content property.

  • isLocked — If the node is locked, this is true; otherwise, it is false.

  • id — GUID for the node.

  • nodeRef — NodeRef string for the node.

  • name — Shortcut access to the name property.

  • type — Fully qualified QName type of the node.

  • typeShort — Prefix string or "short" QName type of the node.

  • parent — Parent node will be null only if this is the root node.

  • permissions — Sequence of the permissions explicitly applied to this node; strings returned are of the format [ALLOWED|DENIED];[USERNAME|GROUPNAME];PERMISSION. For example, ALLOWED;kevinr;Consumer can be easily tokenized on the semicolon (;) character.

  • inheritsPermissions — If the node inherits its parent node permissions, this is true; if the permissions are applied specifically, this is false.

  • hasPermission(permission) — Returns true if the current user has the specified permission on the node. For example:

    <#if userhome.hasPermission("Write")>...</#if>
  • childrenByXPath — Returns a map capable of executing an XPath query to find child nodes, such as companyhome.childrenByXPath["*[@cm:name='Data Dictionary']/*"]. The map executes an XPath search against the current node and returns a sequence of the nodes as results of the query.

  • childByNamePath — Returns a map capable of returning a single child node found by name path, such as companyhome.childByNamePath["Data Dictionary/Content Templates"].

    Under the covers, this method is building an XPath and executing a search against the cm:name attribute on children of the current node. This method allows you to find a specific child node if you know its name.

    Note that the previous API calls use the node they are executed against as the current context for the query. For example, if you have a folder node called myfolder and you execute the call myfolder.childByNamePath["MyChildFolder"], the search tries to find a folder called MyChildFolder as the child of the myfolder node.

  • childrenBySavedSearch — Returns a map capable of executing a search based on a previously Saved Search object.

    It returns a sequence of child nodes that represent the objects from the results of the search. For example:

    companyhome.childrenBySavedSearch["workspace://SpacesStore/92005879-996a-
    11da-bfbc-f7140598adfe"]

    The value specified must be a NodeRef to an existing Saved Search object.

  • childrenByLuceneSearch — Returns a map capable of executing a search against the entire repository based on a Lucene search string.

    It returns a sequence of nodes that represent the objects from the results of the search. The value can be any valid Lucene search string supported by Alfresco. Note that you may need to escape Lucene special characters. The entire repository is searched; the current node is only used as an access point to retrieve the search object.

  • nodeByReference — Returns a map capable of executing a search for a single node by NodeRef reference. This method allows you to find a node if you have the full NodeRef string or NodeRef object.

Advanced TemplateNode API

The following values are available but are required only for special-use cases.

  • qnamePath — QName-based path to the node; useful for building Lucene PATH-style queries that constrain to a path location

  • primaryParentAssocChildAssociationRef instance for the node

  • auditTrail — Returns a sequence of AuditInfo objects representing the Audit Trail for a node; available only if auditing is active for the repository

  • isTemplateContent(object) — Returns true if the given object is a TemplateContentData instance; useful to determine if a value returned from a property is of the d:contentdatatype

  • isTemplateNodeRef(object) — Returns true if the given object is a TemplateNodeRef instance; useful to determine if a value returned from a property is a d:noderefdatatype

Version History API

Through the Version History API, you can obtain metadata and content for a previous version of a versioned document node.

  • versionHistory — Returns a sequence of Version History record objects for a versioned TemplateNode

Each Version History record object has the following API:

  • id — GUID for the node

  • nodeRefNodeRef string for the node

  • name — Name property of the node version record

  • type — Fully qualified QName type of the node

  • createdDate — Created date of the version

  • creator — Creator of the version

  • versionLabel — Version label of the version record

  • isMajorVersion — Boolean true if this was a major version

  • description — Version history description

  • url — URL to the content stream for the frozen content state

In addition, the properties and aspects APIs as described above for TemplateNode are available, which return the frozen history state of the properties and aspects for the node version record.

Classification API

The classification object provides read access to classifications and root categories.

  • getRootCategories(String aspectQName) — A function to get a sequence of root categories for a classification

  • getAllCategoryNodes(String aspectQName) — A function to get a sequence of the category nodes for a classification

  • allClassificationAspects — Returns a sequence of QName objects of all classification aspects

The following extended node API methods are provided to work with category node objects:

  • categoryMembers — Gets all members of a category

  • subcategories — Gets all subcategories of a category

  • membersAndSubCategories — Gets all subcategories and members of a category

  • immediateCategoryMembers — Gets all immediate members of a category

  • immediateSubCategories — Gets all immediate subcategories of a category

  • immediateMembersAndSubCategories — Gets all immediate subcategories of a category

XML Content Processing API

The FreeMarker language supports XML DOM processing using either DOM functional or macro-style declarative operations. The Alfresco TemplateNode API has been extended to provide access to the FreeMarker DOM model objects.

  • xmlNodeModel — Returns the XML DOM model object for the content of the node

If the node content is valid XML and the XML can be parsed, then this method returns the root of the DOM for this node. The DOM can be walked and processed using the syntax as per the FreeMarker XML Processing Guide.

Workflow API

The workflow root object provides read access to the in-progress and finished tasks for the current user. It also provides a function to look up a single task by its task ID. The functions described mostly return WorkflowTaskItem objects.

  • assignedTasks — The sequence WorkflowTaskItem objects representing the assigned tasks for the current user

  • pooledTasks — The sequence WorkflowTaskItem objects representing the pooled tasks for the current user

  • completedTasks — The sequence WorkflowTaskItem objects representing the pooled tasks for the current user

  • getTaskById(taskId) — A function to return a single task given a known task ID

WorkflowTaskItem API

The WorkflowTaskItem API represents a single WorkflowTask object. It will probably contain a package of one or more objects that contains references to the objects pertinent to the workflow item, such as a document or folder of documents scheduled for review.

  • type — Workflow task type value

  • qnameType — Underlying QName model type of the workflow task

  • name — Task name value

  • description — Task description value

  • id — Task ID

  • isCompleted — Boolean value true if the task has been completed

  • startDate — Start date of the workflow task

  • transitions — Returns a map of the available task transition names to transition Labels and IDs

  • initiator — Returns a TemplateNode representing the user who initiated the workflow task

  • outcome — The outcome label from a completed task

  • package — Returns the NodeRef to the workflow package node

  • packageResources — Returns a sequence of the node resources from the package attached to this workflow task

  • properties — A map of all the properties for the task; includes all appropriate BPM-model properties

People API

The people root object provides basic user and group query API and inspection capabilities.

  • getPerson(username) — Returns the person node (cm:person) for the given username; returns null if not found

  • getGroup(groupname) — Returns a group node (usr:authorityContainer) for the given group authority name; returns null if not found

  • getMembers(group) — Gets the members (people) of a group, including all subgroups

  • getMembers(group, recurse) — Gets the members (people) of a group; optionally recurses into subgroups

  • getContainerGroups(person) — Gets the groups that contain the specified person (cm:person node)

  • isAdmin(person) — Returns true if the specified person (cm:person node) is a member of the Administrator group

  • isGuest(person) — Returns true if the specified person (cm:person node) is a guest user

  • getCapabilities(person) — Returns a map of capabilities (Boolean assertions) for the given person

  • isAccountEnabled(person) — Returns true if the specified user account is enabled; returns false if disabled

Default Model Methods

Custom template methods can be added to the FreeMarker language for use on template pages. The default model provides the following methods:

  • hasAspect(TemplateNode, String) — Returns the integer value 1 if the TemplateNode supplied has the aspect with the supplied QName String; otherwise, the integer value 0 will be returned.

  • dateCompare(DateA, DateB) — Compares two dates to see if they differ. This comparison returns 1 if DateA is greater than DateB; otherwise, returns 0.

  • dateCompare(DateA, DateB, Millis) — Compares two dates to see if they differ by the specified number of milliseconds. This comparison returns 1 if DateA is greater than DateB by at least the millisvalue in milliseconds; otherwise, returns 0.

  • dateCompare(DateA, DateB, Millis, Test) — Same as dateCompare(DateA, DateB, Millis) but with the test variable being one of the strings ">", "<", or "==" (greater than, less than, or equal to) as the test to perform.

  • incrementDate(Date, Millis) — Increments a date by the specified number of milliseconds and returns the new date.

  • message(String) — Returns the I18N message string (resolved for current user Locale setting) for the specified String message ID.

  • cropContent(TemplateNode, Length) — Returns the first n characters from the content stream for the specified node.

  • shortQName(String) — Returns the short, or prefix, version of a long QName.

Note

The return values for all custom methods are rather limited. It is only possible to return string, number, or date object. This is why the custom method described does not return a Boolean value, as you might expect.

The Current Date

In FreeMarker there is no such variable as today. Therefore, the current date (as a new Date() Java object) is provided in all templates as the "date" object in the root of the model. For example:

<#assign datetimeformat="EEE, dd MMM yyyy HH:mm:ss zzz">
${date?string(datetimeformat)}

JSP PAGE

As well as the commonly used Web script–based mechanisms for rendering template output, developers can write custom JSP pages with JSF components that render templates.

Following is the minimum JSP code required to display a template using the JSF Template component:

<%@ taglib uri="http://java.sun.com/jsf/html" prefix="h" %>
<%@ taglib uri="http://java.sun.com/jsf/core" prefix="f" %>
<%@ taglib uri="/WEB-INF/repo.tld" prefix="r" %>

<html>
<body>

<f:view>
<h:form>
<r:template template="alfresco/templates/userhome_docs.ftl" />
</h:form>
</f:view>

</body>
</html>
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.224.109.21