Alfresco Share 5, using “authority.ftl” form control

Last week I was designing an Alfresco Content Model including a property to gather a set of Alfresco users to be sent to an external service.

I remembered about authority.ftl form control, which is a picker that could fit fine with my requirements.

I searched about the control at official documentation

… and also in the Community.

After some research inspecting Alfresco source code, I realised that this control is auto-configured depending on the definition of the property to be rendered.

      itemType: "${field.endpointType}",
      multipleSelectMode: ${field.endpointMany?string},
      itemFamily: "authority"

So to include a form control to select MANY USERS following content model should be declared in Repository part.

<aspect name="ks:defaultSigners">
		<association name="ks:alfrescoUser">

And a simple form control association in Share part makes the work.

<field id="ks:alfrescoUser">
    <control template="/org/alfresco/components/form/controls/authority.ftl"/>

Also relevant for this use case the addon provided by Douglas C. R. Paes at Alfresco Colleagues Picker Form.

Sometimes a small investigation before developing your tasks will save you many time and will produce an easier solution.


How to develop a SOAP client from Alfresco Repository

Due to integration requirements with legacy old systems, it happens that Alfresco Repository must invoke an external SOAP endpoint. As Alfresco Repository web application includes a changing JAR Library catalog, using an out-of-the-box implementation to build SOAP clients is advisable.

The target scenario

I selected a sample Global Weather SOAP Web Service endpoint available at 

Starting from WSDL is always a must when build a SOAP Web Service for both client and server parts.

Alfresco repository will invoke this endpoint from a Web Script to proxy parameters and results in a REST invocation.

Creating an standard JAXWS client project

Source code available at

Once the project is compiled with Maven, client Java classes are packaged into the target JAR. In order to use this client, simple invocations can be done.

GlobalWeather service = new GlobalWeather(new URL(""));
String cities = service.getGlobalWeatherSoap().getCitiesByCountry("Spain");

In order to make the JAR available to Maven for next step, an installation is required.

$ mvn clean install

Creating an Alfresco Repository Module for Web Scripts

Source code available at

As JAXWS client does not include any external dependency, the library can be included directly in pom.xml file.

Web Scripts are defined in a standard way:

SOAP Endpoint URL has been declared as property in to make easier changes in the configuration.

Inside Java controller implementation, SOAP JAXWS standard client is invoked:

String country = req.getServiceMatch().getTemplateVars().get("country");

GlobalWeather service = new GlobalWeather(new URL(url));
String cities = service.getGlobalWeatherSoap().getCitiesByCountry(country);

Map<String, Object> model = new HashMap<String, Object>();
model.put("cities", cities);
return model;


Once the project is deployed or even using script from Maven project, SOAP services can be accessed by using Alfresco REST API.



Including new features inside Alfresco Repository is not a complex project, but using the simplest way is always worthy: upgrading and updating processes will be as safe as the are!


How to create a Site for Alfresco using Java API

Some time ago, Site creation in Alfresco was driven by Share web application. So using a simple SiteService.createSite from repository Java API is not enough to provide access to the site from Share.

Below some useful snippets are listed.

Creating the Site

// Default site preset
String sitePreset = "site-dashboard";
SiteInfo siteInfo = siteService.createSite(sitePreset,
    "Test Site",
    "Test Site description", 

Adding site members

Including at least a Manager is advisable.


Creating dashboard

This step is required to provide access from Share.

private void createDefaultDashboard(SiteInfo siteInfo) {
    NodeService nodeService = serviceRegistry.getNodeService();
    FileFolderService fileFolderService = serviceRegistry.getFileFolderService();
    ContentService contentService = serviceRegistry.getContentService();
    FileInfo surfConfig = fileFolderService.create(siteInfo.getNodeRef(), "surf-config", ContentModel.TYPE_FOLDER);
    Map<QName, Serializable> properties = new HashMap<QName, Serializable>();
    properties.put(ContentModel.PROP_CASCADE_HIDDEN, Boolean.TRUE);
    properties.put(ContentModel.PROP_CASCADE_INDEX_CONTROL, Boolean.TRUE);
    nodeService.addAspect(surfConfig.getNodeRef(), ContentModel.ASPECT_HIDDEN, properties);
    // Hint from Bertrand Forest
    properties = new HashMap<QName, Serializable>();
    properties.put(ContentModel.PROP_IS_INDEXED, Boolean.FALSE);
    properties.put(ContentModel.PROP_IS_CONTENT_INDEXED, Boolean.FALSE);
    nodeService.addAspect(surfConfig.getNodeRef(), ContentModel.ASPECT_INDEX_CONTROL, properties);
    FileInfo pages = fileFolderService.create(surfConfig.getNodeRef(), "pages", ContentModel.TYPE_FOLDER);
    FileInfo site = fileFolderService.create(pages.getNodeRef(), "site", ContentModel.TYPE_FOLDER);
    FileInfo siteName = fileFolderService.create(site.getNodeRef(), siteInfo.getShortName(), ContentModel.TYPE_FOLDER);
    Map<QName, Serializable> props = new HashMap<QName, Serializable>(1);
    props.put(ContentModel.PROP_NAME, "dashboard.xml");  

    NodeRef node = nodeService.createNode(
                        QName.createQName(NamespaceService.CONTENT_MODEL_1_0_URI, "dashboard.xml"),
    ContentWriter writer = contentService.getWriter(node, ContentModel.PROP_CONTENT, true);
    // TODO Create dashboard.xml file by using an external file resource instead of a hand-coded String
    writer.putContent("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + 
            "<page>\n" + 
            "      <title>Collaboration Site Dashboard</title>\n" + 
            "      <title-id>page.siteDashboard.title</title-id>\n" + 
            "      <description>Collaboration site's dashboard page</description>\n" + 
            "      <description-id>page.siteDashboard.description</description-id>\n" + 
            "      <authentication>user</authentication>\n" + 
            "      <template-instance>dashboard-2-columns-wide-left</template-instance>\n" + 
            "      <properties>\n" + 
            "        <sitePages>[{\"pageId\": \"documentlibrary\"}]</sitePages>\n" + 
            "      <theme/><dashboardSitePage>true</dashboardSitePage></properties>\n" + 
            "    <page-type-id>generic</page-type-id></page>");

Creating Site containers

There are different containers that should be created (wiki, forum,…) but having a Document Library is required for many use cases.

NodeRef documentLibraryNodeRef =  siteService.createContainer(siteInfo.getShortName(), SiteService.DOCUMENT_LIBRARY, null, null);

Some operations are not described in Alfresco documentation, but they can be guessed inspecting internal structure of the repository.