A Web Script contains 4 pieces:
- A descriptor file
- A Java Script (or a Java Class)
- A freemarker template
- Language bundles
Let's begin by investigating the Desctiptor file in detail. Such an descriptor contains:
- The short name (shortname)
- The description (description)
- The url by including the parameters (url)
- The default format
- The authentication method
Above you can see a Web Script which has the name 'Hello Word'. It 'Greets a user'. The URL is mapped to '/helloworld', whereby one Parameter 'to' is expected. The default response should be 'html' and a user authentication is required in order to execute the script. The value 'extension' means that the requested format is determined by the extension which is used as part of the URL. So for instance 'world.html' or 'world.txt'. As authentication the following values are possible: 'none', 'guest', 'user' or 'admin. Possible formats are: 'html', 'text', 'xml', 'atom', 'rss' or 'json'. There is an optional parameter which is named 'runas'. This parameter is used to execute the Web Script inside the context of another user's session. To be able to fully use this feature it is required that the Web Script is deployed in a static way. (We will talk about the deployment options later in this article.)<webscript> <shortname>Hello World</shortname> <description>Greet a user</description> <url>/helloworld?to={name?}</url> <url>/hello/world?to={name?}</url> <format default="html">extension</format> <authentication>user</authentication> </webscript>
What we need next is to investigate the Java Script file. There are specifc naming conventions. So a Java Script which is accessible via HTTP GET should have an Descriptor and a Java Script file which is named as the following:
- ${id}.${http method}.desc.xml
- ${id}.${http method}.js
The Java Script file can contain basic Java Script (or even Java because it is interpreted by a Java based engine) and calls of the Alfresco Java Script API. Let me give you a short overview about this API. It is even useful if you want to implement Actions or Workflows for the Alfresco System. You can think about this Java Script API like a built in language to access Content. If you know Procedural Languages for Database Systems, then you know what I mean. Indeed, the possibilities those are provided by this API are quite beyond the ones of for instance PL/SQL. So even if you are not a Java Script guy, it should be possible to use the API. There are multiple versios of the API available. This article focuses on the 3.4 one.
A script can import another one:
The example above shows a 'dynamic' import. Which means that the imported script is stored in Alfresco itself. It's also possible to just import from the classpath by using "classpath:${path to js}".
<import resource="/Company Home/Data Dictionary/Scripts/library.js">
The API provides some root objects. Those objects are available out of the box.
- companyhome: The company home root folder
- userhome: The current user's home folder
- person: The current user object
- search: The search API
- people: The people API
- actions: The action API
- logger: A logger
- session: Provides session specific information
- classification: The classification API
- utils: Some helpers
- groups: To access group authorities
- stites: The sites API
The Script Node API has the following important methods:
- properties
- children
- assocs
- aspects
- content
- id
- nodeRef
- name
- type
- parents
- childByNamePath
- getSite
The properties attribute is an associative array. You can access it by using 'node.properties.propx' or 'node.properties["propx"]'.
Beyond the Script Node API there is also the "Modify and Creating" API. Here some important methods:
- createFile
- createFolder
- createNode
- addNode (as child)
- removeNode (remove child assocs)
- createAssociation
- move
- copy
- addAspect
- checkout
- checkin
- cancelCheckout
- isVersioned
- versionHistory
- getVersion
- createdDate
- creator
- label
- type
- descrption
- nodeRef
- node
The content of the node was accessed by using the content attribute. This one provides the following API:
- mimetype
- encoding
- size
- url
- downloadURL
The search API allows you to search for specific documents. The following methods are part of the search API:
- luceneSearch
- xpathSearch
- savedSearch
- findNode (by given node reference)
- query (by using an object which consists a search method and the search query)
var query = {query: "SELECT e.* FROM ecg:mytype AS e WHERE e.ecg:myprop=" + myvar, language: "cmis-alfresco"};
The people API allows to handle users those are stored inside Alfresco. Here the methods of it:
- createPerson
- deletePerson
- getGroup
- createGroup
- parentGroup
- getMembers
- isAdmin
- changePassword
- setPassword
var myaction = create("myaction");The classification API provides the following methods:
myaction.parameters.myparam = 'myvalue';
myaction.execute;
- getAllCategoryNodes
- getAllClassificationAspects
- createRootCategory
- isCategory
- categoryMembers
- subCategories
- createSubCategory
- removeCategory
A special root object for Web Scripts is the one which is named 'model'. It allows you to set the result of the execution of you web script. Here an example:
var username = person.properties.userName;The model object is used to transfer data from the controlling Web Script to the Freemarker template. So let's take a closer look on Freemarker templates!
model.username = username;
Basically a freemarker template can be anything which is textual. So you can write it as html, as text as xml. The idea behind it is to use some static text with some dynamic text from the model. There is a whole language about this freemarker stuff. We just look on the most important parts:
- Place holders
- Data model
- Variables and Types
- Sequences
- Directives
- Comments
- Built-ins
The data model is a Tree and can be set. Every value which you access via a place holder is stored inside the data model. Everything which is not a leaf inside the data model's tree is named 'Hash'. The variables inside the tree those are storing single values (the leafs of the tree) are named 'Scalars'. You can navigate through the model's tree by using indexes. For instance 'animals[0].name'. Scalars are typed: String, Number, Date/Time, Boolean .
Sequences are lists of strings:
["myval1", ... , "myvaln"]
There are several directives. The 'if' directive looks as the following:
<#if myvar = "mystringval"> My text <#else> My other text </#if>Possible operators are: <, >, !=, = .
The list directive is used to itterate over elements of the data model.
<# list myhashvar as myvar> ${myvar.myscalarvar} </#list>
<# list myseq as myvar> ${myvar} </#list>
The include directive can be used to insert content from another file to the template:
<#include "/myfile.html">It is possible to create user defined directives the following way:
<@mydirective myparam1=myval1, ... myparamn=myvaln>
<#-- Some commands --#>
</@mydirective>Comments are used the following way:
<#-- My comment --#>The following built in functions are available:
- myvar!"My optional value": Uses the optional value if myvar is not set
- myvar??: Returns true if myvar is set
- myvar?upper_case: Returns the variable value in upper case letters
- myvar?cap_first: Converts the first letter to upper case
- myvar?trim
- myvar?size
- myvar?int: The integer part of a number (E.G. 5 in case of 5.432)
- myvar?string_short: Date to String conversion
- myvar?foo:string : Boolean to Strng conversion
Let's now investigate how multiple languages are supported. The default message bundle is a properties-file with the following name:
- ${id}.${http method}.properties
- ${id}.${method}_${locale}.properties
${msg("myprop")}So the final question of this article is: How can I deploy and use such a Web Script. There are multiple ways to deploy a web script:
- Dynamic deployment: To the Content Repository itself. Which mean you need to import it to 'Data Dictionary/Web Scripts' or 'Data Dictionary/Web Script Extensions' (The second folder should be used to override scripts from the first folder for testing purposes.)
- Static deployment by copying the folder which contains the Web Script files to ${CATALINA_HOME}/webapps/alfresco/WEB-INF/classes/alfresco/templates/webscripts. This can be simplified by bundling the Web Script into an Alfresco Module Package.
- Extension deployment by copying the folder which contains the Web Script files to ${CATALINA_HOME}/shared/classes/alfresco/extension/templates/webscripts
- Navigate to 'http://${myhost}:8080/alfresco/service/index'
- Click on the 'Refresh Web Scripts' button
very intersting for us
ReplyDelete