Alfresco Share provides a rich web-based collaboration environment for managing documents, wiki content, blogs and more. Share leverages the repository to provide content services and uses the Surf platform to provide the underlying presentation framework.
A number of options are available to developers and administrators for configuring Share to better fit into their environment. Many of these mechanisms are provided by the underlying Surf framework, therefore a knowledge ofSurf is considered useful for anyone wishing to implement substantial customizations.
A lot of the customizations that you might want to do to the Share user interface does not require coding. They can be handled by XML configuration and a simple restart of Content Services.
Architecture Information:Share Architecture
The configurations typically goes into theshare-config-custom.xml file. The following is an example of stuff that you can configure in this file:
Note that a lot of the other extension points that require coding also involve configuration, so it is a good idea to read up on the configuration bit before starting any development with the other extension points.
Share can be configured through a number of configuration files.
The main Share configuration file isshare-config.xml. This can be found attomcat/webapps/share/WEB-INF/classes/alfresco/share-config.xml. While it is possible to change configuration through direct changes to this file this is not recommended as any customizations will be lost if the Share WAR is re-exploded, or you install a new version of Content Services.
To get around this issue it is advisable to make configuration changes to a file outside of the Share WAR. This can be done through the fileshare-config-custom.xml, which can be found attomcat/shared/classes/alfresco/web-extension/share-config-custom.xmlin the default Alfresco installation. Any changes made here will be applied once the changes have been saved, and Content Services restarted. Further, your configuration changes can be saved between reinstalls and if the Share WAR re-explodes at any point your configuration file will be unaffected.
Note: If you are overriding a configuration section, you must apply the
replace="true"attribute to replace the existing Content Services configuration.
It should also be noted that it is possible to package ashare-config-custom.xml file in a JAR or AMP. In this way you can have multipleshare-config-custom.xml files packaged in JARs or AMPs if necessary. JARs will be loaded from the classpath, for example./tomcat/shared/lib. AMPs will be applied to the Share WAR file.
CAUTION: The order in which multiple
share-config-custom.xmlfiles are applied is not guaranteed in the case where multiple files override the same section of configuration.
Another key Share configuration file isslingshot-application-context.xml which can be found attomcat/webapps/share/WEB-INF/classes/alfresco/slingshot-application-context.xml in the default Alfresco installation. This loads a number of other configuration files:
<!-- Spring Web Scripts --><value>classpath:org/springframework/extensions/webscripts/spring-webscripts-config.xml</value><value>classpath:META-INF/spring-webscripts-config-custom.xml</value><value>jar:*!/META-INF/spring-webscripts-config-custom.xml</value><!-- Alfresco Surf --><value>classpath:org/springframework/extensions/surf/spring-surf-config.xml</value><value>classpath:org/springframework/extensions/surf/spring-surf-config-remote.xml</value><value>classpath:META-INF/spring-surf-config-custom.xml</value><value>jar:*!/META-INF/spring-surf-config-custom.xml</value><!-- Surf Autowire Support --><value>webapp:WEB-INF/surf.xml</value><!-- Common form config --><value>classpath:alfresco/form-config.xml</value><!-- Share default config --><value>classpath:alfresco/share-config.xml</value><!-- Share help url config --><value>classpath:alfresco/share-help-config.xml</value><!-- Share form config --><value>classpath:alfresco/share-form-config.xml</value><!-- Share Document Library config --><value>classpath:alfresco/share-documentlibrary-config.xml</value><!-- Share Data List form config --><value>classpath:alfresco/share-datalist-form-config.xml</value><!-- Share workflow form config --><value>classpath:alfresco/share-workflow-form-config.xml</value><!-- Share CMIS config --><value>classpath:alfresco/share-cmis-config.xml</value><!-- Share Security config --><value>classpath:alfresco/share-security-config.xml</value><!-- Share custom config --><value>classpath:alfresco/web-extension/share-config-custom.xml</value><value>jar:*!/META-INF/share-config-custom.xml</value><value>classpath:alfresco/web-extension/share-config-custom-dev.xml</value><value>jar:*!/META-INF/share-config-custom-dev.xml</value>Note that the custom configuration files are loaded last, so that they can override existing configuration.
CAUTION: configuration files with the same base file name must have different effective paths in order to be loaded. For example, if you tried to load
classes/alfresco/web-extension/share-config-custom.xmlandWEB-INF/classes/alfresco/web-extension/share-config-custom.xml, only one of them would be loaded, as these both have the effective pathalfresco/web-extension/share-config-custom.xml. Note that where files are loaded from multiple JAR files, such as through<value>jar:*!/META-INF/share-config-custom.xml</value>, they have different effective paths, and so multiple configuration files with the same base file name can be successfully loaded in this case.
The following table summarizes the main Share configuration files:
| Configuration file | Description | Location |
|---|---|---|
| share-config.xml | Default Share configuration file. | classpath:alfresco |
| slingshot-application-context.xml | Spring beans file which also loads various configuration files. | tomcat/webapps/share/WEB-INF/classes/alfresco |
| share-form-config.xml | Default configuration for thecm:content andcm:folder forms. | classpath:alfresco |
| share-datalist-form-config.xml | Default configuration for datalists. | classpath:alfresco |
| share-documentlibrary-config.xml | Default configuration for the document library, my files, shared files and repository pages. | classpath:alfresco |
| share-workflow-config.xml | Default configuration file for the Alfresco Process Services Workflow forms. | classpath:alfresco |
Note: Usually, once you have changed a configuration file, you will need to restart Content Services for the changes to take effect.
This information describes how to change the minimum length of the Share user name and password.
Open the<web-extension>/share-config-custom.xml file.
Search for the text “username”. You see the following configuration:
<config evaluator="string-compare" condition="Users"> <users> <!-- minimum length for username and password --> <username-min-length>2</username-min-length> <password-min-length>3</password-min-length> </users></config>Change the value of<username-min-length> and<password-min-length>.
When there is a mix of username types, for example, some using the@domain in their username, this may have an impact on the use of Share.
For example, there may be users with both the@domain and without:
user2@domain.comuser1This configuration enables Share to function correctly when using mixed users types.
Open the<web-extension>/share-config-custom.xml file.
Add the following bean:
<bean parent="webframework.sitedata.persister.abstract"> <property name="store" ref="webframework.webapp.store.remote" /> <property name="pathPrefix"><value>alfresco/site-data/${objectTypeIds}</value></property> <property name="tenantObjectCache"><value>false</value></property></bean>Save the file, and restart the Alfresco server.
Use this information to configure the default port configuration for Share.
Open the<web-extension>/share-config-custom.xml file.
Uncomment the following section by removing the begin comment<-- and end comment--> lines surrounding this section.
<config evaluator="string-compare" condition="Remote"> <remote> <endpoint> <id>alfresco-noauth</id> <name>Alfresco - unauthenticated access</name> <description>Access to Alfresco Repository WebScripts that do not require authentication</description> <connector-id>alfresco</connector-id> <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url> <identity>none</identity> </endpoint> <endpoint> <id>alfresco</id> <name>Alfresco - user access</name> <description>Access to Alfresco Repository WebScripts that require user authentication</description> <connector-id>alfresco</connector-id> <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url> <identity>user</identity> </endpoint> <endpoint> <id>alfresco-feed</id> <name>Alfresco Feed</name> <description>Alfresco Feed - supports basic HTTP authentication via the EndPointProxyServlet</description> <connector-id>http</connector-id> <endpoint-url>http://localhost:8080/alfresco/s</endpoint-url> <basic-auth>true</basic-auth> <identity>user</identity> </endpoint> <endpoint> <id>alfresco-api</id> <parent-id>alfresco</parent-id> <name>Alfresco Public API - user access</name> <description>Access to Alfresco Repository Public API that require user authentication. This makes use of the authentication that is provided by parent 'alfresco' endpoint.</description> <connector-id>alfresco</connector-id> <endpoint-url>http://localhost:8080/alfresco/api</endpoint-url> <identity>user</identity> </endpoint> </remote></config>Uncomment the following section if you are using Kerberos, or external SSO, or an HTTP load balancer.
<config evaluator="string-compare" condition="Remote"> <remote> <ssl-config> <keystore-path>alfresco/web-extension/alfresco-system.p12</keystore-path> <keystore-type>pkcs12</keystore-type> <keystore-password> alfresco-system</keystore-password> <truststore-path> alfresco/web-extension/ssl-truststore</truststore-path> <truststore-type>JCEKS</truststore-type> <truststore-password>password</truststore-password> <verify-hostname>true</verify-hostname> </ssl-config> <connector> <id>alfrescoCookie</id> <name>Alfresco Connector</name> <description>Connects to an Alfresco instance using cookie-based authentication</description> <class>org.alfresco.web.site.servlet.SlingshotAlfrescoConnector</class> </connector> <endpoint> <id>alfresco</id> <name>Alfresco - user access</name> <description>Access to Alfresco Repository WebScripts that require user authentication</description> <connector-id>alfrescoCookie</connector-id> <endpoint-url>http://localhost:8080/alfresco/wcs</endpoint-url> <identity>user</identity> <external-auth>true</external-auth> </endpoint> <endpoint> <id>alfresco-api</id> <parent-id>alfresco</parent-id> <name>Alfresco Public API - user access</name> <description>Access to Alfresco Repository Public API that require user authentication. This makes use of the authentication that is provided by parent 'alfresco' endpoint.</description> <connector-id>alfresco</connector-id> <endpoint-url>http://localhost:8080/alfresco/api</endpoint-url> <identity>user</identity> <external-auth>true</external-auth> </endpoint> </remote> </config>Replace all instances of 8080 with the required port number.
Save the file.
Use this information to turn off cookies that store a username after a session expires.
By default, a cookie is stored that allows you to repopulate the user name after a user logs out, or the session expires. Follow these instructions if you do not want this user name stored.
Open the following file:tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml
Set theenableCookie property tofalse.
<config evaluator="string-compare" condition="Cookie" replace="true"> <cookie> <enableCookie>false</enableCookie> </cookie></config>and disable the login cookie:
<config evaluator="string-compare" condition="WebFramework"> <web-framework> <defaults> <login-cookies-enabled>false</login-cookies-enabled> </defaults> </web-framework></config>Save the edited file.
Restart Alfresco.
Share actions are disabled by default when using Smart Folders in Content Services.
If you need to enable Share actions, these must be explicitly set in the following files:
<configRootShare>/classes/alfresco/share-documentlibrary-config.xml: these are Share standard defaults, do not modify them<classpathRoot>/alfresco/web-extension/share-config-custom.xml: for standard Share actions<classpathRoot>/alfresco/web-extension/smartfolders-amp-actions-config.xml: for custom module actions and Google DocsFor example:
<action index="100" appendEvaluators="true"> <evaluator>evaluator.doclib.action.DocumentEnableInSmartFolder</evaluator> </action>In each file, you can find the new evaluators to enable actions in theactionGroups section:
DocumentEnableInSmartFolder: enable action for documents in a Smart FolderFolderEnableInSmartFolder: enable action for folders in a Smart FolderSmartFolderEnable: enable action for Smart FoldersFolderAndSmartFolderEnable: enable action for folders and Smart FoldersAction limitations on Smart Folders include:
The External Users panel is disabled by default in Alfresco Share. Use this information to enable this panel to add external users.
Open the<web-extension>/share-config-custom.xml file.
Add the following section to theshare-config-custom.xml file.
<config evaluator="string-compare" condition="Users" replace="true"> <enable-external-users-panel>true</enable-external-users-panel></config>This implementation enables the External Users panel in the Share user interface.
Note: External users are a way for users without Administrator permissions to add a user to Content Services. When they accept the invite they will have the same access as a standard user, and will be counted against licensing.
The Share document library is a feature that gives full access to the Content Services repository.
The default content structure for Share is based on sites, and this does not give full visibility of the content in the repository. By enabling the document library configuration setting, you have access to multiple navigation options, for example, folders and categories, tags, and filters. This feature also allows you to recreate and edit text files, for example, within the Data Dictionary.
It is possible to copy or move files to the document library without any repository permissions.
The document library is accessed in Share through theRepository,My Files, andShared Files links in the header, and through theDocument Library link in a site. These all kind different views of the complete content repository.
It is possible to control the visibility of theRepository link in Share through configuration. Note theRepository link is always visible to Administrators.
Load the filetomcat/shared/classes/alfresco/web-extension/share-config-custom.xml into your favorite editor (assuming you are using the Tomcat application server).
Locate theRepository Library config section:
<!-- Repository Library config section --> <config evaluator="string-compare" condition="RepositoryLibrary" replace="true"> <!-- Root nodeRef or xpath expression for top-level folder. e.g. alfresco://user/home, /app:company_home/st:sites/cm:site1 If using an xpath expression, ensure it is properly ISO9075 encoded here. --> <root-node>alfresco://company/home</root-node> <tree> <!-- Whether the folder Tree component should enumerate child folders or not. This is a relatively expensive operation, so should be set to "false" for Repositories with broad folder structures. --> <evaluate-child-folders>false</evaluate-child-folders> <!-- Optionally limit the number of folders shown in treeview throughout Share. --> <maximum-folder-count>500</maximum-folder-count> </tree> <!-- Whether the link to the Repository Library appears in the header component or not. --> <visible>true</visible> </config>The configuration that can make theRepository link visible or invisible for non-administrators is the following:
<visible>false</visible>Set totrue to have the Repository link available to all users.
Restart the Content Services server.
Aspects can be configured in the file./tomcat/webapps/share/WEB-INF/classes/alfresco/share-documentlibrary-config.xml.
Aspects can be added to any document in the repository. Examples of aspects includetaggable,exif, andversionable. There are many others. Each aspect can be configured as visible, hidden, addable, and removable.
Load the fileshare-documentlibrary-config.xml into your favorite editor.
Search for the text “aspects”. You will find the following configuration:
<!-- Used by the "Manage Aspects" action and Rules pages For custom aspects, remember to also add the relevant i18n string(s) aspect.cm_myaspect=My Aspect --> <aspects> <!-- Aspects that a user can see in UI. Used by Rules, aspects are the listed aspects for rule's "has-aspect" action condition. --> <visible> <aspect name="cm:generalclassifiable" /> <aspect name="cm:complianceable" /> <aspect name="cm:dublincore" /> <aspect name="cm:effectivity" /> <aspect name="cm:summarizable" /> <aspect name="cm:versionable" /> <aspect name="cm:templatable" /> <aspect name="cm:emailed" /> <aspect name="emailserver:aliasable" /> <aspect name="cm:taggable" /> <aspect name="app:inlineeditable" /> <aspect name="cm:geographic" /> <aspect name="exif:exif" /> <aspect name="audio:audio" /> <aspect name="cm:indexControl" /> <aspect name="dp:restrictable" /> </visible> <!-- Aspects that a user can add in UI. Used by Rules, aspects are the listed aspects for rule's "add-features" action. Same as "visible" if left empty. --> <addable> </addable> <!-- Aspects that a user can remove in UI. Used by Rules, aspects are the listed aspects for rule's "remove-features" action. Same as "visible" if left empty --> <removeable> </removeable> </aspects>Modify the configuration of aspects as required.
You have seen how to configure aspects via the document library configuration file. You can also add similar configurations toshare-config-custom.xml.
Alfresco Share offers a number of extension points for the document library.
This includes:
This documentation also includes ajsNode client-side help object reference and a list of out-of-the-box evaluators.
In order to preserve existing customizations and third party add-ons, a parallel set of data web scripts has been developed to coexist with the previous data web scripts. These web scripts are located in theremote-api project and have URLs starting with/slingshot/doclib2/.
There are three extension points supported by the repository data web scripts.
A custom response appears within themetadata.custom section of the JSON response. An example of a cleanly installed service is thevtiServer configuration, defined within the slingshot-context.xml file.
ThecustomResponses property defines a map of JSON key to custom response bean within theSlingshotDocLibCustomerResponse bean definition.
DefaultslingshotDocLibCustomResponse bean configuration:
<bean parent="baseJavaScriptExtension" > <property name="extensionName"> <value>slingshotDocLib</value> </property> <property name="<b>customResponses</b>"> <map> <entry key="vtiServer"> <ref bean="doclibCustomVtiServer"/> </entry> </map> </property></bean>The bean for returning thevtiServer configuration is defined as:
<bean> <property name="scriptUtils"> <ref bean="utilsScript" /> </property> <property name="sysAdminParams"> <ref bean="sysAdminParams" /> </property> <property name="port"> <value>${vti.server.external.port}</value> </property> <property name="host"> <value>${vti.server.external.host}</value> </property></bean>TheVtiServerCustomResponse class (which implementsCustomResponse) returns a Serializable object (for example aLinkedHashMap) that is serialized into the JSON response by the DocLib web scripts.
This extension point is designed to return useful information that is not specific to any node, for example, the presence of an optional module; whether a subsystem is active or not, etc.
The other place the data web scripts may be extended is via the property decorator extension mechanism.
To add a new property decorator, the baseDecorator bean needs to be extended with the property decorator you wish to use. For example:
<bean parent="baseDecorator"> <property name="nodeService" ref="nodeService"/> <property name="personService" ref="PersonService" /> <property name="propertyNames"> <set> <value>ds:uploader</value> </set> </property></bean>The third place the data web script response can be extended is by using the list of permissions that are returned for each node. These are defined by using theuserPermissions property on theapplicationScriptUtils bean. For example:
<property name="<b>userPermissions</b>"> <list> <value>CancelCheckOut</value> <value>ChangePermissions</value> <value>CreateChildren</value> <value>Delete</value> <value>Write</value> </list></property>The default set of permissions should not be reduced without fully understanding the impact on actions, indicators, and metadata evaluators already in use throughout Share.
In versions of Alfresco Share previous to 4.0, the client-side JavaScript requested JSON data from the repository directly by using the proxy servlet. From 4.0 onwards, there is a new data web script (at/components/documentlibrary/data/) that requests data from the repository and processes the response based on a configurable set of evaluators before finally returning JSON data to the browser.
All configuration for, and evaluation of, Document Library status indicators, metadata templates, and actions is on the web tier instead of split between the repository and the browser.
The individual action configuration files (for exampledocumentlist.get.config.xml,document-details.get.config.xml) have been removed and all actions are now defined within common configuration sections.
The new or altered areas of configuration inshare-documentlibrary-config.xml are:
<indicators> section for configuring status indicators<metadata templates> for configuring the metadata displayed within the Document Library’s “browse” view<actions> section defining all available actions across the various Document Library view pages<actionGroups> that define which (and in what order) actions are to appear on the Document Library pages<dependencies> section for defining custom client-side functionality and stylesheetsTheslingshot-documentlibrary-context.xml file contains all bean definitions for web tier evaluators.
Defined within theDocumentLibrary config section, status indicators are small icons typically used to indicate the presence of a marker aspect, or whether a document is in a particular state, for example checked out for editing.
(
Indicator images by default are referenced by id:/res/components/documentlibrary/indicators/{id}-16.png unless the name is overridden by the “icon” attribute. Tooltip labels are also defaulted by id:status.{id} and can be overridden by thelabel attribute.
The status indicators are located in the<indicators> config container element with the following structure:
<indicator id (index) (icon) (label)> <evaluator /> <labelParam index /> <override /></indicator>where:
<indicator>: Status indicator element with the following attributes:id: Unique indicator idindex: Determines display order of this indicatoricon: Icon filename; if not specified,id is usedlabel: Tooltip i18 label; if not specified,id is used<evaluator>: Bean id of evaluator that determines the visibility of the image. The Evaluator extendsorg.alfresco.web.evaluator.BaseEvaluator<labelParam>: Allows placeholder values within i18n label to be replace at runtime with node properties. The value is the replacement string or dot notation path to a node property. The attribute is:index: Index of placeholder value with i18n message.<override>: Allows this indicator to override (hide) other indicators that would otherwise be visible. The value is the id of another indicator to override.Example config
<config evaluator="string-compare" condition="DocumentLibrary">... <indicator index="10"> <evaluator>evaluator.doclib.indicator.googleDocsLocked</evaluator> <labelParam index="0">{jsNode.properties.owner.displayName}</labelParam> <labelParam index="1">{jsNode.properties.owner.userName}</labelParam> <override>locked</override> </indicator></config>A note about thelabelParamvalue: refactoring on the client-side (JavaScript code) means that a common helper object is available for each node within the Document Library during the rendering cycle, namelyjsNode. A full reference for this new resource is injsNode reference.
The metadata template refers to the section of the document “browse” page under the file name. This area can be customized with node properties and/or by custom rendering functions.

In a clean install, there are two templates defined: thedefault (fallback) template and one used when rendering working copies. These are both defined withinshare-documentlibrary-config.xml and can be extended or overridden as required (by usingshare-config-custom.xml).
The metadata templates are located in the<metadata-templates> config container element with the following structure:
<template id> <evaluator /> <line id (index) (simpleView) (evaluator) /> <override /></template>where:
<template>: Template element with the following attribute:id: Unique template id<evaluator>: Bean id of evaluator that determines whether the template is to be used for this node or not. The Evaluator extendsorg.alfresco.web.evaluator.BaseEvaluator<line>: Allows placeholder values within i18n label to be replace at runtime with node properties. The value refers either to a node property (such ascm_description) or a customer JavaScript renderer. To add a label in front of the property, add the label’s i18n messageId after the property value, separated by a space (such as {cm_description details.description}. The attributes are:id: Id of the line within the template. Must be unique within this template.index: Optional index for ordering the lines when rendering.view: If set to “simple” or “detailed”, then this line will only be rendered when either the simple or detailed view is toggled on, respectively. Leave empty, or omit the attribute for both views.evaluator: Optional evaluator to determine whether this line will be rendered for a node when using the template.Example config
<config evaluator="string-compare" condition="DocumentLibrary">... <template> <evaluator>evaluator.doclib.metadata.hasExif</evaluator> <line index="10" view="detailed">{date}{size}</line> <line index="20" evaluator="evaluator.doclib.metadata.hasExposure"> {exposure exif.label.exposure} </line> <line index="30" view="detailed">{description}</line> <line index="40" view="detailed">{social}</line> </template></config>Custom JavaScript renderers
A renderer can either be a simple property value, or use a custom JavaScript renderer. To register a custom renderer, fire a Bubbling (global) event, passing-in the renderer id and the rendering function:
if (Alfresco.DocumentList){ YAHOO.Bubbling.fire("registerRenderer", { propertyName: "renderer id", renderer: function(record, label) { return "..."; } });}The rendering function should return property escaped HTML.
Actions are defined globally in theshare-documentlibrary-config.xml file, in theDocLibActions config section. This means they can be overridden and extended by using ashare-config-custom.xml file. These customizations can be by using the AMP, JAR or web-extension folder mechanism, or a mixture of all three.
Actions are also now grouped by view type instead of node “state”.

The actions are located in the<actions> config container element with the following structure:
<action id type (icon) label> <param name /> <evaluator negate /> <permissions> <permissions allow /> </permissions> <override /> </action>where:
<action>: Action config container element with the following attributes:id: Unique action idtype: Action type. Javascript, link, and pagelink are supportedicon: Optionally, override the icon name. If not set, the ID is usedlabel: The action’s i18n message ID<param>: Action parameter elements with the following attribute:name: Parameter name<evaluator>: Bean ID of evaluator that determines whether the action is valid for this node or not. Evaluator extendsorg.alfresco.web.evaluator.BaseEvaluator and contains the following attribute:negate: If set totrue, the output of the evaluator is inverted.<permissions>: Permission config container element.<permission>: List of permissions required for the actions, as defined in theapplicationScriptUtils bean config with the following attributes:allow: If the permission specifies, the action is allowed.deny: If the permission specifies, the action is hidden.<override>: If this action should override the visibility of other actions, they are specified using this element.Example config
<config evaluator="string-compare" condition="DocLibActions">... <!-- Inline edit --> <action type="pagelink" label="actions.document.inline-edit"> <param name="page">inline-edit?nodeRef={node.nodeRef}</param> <permissions> <permission allow="true">Write</permission> </permissions> <evaluator>evaluator.doclib.action.inlineEdit</evaluator> </action></config><!-- Checkin from Google Docs --><config evaluator="string-compare" condition="DocLibActions">... <action type="javascript" label="actions.document.checkin-google"> <param name="function">onActionCheckinFromGoogleDocs</param> <evaluator>evaluator.doclib.action.googleDocsCheckIn</evaluator> <override>document-checkout-to-googledocs</override> </action></config>An action can be disabled across the whole application using the following configuration. For example the following config removes the “Upload New Version” action from users.
<config evaluator="string-compare" condition="DocLibActions">... <actions> <action> <evaluator>evaluator.doclib.action.disableAction</evaluator> </action> </actions></config>Add an evaluator, used on an out-of-the-box action:
<config evaluator="string-compare" condition="DocLibActions"> <actions> <action> <evaluator negate="true">wcmqs.evaluator.doclib.action.isWebsiteContainerType</evaluator> </action> </actions></config>Actions are grouped using theactionGroup elements. The type of node and also the view currently in use determines the actual group used. The group is calculated by thecalculateActionGroupId() function insurf-doclist.lib.js and is designed to be overridden if many new and/or altered actions are required.
The action groups defined in a default installation are:
| Action Group ID | Default Usage |
|---|---|
| document-browse | Documents on the browse page |
| document-details | Document on the document details page |
| folder-browse | Folders on the browse page |
| folder-details | Folders on the folder details page |
| document-link-browse | Links to documents on the browse page |
| document-link-details | Links to folders on the document details page |
| folder-link-browse | Links to folders on the browse page |
| folder-link-details | Links to folders on the folder details page |
The action groups are located in the<actionGroups> config container element with the following structure:
<actionGroup id> <action /> </actionGroup>where:
<actionGroup>: Action group config container element with the following attribute:id: Unique action group ID<action>: Action element with the following mandatory attribute:id: Reference to action as defined in<actions> config sectionOther actions properties can be overridden here, although it is recommended from a maintenance view to only override “simple” properties like the icon and label. These make it possible to reuse an action with document-biased icon and label to be used for folders.
Example config
<config evaluator="string-compare" condition="DocLibActions">... <actionGroup> <action index="100" /> <action index="110" icon="folder-edit-properties" /> <label="actions.folder.edit-metadata" /> </actionGroup></config>TheDocLibCustom config section is where dependencies on custom client-side assets can be defined. These are defined in exactly the same way as for custom Forms dependencies.
The client-side dependencies are located in the<dependencies> config container element with the following structure:
<css src /> <js src />where:
<css>: Stylesheet dependencies element with the following attribute:src: Path to the css file, relative to the/res servlet<js>: JavaScript dependencies element with the following attribute:src: Path to the js file, relative to the/res servletOther actions properties can be overridden here, although it is recommended from a maintenance point of view to only override “simple” properties like the icon and label. These make it possible to reuse an action with document-biased icon and label to be used for folders.
Example config
<config evaluator="string-compare" condition="DocLibCustom"> <dependencies> <css src="/custom/my-customization.css" /> <js src="/custom/my-customization.js" /> </dependencies></config>Two global events are available to make it easier to add new metadata template renderers and client-side action handlers.
Custom client renderers are registered with the Document Library using the newregisterRenderer Bubbling event.
Ensure the client-side assets are loaded onto the page using theDocLibCustom / dependencies configuration section.
Using the example to add a new EXIF metadata renderer to produce the output as follows.

Giving the renderer anid of exposure also extends the metadata templates using a custom line config:
<line index="20">{exposure exif.label.exposure}</line>The JavaScript to register the custom renderer is then as follows. Note the event name, the event property names and where the custom renderer id is specified.
YAHOO.Bubbling.fire("registerRenderer",{ propertyName: "exposure", renderer: function exif_renderer(record, label) { ... return html; } });SeeEXIF renderer source code for the complete source for this example.
In a very similar way to metadata renderers, new client-side actions are registered using theregisterAction Bubbling event message.
YAHOO.Bubbling.fire("**registerAction**",{ actionName: "onActionPreviewWebAsset", fn: function WCMQS_onActionPreviewWebAsset(record) { ... }});Within the document library it is possible to select from a number of views. It is also possible to add custom views to the document library through configuration in theshare-documentlibrary-config.xml file.
When browsing content in the document library it is possible to select from a variety of views including:
These views are selected from theOptions button.
Theshare-documentlibrary-config.xml file controls what views will be available as options when browsing the Document Library, My Files, Shared Files, and repository pages. It is also possible to use a module that provides evaluated configuration to have the options change based on criteria such as site name, site preset, user group, and so on.
It is possible to customize these views, and also add additional view types through configuration in theshare-documentlibrary-config.xml file. These views are also present in the My Files, Shared Files and repository pages.
The views are rendered by view renderers, which have various attributes and also a block of configuration (in JSON) associated with them. For example:
<view-renderer iconClass="table" label="button.view.email" index="50" widget="Alfresco.DocumentListTableViewRenderer"> <dependencies> <js src="components/documentlibrary/documentlist-view-detailed.js" /> <js src="components/documentlibrary/documentlist-view-table.js" /> <css src="components/documentlibrary/documentlist-view-table.css" /> </dependencies> <json-config> { "actions": { "show": "true" }, "indicators": { "show": "true" }, "selector": { "show": "true" }, "thumbnail": { "show": "false" }, "propertyColumns": [ { "property": "cm:originator", "label": "table.email.label.originator", "link": "true" }, { "property": "cm:subjectline", "label": "table.email.label.subjectline", "link": "true" }, { "property": "cm:sentdate", "label": "table.email.label.sentdate" }, { "property": "cm:addressee", "label": "table.email.label.addressee" }, { "property": "cm:addressees", "label": "table.email.label.addressees" }, { "property": "cm:attachments", "label": "table.email.label.attachments" } ] } </json-config> </view-renderer>The following snippet shows a custom simplified view called “minimalist”:
<view-renderer iconClass="table" label="button.view.minimalist" index="60" widget="Alfresco.DocumentListTableViewRenderer"> <dependencies> <js src="components/documentlibrary/documentlist-view-simple.js" /> <js src="components/documentlibrary/documentlist-view-table.js" /> <css src="components/documentlibrary/documentlist-view-table.css" /> </dependencies> <json-config> { "actions": { "show": "false" }, "indicators": { "show": "false" }, "selector": { "show": "true" }, "thumbnail": { "show": "false" }, "propertyColumns": [ { "property": "cm:name", "label": "table.minimalist.label.name", "link": "true" } ] } </json-config> </view-renderer>Note that the value of labels such astable.minimalist.label.name are set in properties files, so that multiple translations can be provided.
The minimalist custom view uses the Table View renderer.
There are four columns that are always present in the table, which can be hidden if required:
All other columns must be defined in thepropertyColumns array. The property attribute can be set to either a document property, such ascm:name or a metadata template renderer such assize,tags ordate.
When you run Share, the look and feel is set by a default theme. Use this information to select one of the alternative themes available in Share, and also how to create and use your own themes for corporate branding.
Share themes consist of a directory containing a CSS and images files, and they can be located in the theme directory (<TOMCAT_HOME>/webapps/share/WEB-INF/classes/alfresco/site-data/themes). The default theme is called default.xml.
The following themes are available:
The default theme, which comprises the CSS and image assets used across all pages, displays in a new installation.
You can also create your own themes. Take a look at theShare Theme Extension Point and theAdding a custom Share Theme tutorial.
Only an Administrator user can select the Share theme. Any change to the theme will affect all users of the Content Services instance from the next time that they log in or from a browser refresh.
The available themes are installed in the<configRootShare>/classes/alfresco/site-data/themes directory.
On the toolbar, select theAdmin Tools menu option and clickApplication in the Tools list.
The Options page appears.
Select the required theme from the menu:
ClickApply.
The new theme displays in Share. The new theme persists across sessions.
A theme consists of some CSS files, an image directory, and a directory for assets for YUI. To create a new look, change the presentation.css file and, if required, replace or add images to the/images directory.
Open thepresentation.css file.
Locate the properties at the end of thepresentation.css file.
Edit the following four properties:
colorbackgroundbackground-colorborderAny change to these properties will change the theme.
/ Theme colors /.theme-color-1,a.theme-color-1,a.theme-color-1:visited,a.theme-color-1:hover{ color: #6CA5CE;} .theme-color-2,a.theme-color-2,a.theme-color-2:visited,a.theme-color-2:hover{ color: #038603;} .theme-color-3,a.theme-color-3,a.theme-color-3:visited,a.theme-color-3:hover{ color: #C7DBEB;} .theme-color-4,a.theme-color-4,a.theme-color-4:visited,a.theme-color-4:hover{ color: #0D3B57;} / Theme background colors / .theme-bg-color-1,div.theme-bg-color-1{ background-color: #6CA5CE;} .theme-bg-color-2,div.theme-bg-color-2{ background-color: #fffbdd;} .theme-bg-color-3,div.theme-bg-color-3{ background-color: #DEE8ED;} .theme-bg-color-4,div.theme-bg-color-4{ background-color: #EBEFF1;} .theme-bg-color-5,div.theme-bg-color-5{ background-color: #2B6EB5;} .theme-bg-1{ / background-image: url(images/navbar-bg.png); /} .theme-bg-2{ / background-image: url(images/navbar-bg-2.png); /} / Theme border type/colors / .theme-border-1{ border-color: #457f63; border-style: dotted;} .theme-border-2{ border-color: #2B6EB5;}Locate theYUI Theme Changes section.
This section allows changes to the YUI components.
Edit the properties in this section to change the theme.
Alfresco Share presents data view and entry forms throughout its user interface, which are built on the Surf framework. This framework provides a convention for implementing forms.
Content Services uses only one configuration syntax and one set of UI controls for forms throughout.
Forms are used in theView Metadata andEdit Metadata pages within Share.
The following screen shot shows the form component on theEdit Metadata page:

The content of the form is completely driven from configuration custom types, custom aspects. Their properties and associations can be displayed.
The forms engine consists of four major parts; the form service, form component, form configuration, and the JavaScript for UI component (which includes the forms runtime).
The following diagram shows a high-level architecture diagram of the forms engine.

The forms runtime is responsible for the execution of a form. It manages all input, validation (client or call-back), events, submission, and it consists of a small, lightweight JavaScript library. An unobtrusive JavaScript pattern is used, where behavior is added to the HTML form elements when the page loads. The forms runtime provides the following capabilities:
When a request is made to a page containing the form component, the following sequence of events occurs.
For a description of the available form controls, refer toForms reference.
At this point, the form is ready for the user to interact. When the user interacts with the form, the forms runtime constantly checks the validation rules enabling and disabling theSubmit button appropriately. When the user submits the form, the following sequence of events occurs.
Forms can be configured through theshare-config-custom.xml file.
The default forms configuration is specified in the./tomcat/webapps/share/WEB-INF/classes/alfresco/share-form-config.xml file. This file contains all the default controls and constraint handlers for the content model and the form configuration for thecm:contentandcm:folder types. This file also contains an example of configuring thecm:content type.
Note: You should apply all your forms customizations to a custom configuration file. To configure forms for the Share application, use the custom configuration file named
share-config-custom.xml.
There are a number of files involved in form configuration, but generally you should add your configurations to a custom configuration file. The default configuration files are listed here so that you can see the range of configurations available:
| File | Description |
|---|---|
| form-config.xml | Default form configuration file |
| share-form-config.xml | Default forms for content and folder creation, edit and search |
| share-datalist-form-config.xml | Forms for the built-in datalists |
| share-workflow-form-config.xml | Core workflow forms and built-in workflows |
CAUTION: Avoid editing the default configuration files directly.
One of the most common customizations is to add new controls. A control is the label for a field and the interface that the user interacts with for setting the value of the field.
A control is a FreeMarker template snippet that includes the markup to define the control. The model for the template includes the field and form being generated, represented by afield andform object, respectively. The following snippet shows the structure of thefield object, using thecm:name property as an example:
{ kind : "field", id : "prop_cm_name", configName : "cm:name", name : "prop_cm_name", dataType : "d:text", type : "property", label : "Name", description : "Name", mandatory : true disabled : false, repeating : false, dataKeyName : "prop_cm_name", value : "plain-content.txt", control: { params: {}, template : "controls/textfield.ftl" }}Although theid property provides a unique identifier for the field, it is only scoped to the current form. If there are multiple forms on the page containing the same field, this identifier will not be unique. The model propertyfieldHtmlId should be used as the identifier for the control, as this is guaranteed to be unique for the page.
The state of thedisabled property must always be adhered to when implementing controls as this is driven from the field definition returned from theFormService and from theread-only attribute in the form configuration. If thedisabled property is set to true, the control should never allow the value to be edited.
The control is also responsible for rendering an appropriate UI representation for the mode the form is currently in. The form mode can be retrieved from theform.mode property. A pattern used by most the out-of-the-box controls is shown:
<#if form.mode == "view"> // view representation goes here...<#else> // edit and create representation goes here...</#if>The final rule for controls is that they must supply the field current value in a DOM element that has avalue property and theid property set to the value offieldHtmlId FreeMarker variable.
For advanced controls, that is, association, date, period, and so on, this usually requires a hiddenform field.
A validation handler is a small JavaScript function that gets called by the forms runtime when a field value needs to be validated.
The JavaScript function signature for a validation handler looks like this:
/** * Validation handler for a field. * * @param field {object} The element representing the field the validation is for * @param args {object} Object containing arguments for the handler * @param event {object} The event that caused this handler to be called, maybe null * @param form {object} The forms runtime class instance the field is being managed by * @param silent {boolean} Determines whether the user should be informed upon failure * @param message {string} Message to display when validation fails, maybe null * @static */function handler-name(field, args, event, form, silent, message)The built in “mandatory” validation handler is defined as follows:
Alfresco.forms.validation.mandatory = function mandatory(field, args, event, form, silent, message)Thefield parameter is usually the HTML DOM element representing the field’s value, which is normally an HTML input DOM element, so that the value property can be accessed. The structure of theargs parameter is dependent on the handler being implemented. By default, these will be the parameters of the constraint defined on the field.
The handler is responsible for taking the value from the field and uses theargs parameter to calculate whether the current value is valid or not, returningtrue if it is valid andfalse if it is not.
You can configure the type metadata in theshare-config-custom.xml file in<web-extension>. It is also possible to deploy custom configurations via JARs or AMPs.
The following snippet shows the forms definition in theshare-config-custom.xml file.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <field-visibility> <show /> <show force="true" /> <show force="true" /> <show /> <show force="true" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> </field-visibility> </form> </forms></config>The configuration defines that thecm:name property is visible in all modes, whereas thecm:creator,cm:created,cm:modifier, andcm:modified properties are visible in view mode only.
Themimetype andsize properties are known as transient properties because they do not exist as properties in the model. These properties are formed from thecm:content property. TheNodeFormProcessor knows about these properties and generates a field definition to represent them so that they will appear in the forms.
Theforce attribute ensures that theNodeFormProcessor searches the entire content model for the property or association definition before returning anything.
Open the<web-extension>/share-config-custom.xml file.
Enter the configuration for custom types.
The following example configuration shows themy:text,my:dateTime andmy:association properties being configured for the custommy:example type.
<config evaluator="node-type" condition="my:example"> <forms> <form> <field-visibility> <show /> <show /> <show /> </field-visibility> </form> </forms></config>Add more fields to the default configuration.
The following example shows how to show the node’sDBID property for allcm:content nodes.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <appearance> <field> <control> <control-param name="rows">20</value> <control-param name="columns">20</value> </control> </field> </appearance> </form> </forms></config>Note: The full prefix version of the type is required in the
conditionattribute.
Theforce attribute forces theNodeFormProcessor to search the entire content model for the property or association definition before returning anything.
Save your file.
Add the properties and associations defined on aspects by adding them to the list of fields to show for a type. The aspects that appear can be defined on a type by type basis, and you can control the ordering of the fields.
Open the<web-extension>\share-config-custom.xml file.
Note: While you can configure the aspect metadata by directly editing the
share-config-custom.xmlfile in<web-extension>. It is also possible to deploy custom configurations via JARs or AMPs.
Enter the configuration for custom types.
The following example configuration shows thecm:from andcm:to properties for thecm:effectivity aspect.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <field-visibility> <show /> <show force="true" /> <show force="true" /> <show /> <show force="true" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> <show for-mode="view" /> <!-- cm:effectivity aspect --> <show/> <show/> </field-visibility> </form> </forms></config>Add custom aspects to the default configuration by overriding the configuration.
The following example shows how to add the fields of an example aspect to all forms for thecm:content type.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <field-visibility> <!-- fields from my example aspect --> <show /> <show /> </field-visibility> </form> </forms></config>This will apply the aspects to allcm:content nodes.
Save the file.
It is also possible to have the fields appear for any type of node to which the aspect is applied. For example, you may wish to display themy:aspectProperty andmy:aspectAssociation fields for any type of node to which themy:customAspect is applied:
<config evaluator="aspect" condition="my:customAspect"> <forms> <form> <field-visibility> <!-- fields from my example aspect --> <show /> <show /> </field-visibility> </form> </forms></config>Most of the built in controls have parameters that allow some basic customization.
Open the<web-extension>\share-config-custom.xml file.
Change the number of rows and columns used for thetextarea control that thecm:description field uses by default.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <appearance> <field> <control> <control-param name="rows">20</control-param> <control-param name="columns">80</control-param> </control> </field> </appearance> </form> </forms></config>If alltextarea controls in the application need to have these settings, configure the control in thedefault-controls element. For example:
<config evaluator="node-type" condition="cm:content"> <forms> <default-controls> <type name="d:mltext"> <control-param name="rows">20</control-param> <control-param name="columns">80</control-param> </type> </default-controls> </forms></config>Save the file.
For longer forms, you can group fields together in logical grouped or nested sections.
Open the<web-extension>\share-config-custom.xml file.
Enter the configuration for custom types.
The following example configuration shows how to group some fields from an imaginary custommy:example type.
<config evaluator="model-type" condition="my:example"> <forms> <form> <field-visibility> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> </field-visibility> <appearance> <set appearance="fieldset" label="Text Fields" /> <set appearance="panel" label="Number Fields" /> <set appearance="fieldset" label="Date Fields" /> <field set="text" /> <field set="text" /> <field set="text" /> <field set="text" /> <field set="number" /> <field set="number" /> <field set="number" /> <field set="number" /> <field set="date" /> <field set="date" /> </appearance> </form> </forms></config>Nested sets are also supported. Use theparent attribute in theset element. The following example configuration shows the fields of themy:example type in a nested set.
<config evaluator="model-type" condition="my:example"> <forms> <form> <field-visibility> <show /> <show /> <show /> <show /> <show /> <show /> <show /> <show /> </field-visibility> <appearance> <set appearance="fieldset" label="Built In" /> <set appearance="fieldset" label="Custom Data" /> <set parent="custom" appearance="panel" label="Text" /> <set parent="custom" appearance="panel" label="Numbers" /> <field set="builtin" /> <field set="text" /> <field set="text" /> <field set="text" /> <field set="number" /> <field set="number" /> <field set="number" /> <field set="number" /> </appearance> </form> </forms></config>Save the file.
Fields that do not specify a set belong to the implicitdefault set. They are rendered together, by default, but without any visual grouping.
Open the<web-extension>\share-config-custom.xml file.
Enter the configurations for the set label.
The appearance of the default set can be controlled in the same way as other sets, for example, using an identifier of an empty string.
<set appearance="panel" />This will render a panel around all the fields with a label ofDefault.
To specify a different label, add thelabel attribute. For example, the following label will beGeneral.
<set appearance="panel" label="General" />You can also use a message bundle key.
<set appearance="panel" label-id="form.set.general" />Save the file.
If none of the out-of-the-box controls are sufficient, you can add new controls and reference them. Controls are FreeMarker template snippets, therefore, they contain only the HTML markup required to represent the control. The templates need to be stored in thesite-webscripts directory, which will usually be in the application server shared classpath.
The following example configuration shows a very simple custom text field control that always displays with a green background, white text, and 700 pixels wide. For a production system, use a CSS class; however, this example shows a hard coded style.
<div> <#if form.mode == "view"> <div> <span>${field.label?html}:</span> <span>${field.value?html}</span> </div> <#else> <label for="${fieldHtmlId}">${field.label?html}:<#if field.mandatory><span>*</span></#if></label> <input type="text" name="${field.name}" value="${field.value}" <#if field.disabled>disabled="true"</#if> /> </#if> </div>The following example configuration shows this control being used for thecm:name property, with a file name ofmy-textfield.ftl.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <appearance> <field> <control template="/my-textfield.ftl" /> </field> </appearance> </form> </forms> </config>By default, forms are rendered with the field labels positioned above the input control.

To change this layout, provide a custom CSS to override the default style rules. Control dependencies can be provided by using custom configuration.
Add the custom CSS in thecustom-label-layout.css file, located in the/custom/forms directory within the web application.
Add the following configuration:
<config> <forms> <dependencies> <css src="/custom/forms/custom-label-layout.css" /> </dependencies> </forms></config>To move the labels to the left of the input control, the following CSS should be present in thecustom-label-layout.css file:
.form-container label{ display: inline; float: left; text-align: right; width: 6em; margin-right: 1em; margin-top: 0.4em;}Save the file.
The result of this customization is shown as:

The default template that renders the form UI generates one column of fields. There are scenarios where more control might be required over the layout. To enable these scenarios, it is possible to replace the default template with a custom template. A different template can be provided for each form mode.
Store the custom templates in thesite-webscripts directory, which is usually be in the application server shared classpath.
The example shows theEdit form for the standardcm:content type being configured to render with two columns of fields.
<config evaluator="node-type" condition="cm:content"> <forms> <form> <edit-form template="/2-column-edit-form.ftl" /> </form> </forms></config>The example template2-column-edit-form.ftl is available in the distribution in the samples folder.
The following example shows the contents of the2-column-edit-form.ftl file. It uses some of the FreeMarker macros available inform.lib.ftl but supplies its ownrenderSetWithColumns macro to render the HTML required to create the grid using the YUI grid CSS capabilities.
<#import "/org/alfresco/components/form/form.lib.ftl" as formLib /> <#if error?exists> <div>${error}</div><#elseif form?exists> <#assign formId=args.htmlid + "-form"> <#assign formUI><#if args.formUI??>${args.formUI}<#else>true</#if></#assign> <#if formUI == "true"> <@formLib.renderFormsRuntime formId=formId /> </#if> <div> <#if form.showCaption?exists && form.showCaption> <div><span>*</span>${msg("form.required.fields")}</div> </#if> <#if form.mode != "view"> <form method="${form.method}" accept-charset="utf-8" enctype="${form.enctype}" action="${form.submissionUrl}"> </#if> <div> <#list form.items as item> <#if item.kind == "set"> <@renderSetWithColumns set=item /> <#else> <@formLib.renderField field=item /> </#if> </#list> </div> <#if form.mode != "view"> <@formLib.renderFormButtons formId=formId /> </form> </#if> </div></#if> <#macro renderSetWithColumns set> <#if set.appearance?exists> <#if set.appearance == "fieldset"> <fieldset><legend>${set.label}</legend> <#elseif set.appearance == "panel"> <div> <div>${set.label}</div> <div> </#if> </#if> <#list set.children as item> <#if item.kind == "set"> <@renderSetWithColumns set=item /> <#else> <#if (item_index % 2) == 0> <div><div> <#else> <div> </#if> <@formLib.renderField field=item /> </div> <#if ((item_index % 2) != 0) || !item_has_next></div></#if> </#if> </#list> <#if set.appearance?exists> <#if set.appearance == "fieldset"> </fieldset> <#elseif set.appearance == "panel"> </div> </div> </#if> </#if></#macro>When the configuration and template is in place, the Edit Metadata page for acm:content type in Share has the following appearance.

You can add custom MIME types to Share.
When you edit the properties of a document, it is possible to select a MIME types from a drop-down list. You can add custom MIME types to this list.
Custom MIME types are added to a configuration file. An example file is provided:./tomcat/shared/classes/alfresco/extension/mimetype/mimetypes-extension-map.xml.sample. You can rename this file to./tomcat/shared/classes/alfresco/extension/mimetype/mimetypes-extension-map.xml. It will be processed when Content Services is restarted.
The content of the example file is as follows:
<alfresco-config area="mimetype-map"> <config evaluator="string-compare" condition="Mimetype Map"> <mimetypes> <mimetype mimetype="application/XXX" display="Example mimetype"> <extension>ex</extension> </mimetype> </mimetypes> </config> </alfresco-config>You can add custom MIME types as required to this file, or create your own configuration file located on the classpath.
tomcat/shared/classes/alfresco/web-extension/share-config-custom.xml (Untouched by re-deployments and upgrades)aio/share-jar/src/main/resources/META-INF/share-config-custom.xml - Share configuration related to a specific Share module extension, such as Document Library Action configuration, form configuration, aspect and type configuration.