Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
Web Scripts
JavaScript API
Examples
2.1
This information applies to Alfresco Version 2.1.
IMPORTANT: This document details the JavaScript API and Script Services for Alfresco 2.1 and 2.2. For more recent versions (3.0+) then please see this document: JavaScript API. If you are looking for details on Alfresco 2.0 or 1.4 then please see this document: JavaScript API For Alfresco 1.4 and 2.0. Note that this page will no longer be maintained or updated except to correct any mistakes.
The Alfresco JavaScript API allows script writers to develop JavaScript (ECMA Script) 1.6 compatible files that access, modify, and create Alfresco repository objects. It provides a simple, clean, and object-oriented API to well known Alfresco concepts such as Nodes, Properties, Associations, and Aspects. The API is similar to the Alfresco Template API - with a significant difference in that it allows modification and creation of nodes, aspects, and properties.
Using the API script writers can:
In addition, scripts can create new files, folders, or nodes of any type, copy/move/delete nodes and create/modify/remove associations between nodes. All the usual Alfresco security and ACL permissions apply.
In Alfresco Version 2.1, the ability for scripts to include other scripts has been added. The developer can build libraries of scripts that are included at runtime to reduce copy/paste between script files.
As JavaScript is a standard language (also known as ECMA Script) there are many web resources, online tutorials and books to help developers in writing JavaScript files. It is suggested that potential script writers read up on JavaScript resources before attempting to script the Alfresco repository.
A good general JavaScript reference can be found on the Mozilla site.
The integrated JavaScript engine in Alfresco utilises the Mozilla Rhino JavaScript Engine for Java. This allows JavaScript 1.6 (ECMA Script) files to access Alfresco Java objects using a simple bean-style notation and interpreted mode execution without compiling to external class files.
In Alfresco Version 2.1, a mechanism for adding and configuring additional scripting engines has been added. It is now possible to completely replace or augment the existing script engines with others such as PHP or Ruby. The correct scripting implementation will be automatically selected by the ScriptService when executing a script file based on the file extension of the script being executed. If it cannot resolve the engine to use, then the developer can specify it explicitly when calling the ScriptService. By default only JavaScript is available and this is the API documented here. However a Java-based PHP scripting engine is also provided as an additional AMP download.
Note: There are many example scripts illustrating the API in the JavaScript API Cookbook.
Scripts can currently be executed in two different ways:
JavaScript can also be used to build business logic for Workflow and also the new Web Scripts REST API in Alfresco 2.1.
Script files can be stored either on the ClassPath (for example, in alfresco/extension/myscripts) or in a repository store. Scripts are generally stored in the default repository in the Company Home/Data Dictionary/Scripts location. Scripts in this location can be accessed directly by users via the Execute a script action. Scripts in any repository location can be accessed by any user via REST URL if they have the appropriate read permissions on the script document. Scripts on the ClassPath can be imported into other scripts but not executed directly in the web client.
In Alfresco Version 2.1 the notion of including scripts into existing scripts was added. This feature allows libraries of scripts to be built and used by other scripts at runtime. The syntax to import the scripts is specific to Alfresco and not a feature of standard JavaScript. For example, the <script src='...'>
syntax you may be familiar with, as supported by most web browsers, is not part of standard ECMA JavaScript and will not work!
The syntax to import other scripts is strict and must be followed exactly or the import may fail. Import directives must be the first lines in the JavaScript file - no comment or code is allowed above those lines. Only the following syntax variants are supported:
Import a script from the repository via name based path:
<import resource='/Company Home/Data Dictionary/Scripts/library.js'>
Import a script from the repository via a NodeRef reference:
<import resource='workspace://SpacesStore/6f73de1b-d3b4-11db-80cb-112e6c2ea048'>
Import a script from a Java ClassPath location:
<import resource='classpath:alfresco/extension/myutils.js'>
Multiple script import of the same script content and circular dependencies are dealt with. A script can import several other scripts from multiple different locations, that is, a script from the repository and another from the classpath.
After the import lines, usual JavaScript code and comments may begin - the imports must be first lines in the file.
The Alfresco JavaScript API provides a rich set of scriptable Java objects that
are available to the script writer. Many 'root' scope objects are provided by
default, such as access to the user home folder, company home folder, WCM Web
Projects, search, People API and logging functionality. It is possible to
configure in additional root scope objects for use by your scripts, see the
section on adding custom Script APIs.
Most default root objects are known as Script Node objects that wrap the common Alfresco repository concepts such as nodes, aspects, associations, and properties. They also provide access to common services through an object-oriented API.
If you are accessing the script engine either through a rule/action (Execute a Script) in the Web Client or through the Script Command Processor then the following objects are available by default in the root scripting scope:
companyhome | The Company Home Script Node. |
---|---|
userhome | Current user Home Space Script Node. |
person | Script Node representing the current user Person object. |
space | The current space Script Node (if any). Note that for a script executing from a rule, the space object will be the space that the rule resides in, this may not be the space you are expecting if the rule is inherited. |
document | The current document Script Node (if any). |
script | The Script Node representing the script object itself. Not present if the script is loaded from the Java ClassPath. Other useful root scope objects provided by default. |
args | An associative array of any URL parameters passed via the Script Processor Servlet (only available if the script was executed via the script servlet). |
search | A host object providing access to Lucene and Saved Search results. See the Search API section. |
people | A host object providing access to Alfresco people and groups. See the People API section. |
actions | A host object providing invocation of registered Alfresco Actions. See the Actions API section. |
logger | A host object providing access to console logging facilities for debugging of scripts. See the Logging API section. |
session | Session related information such as the current authentication ticket. See the Session API section. |
classification | Access to the root elements of the classification API. See the Classification API section. |
utils | Access to a library of useful helper functions not provided as part of generic JavaScript. See the Utility Functions section. |
avm | Access to WCM objects such as AVM paths and searching within AVM stores and web projects. See the AVM API section. |
crossRepoCopy | Cross repository copy support. See the Cross Repository Copy section. |
The default model objects can be accessed directly from the root of a script scope and follow the standard JavaScript pattern of property dot notation style syntax, for example:
var name = userhome.properties.name
Here the variable name is populated by accessing the properties property and the name value within it.
The node children/association/aspect model is built dynamically as required. For example, you can write statements that walk multiple node collections such as:
userhome.children[1].children[0].children[2].name
The companyhome, userhome, document, space, and person objects represent Alfresco Node objects and provide access to the common Alfresco concepts such as properties, aspects, and associations. The following Node API is available to use within scripts:
var name1 = userhome.properties.name
var name2 = userhome.properties['name'];
var name3 = userhome.properties['cm:name'];
var name4 = userhome.properties['{http://www.alfresco.org/model/content/1.0}name'];
A useful feature is that properties of type d:noderef are automatically converted into another ScriptNode object. This means the script writer can dynamically walk the object hierarchy for a 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:
var locale = document.properties.locale.properties.name;
If you wish to retrieve the NodeRef value for a d:noderef property, then the following code will work:
var localeNoderef = document.properties.locale.nodeRef;
In addition, any properties of type d:content are converted to special ScriptContent objects that themselves feature an API to get or modify the content, mimetype, size and url for the content property. For example:
var mimetype = document.properties.content.mimetype;
var content = document.properties.content.content;
As most documents are derived from the default Content Model type cm:content, shortcut APIs are provided for content, mimetype, size and url for the cm:content property, for example:
document.content = 'some new text content';
var mimetype = document.mimetype;
var url = document.url;
Properties can be modified and new properties added, see the Modifying and Creating API section below.
children | A readonly JavaScript Array of the child nodes. For example mynode.children[0]. Note that since Alfresco 2.1, all methods that returns lists of data now return true JavaScript Array objects rather than simple Java lists. This means standard JavaScript 1.6 syntax for each and for each in can be used to iterate the results. |
---|---|
assocs | A readonly associative array (map) of the target associations of the node. Each named entry in the array contains an Array of the ScriptNode objects on the end of the association. For example: mynode.assocs['cm:translations'][0]. |
childAssocs | A readonly associative array (map) of the child associations of the node. Each named entry in the array contains an Array of the ScriptNode objects on the end of the association. For example:myforumnode.childAssocs['fm:discussion'][0]. |
aspects | A readonly array of the aspects (as fully qualified QName strings) applied to the node. (This is returned as a Java HashSet) |
isContainer | returns true if the node is a folder node, false otherwise. |
isDocument | Returns true if the node is a content node, false otherwise. |
content | The content of the node on the default cm:content property as a string value. This value can be modified to update the content of the node, see the Modifying and Creating API section below. |
url | The readonly url to the content stream for this node. |
downloadUrl | The readonly url to the content stream for this node as an HTTP1.1 attachment object. |
mimetype | The mimetype encoding for content on the default cm:content property attached to this node. |
size | the readonly size in bytes of content on the default cm:content property attached to this node. |
displayPath | The readonly display path to this node. NOTE: care must be taken when accessing the display path if the current user does not have permissions to view all of it. A fix has been made in Alfresco 2.1.1E so that the display path can always be obtained safely for any user. For example:
|
qnamePath | The readonly (qname) path to this node. (sorry, available 2.1 Enterprise onwards) For example:
|
icon16 | The readonly small icon image for this node. |
icon32 | The readonly large icon image for this node. |
isLocked | Return true if the node is locked. Otherwise, it is false. |
id | GUID for the node. |
nodeRef | NodeRef as a string for the node. |
name | Shortcut access to the cm:name property. |
type | Fully qualified QName type of the node. |
parent | The parent node, can be null if this is the root node. NOTE: care must be taken when accessing the parent node if the current user does not have permissions to view it. A fix has been made in Alfresco 2.1.1E so that the parent node can always be obtained to allow a hasPermission() check to be applied before accessing it in a script. |
isCategory | true if this is a category node and false otherwise. See the Classification API section. The following Node API functions are provided to help locate child nodes using an XPath or Name based path: |
Node childByNamePath (string path) | Performs an xpath based on the name property of the nodes and returns a Node found at the specified path. The path is relative to the current node. If the named node is found then it is returned, else null is returned. For example: var testingFolder = userhome.childByNamePath('QA/Performance/Testing');. |
Array childrenByXPath (string xpath) | Performs an xpath based query search and returns an array of the nodes found. The XPath search is relative to the current node. An empty array will be returned if no results are matched. For example: var nodes = userhome.childrenByXPath('*[@cm:name='Finance Documents']/*');. |
The following values are available but are only required for special use cases. You can safely ignore these if you do not know what they mean.
Most of the available ScriptNode API returns read-only values, however the real power of the scripting API can be found in the support for writable objects and access to Alfresco Repository services through this API. The ScriptNode object allows modification of properties, adding new properties, adding aspects, creating new files, folder, and custom type nodes, and of course, updating and setting the text content stream for a node. In addition, it is possible to perform powerful features such as deleting nodes, transforming content, executing templates, and modifying the associations for a node.
// change the name of this document
document.properties.name = 'Backup of ' + document.properties.name;
// add a new property string
document.properties['cm:locale'] = mylocalenode;
// save the property modifications
document.save();
Important: The node.save()
API call is needed to persist the property modifications - all other modifications made using the API (such as content or adding aspects) take immediate effect.
It is important to note that JavaScript objects are different to native repository Java objects. Property values in the repository must be of the correct object type as defined in the Data Dictionary and exposed by the content model. So a String property value expects a Java String and a multi-valued property expects a List. The Alfresco JavaScript API will perform the conversion of most object types between JavaScript and Java and visa-versa for you, for example Array (for a multi-value property), numbers, dates, boolean, and strings. The conversion code has been improved in Alfresco Version 2.1 and handles all common type conversions and recursive lists of those types.
var props = new Array(1);
props['cm:template'] = myTemplateNode.nodeRef;
document.addAspect('cm:templatable', props);
The ScriptContent API provides several functions and properties related to node properties of type d:content, for example, document.properties.content.
content | A read/write value that represents the content as a string. |
---|---|
write(ScriptContent content) | Copy the content from the specified ScriptContent (sorry, available from 2.1 Enterprise onwards). |
mimetype | A read/write string value that represents the mimetype of the content. |
encoding | A read/write string value that represents the encoding of the content. |
size | A readonly value that represents the size of the content. |
url | A readonly string representing the download url for the content. |
downloadUrl | A readonly string representing the download (as attachment) url for the content. |
The ScriptNode API features several functions and properties related to permissions in the repository. It is a common use case to check for the appropriate user permissions on a node before attempting to access or modify it.
org.alfresco.service.cmr.security.PermissionService
. Most commonly used permission checks are 'Read', 'Write', 'Delete' and 'CreateChildren'.The checkin/checkout ScriptNode API features methods for checkout, checkin and cancelling checkout of working copies. Note that you may wish to first add the cm:versionable aspect to a node if you wish version history to be recorded when using these methods.
The following ScriptNode functions make use of the document transformation services available in Alfresco. The OpenOffice server is required for some document transformations.
The following functions make use of the image transformation services available in Alfresco. The ImageMagick components will need to be installed correctly and working. Note that detailed information on the ImageMagick options mentioned in the methods below can be found on the ImageMagick website.
The following functions make use of the FreeMarker template processing services available in Alfresco. The result of the template execution is returned as a string from each function. Note that the node is used as the context to the template. If this node is a document, it will be setup as the 'document' context object for the template, with the parent space setup as the 'space' context object for the template, if it is a folder then it will be setup only as the 'space' context object for the template. An argument list can also be passed to the template - and will be available as the 'args' object, see Template Default Model page for more information on template models and the 'args' object.
The Search API provides direct access to repository level Lucene search results and Saved Search results. It is accessable via the 'search' root scope object. Note that local searches can be performed using the ScriptNode APIs childByNamePath and childByXPath as detailed above.
Like the various node objects, the search object is part of the root scope available to script writers. The API provides the following functions:
The People API provides access to Alfresco people and groups. The API provides the following functions:
Details of the API to workflow can be found in the Workflow documentation.
A root level object 'actions' is provided that allows invocation of Alfresco Actions registered with the Repository.
A ScriptAction represents an Alfresco Action registered within the Repository.
// create mail action
var mail = actions.create('mail');
mail.parameters.to = 'davidc@alfresco.com';
mail.parameters.subject = 'Hello from JavaScript';
mail.parameters.from = 'davidc@alfresco.com';
mail.parameters.template = roothome.childByNamePath('Company Home/Data Dictionary/Email Templates/notify_user_email.ftl');
mail.parameters.text = 'some text, in case template is not found';
// execute action against a document
mail.execute(doc);
A root level object 'logger' is provided that provides functions to aid debugging of scripts.
log4j.logger.org.alfresco.repo.jscript
should be set to DEBUG
. This can be applied in the log4j.properties file (TomCat) or log4j.xml file (JBoss) on the Alfresco server.A root level object 'session' is provided to access to the current logged in user session ticket as a string value.
There are two parts to the API: manipulating classifications and manipulating the categories that they contain. A root level object 'classification' is provided to return category nodes. The CategoryNode objects returned from the functions are extended from the standard JavaScript ScriptNode model to include category manipulation.
The CategoryNode object API.
{{AVMWarning}}
The Alfresco Versioning Machine (AVM) API provides access to Web Content Management (WCM) stores and their associated file and folder nodes. A WCM project is divided into 'stores' such as the Staging Store and various User Sandbox stores and the child nodes of these stores. The store contents has a well defined structure and developers should read the associated wiki pages to get familar with the structure and the naming convention used for staging and user stores.
The Store objects returned by the methods above have the following additional API:
The AVM specific node objects returned by the methods above extend the ScriptNode object as detailed above, they also have the following additional API:
A root level object 'crossRepoCopy' is provided to enable copy of nodes between document management spaces (ADM) and WCM spaces (AVM).
A root level object 'utils' is provided as a library of helper functions that are missing from generic JavaScript.
Example Scripts have been moved to JavaScript API Cookbook Page.
The Alfresco Server provides a built-in server-side Javascript debugger which allows line by line step through, variable inspection and arbitrary script execution.
Note:
To enable and disable the Javascript debugger use the following URL (you must be logged in as an administrator):
http://<host>:<port>/alfresco/service/api/javascript/debugger
This URL displays the current status of the debugger and allows you toggle between enabled and disabled.
When enabled, the Javascript Debugger window is displayed. Upon execution of any server-side Javascript, the debugger will intercept and stop execution at the first Javascript statement. You can then step through, view variables etc or resume execution. When disabled, server-side Javascript is executed without interruption.
The Script Service is a typical Alfresco repository service accessed via a Spring managed bean with the name of ScriptService.
Only developers will be interested in accessing the ScriptService directly, those more interested in simply writing scripts themselves should skip this section and jump to Scripting API.
The available scripting engines can be configured in the Alfresco Spring config file script-services-context.xml. You should download the Alfresco SDK to examine the structure of this file.
In Alfresco 2.1 a mechanism for adding additional scripting engines has been added. It is now possible to completely replace or augment the existing JavaScript implemenation with others such as PHP or Ruby. The correct script engine implementation will be automatically selected by the ScriptService when executing a script based on the file extension of the script being executed. If it cannot resolve the engine to use, then the developer can specify it explicitly when calling the ScriptService.
Further engines can be added by developers. Examining the script-services-context.xml for configuration examples. The engine must implement org.alfresco.service.cmr.repository.ScriptProcessor
interface and it is recommend to extend the org.alfresco.repo.processor.BaseProcessor
abstract class and override the various execute() methods.
A Java based PHP engine has been integrated and is a good example of this, it is available as an AMP download for addition into an existing Alfresco 2.1 installation.
It is possible to create and add custom script API's implemented in Java and accessible as root objects in JavaScript. This provides an integration point for Alfresco extensions to provide custom API's where appropriate.
In order to implement a custom JavaScript API it is recommended that you develop a POJO (Plain Old Java Object) that extends the base class org.alfresco.repo.processor.BaseProcessorExtension
. The public methods of your class will be those that will be accessable from JavaScript. (For example see org.alfresco.repo.jscript.ScriptLogger
).
Once complete, you must then configure your bean in Spring. Make use of the baseJavaScriptExtension parent bean definition in order to ensure your object is automatically registered with the ScriptService framework. The name of the object as it will appear to script writers must also be specified in the bean definition.
The following example shows the bean definition for the ScriptLogger custom API.
<bean id='loggerScript' parent='baseJavaScriptExtension' class='org.alfresco.repo.jscript.ScriptLogger'>
<property name='extensionName'>
<value>logger</value>
</property>
</bean>
Since this is a standard Spring bean definition any additional services that are required can be injected as properties into the bean definition in the usual way.
Once this bean have been loaded the custom API object will be accessible directly in JavaScript by calling the public methods on the named object. For example the following shows how the log method can be called on the logger API we have defined above.
...
logger.log('This is a log message.');
...
NOTE For a fully worked out example, please see our our content community.
In some cases, you may find that you're unable to satisfy a requirement using the Javascript API, but that a Java API (perhaps the Alfresco Foundation Services API or AVMService for our WCM module) contains facilities that would allow you to do so.
Using the method described in Adding Custom Script APIs, it is possible to add additional root scope objects to Javascript. In the case of the Alfresco Foundation Services API the only object that needs to be injected is the ServiceRegistry (or a proxy of it) - an example implementation of this may be found at Configuring the ServiceRegistry as a Javascript Root Object.
As of Alfresco 2.1.3, Javascript scripts stored in the classpath can also leverage the Rhino Javascript interpreter's native Java integration facilities (see the Rhino documentation for more details). For security reasons these mechanisms are completely disabled for Javascript scripts that are stored in the repository.
Note that there are some important things to keep in mind when calling native Java APIs from Javascript:
var value1 = javaMap['key1']
var value2 = javaMap.key2
You must call the underlying Java methods instead:
var value1 = javaMap.get('key1')
var value2 = javaMap.get('key2')
Please note that these techniques are solely intended for developers who wish to take advantage of the productivity benefits of a scripted language while still having access to the full power of native Java APIs. They should not be used for end user scripting scenarios (eg. end user developed custom actions uploaded to the repository, workflow scripts, etc.).
Return to Developer Guide