Alfresco Share customizations (I)

In our latest post, we explained which are the new features of the new Alfresco version. One of them was easying the customization of Spring Surf and Alfresco Share components. In this blog post we will explain which is the best way to extend and customize the Share UI components and pages.

As you will know Alfresco Share has been built using the Spring Surf technology, which Alfresco contributed it originally to the Spring community.

Being a Spring based application, Alfresco Share has context configuration files which indicates the application the file system directories in where to look for other files and the order in which they are processed. The file to look at is surf-config.xml located in WEB-INF/classes. See an example below.




  <property name="defaultHandler">
     <bean class="org.springframework.extensions.surf.mvc.UrlViewController">
        <property name="urlPathHelper" ref="urlPathHelper"></property>
     </bean>
  </property>

The way this file is processed is from top to bottom, the referenced files in the bottom of the list override the configuration of the referenced files up in the list if there is a match in the Spring bean ID. Note that the paths are relatives to the classpath and the asterisk (*) character is used as a wildcard when matching file names. So for instance, the classpath*:alfresco/web-extension/*-context.xml will process any files located in the alfresco/web-extension within the classpath which files' names end in "-context.xml.

Another important configuration file listed in the one above is the slingshot-application-context.xml in WEB-INF/classes/alfresco, which overrides the config source to add its own list:


      
         
            
            classpath:org/springframework/extensions/webscripts/spring-webscripts-config.xml
            classpath:META-INF/spring-webscripts-config-custom.xml
            jar:*!/META-INF/spring-webscripts-config-custom.xml
        <!-- Spring 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><p>            <!-- 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><p>            <!-- Share Data List form config -->
        <value>classpath:alfresco/share-datalist-form-config.xml</value><p>            <!-- Share workflow form config -->
        <value>classpath:alfresco/share-workflow-form-config.xml</value>
        
        <!-- Share CMIS config -->
        <value>classpath:alfresco/share-cmis-config.xml</value><p>            <!-- Share Security config -->
        <value>classpath:alfresco/share-security-config.xml</value><p>            <!-- 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>
     </list>
  </constructor-arg>

Same as before it goes from top to bottom. Just to comment that the jar: placeholder refers to JAR files in the classpath.

The web-extension folder located either on the shared directory or in WEB-INF/classes/alfresco is where all the custom server side files should go, such as configuration files, webscripts, templates, page definitions, etc. If you aim to override an existing file, you just need to create the same folder hierarchy inside the web-extension folder and overwrite the whole file you want to change.

This is how a Alfresco Share project should look like.

alfresco share project structure

As you can see all the server side extensions go under the web-extension folder, and the client side files (javascript, CSS, etc.) in src/main/webapp. This project layout is the default one provided by the Maven archetype to develop Alfresco Share extensions.

Custom spring beans will be configured in custom-slingshot-application-context.xml file (a sample file is provided with the Maven artifact). On the other hand, the User Interface configurations will be done in share-config-custom.xml. These configurations will overwrite any default configuration that match them.

The DocLibCustom 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.All the configurations in share-config-custom.xml will overwrite the default ones. The client-side dependencies are located in the <dependencies> config container element with the following structure:In following blog posts we will develop interesting extensions and you will be able to see the best practices in action. The <css> tag defines Stylesheet dependencies while the <js> tag defines the Javascript dependencies. Both of those tags have a common src attribute, which value is the path to the file, relative to the /res servlet. Example:


   
      
         
            
            
         
   

One thing a developer needs to know about Alfresco Share is how the main components in it are built. There are 2 major components in Alfresco Share: pages and dashlets. Freemarker templating engine is used to render them.

Dashlets are webscripts that belong to a certain webscript family. There are 2 types of dashlets and to define each type the family is different, that is the only difference between them:

  • Site dashlets: webscript family being 'site-dashlet'
  • Dashlets: webscript family being 'dashlet'

Pages are templates backed by webscripts to make them dynamic pages. Each webscript is a different component of the page. Let's analyze the document list page for instance.

Alfresco Share DocLib Components

You can see the different components backed by webscripts in the screenshot above. Each component is marked in the template with the <@region /> tag given an ID and mapped to a webscript in the configuration files.

There will be Alfresco and Share Extensions going on, all related to one topic I'm still thinking about and will be available in my GitHub account. Note that this project is currently a skeleton. I will be pushing code as moving forward with the blog post.

Stay tuned!

Show Comments