Customizing Alfresco Share JavaScript Controllers

cancel
Showing results for 
Search instead for 
Did you mean: 

Customizing Alfresco Share JavaScript Controllers

Intermediate II
0 8 2,118

Introduction

In the last blog I introduced extension module 'customizations' and demonstrated how they could be used to override an i18n properties file to change the label on the User Dashboard. In this post I'm going to be demonstrating how to change the behaviour of a Web Script by augmenting its JavaScript controller. The extensibility features used are currently available in the latest Alfresco Community source and will be in Alfresco Enterprise 4.0.

Tutorial

In this tutorial I'm going to demonstrate how to provide an extension to the JavaScript controller file for the Web Script behind the 'Web View' dashlet so that the Alfresco.com web site will be displayed if the user hasn't specified another.

Making this kind of change does require some insider knowledge of how Alfresco Share is coded. Fortunately we can use a combination of SurfBug and the Web Scripts service UI to find out everything you need to know. There's no guarantee that you will be able to do everything you want using this method - but it would definitely be worth exploring as a first port of call.

First of all we need to add the 'Web View' dashlet to the User Dashboard:

  1. Log on to Alfresco Share
  2. Click the 'Customize Dashboard' button
  3. Click on 'Add Dashlets'
  4. Drag the 'Web View' dashlet from the available list and drop it into one of the dashboard columns
  5. Click 'OK'


Initially the dashlet will display the message 'No web page to display' as it has not been configured.

Screen shot showing the default Web View dashlet

Working in the Alfresco Engineering team meant that I already knew that I'd be able to make the customization I wanted - but by enabling SurfBug (http://localhost:8080/share/page/surfBugStatus - if you're using the default port) and clicking on the Web View dashlet you can find the Web Script URI ('/components/dashlets/webview') that renders it and by browsing for Web Scripts by URI (http://localhost:8080/share/page/index/uri/) you can access all the information (including the source of the JavaScript controller). This was explored in greater detail in the last blog if you need a refresher on how to find this information.

By inspecting the source of both the controller and the template you can work out what model properties the template is using and whether or not you can provide an extension to update the model after the base controller but before the template in order to create the desired result.

Screen shot showing the Web Script info for the Web View dashlet

Having identified that the dashlet is rendered by a Web Script using the controller ' webview.get.js' in the 'org.alfresco.components.dashlets' package we can define a new module with a customization to apply to it.

Edit the 'blog-demo.xml' file and add the following module configuration:

<module>
    <id>Blog Module (Web View JavaScript controller change)</id>
    <customizations>
        <customization>
            <targetPackageRoot>org.alfresco.components.dashlets</targetPackageRoot>
            <sourcePackageRoot>blog.demo.customization</sourcePackageRoot>
        </customization>
    </customizations>
</module>

Although we're targeting a different package, we're going to map it to the same package as we used for the properties customization in the last blog post.

Create a file called 'webview.get.js' containing the following:

if (model.isDefault == true)
{
    model.webviewTitle = 'Alfresco!';
    model.uri = 'http://www.alfresco.com';
    model.isDefault = false;
}

Place the new file in the 'webscripts.blog.demo.customization' package, rebuild and deploy your JAR, restart the web server and deploy your new module. When you login to Alfresco Share you should see that the Web View dashlet now displays the Alfreco.com website.

Screenshot showing the customized Web View dashlet

Your ability to customize Alfresco Share pages in this way will be somewhat limited to how they have been coded - but it's worth exploring as an option. In the future we will endeavor to create Web Script controllers with respect to potential extensions, but as the existing controllers weren't created with this in mind it's really pot luck as to whether you can achieve what you want.

However, there's another customization file type that you can also use... in the next blog post I'll be demonstrating how to customize Web Script FreeMarker templates.

Place the new file in the 'blog.demo.customization' package, rebuild and deploy your JAR, restart the web server and deploy your new module. When you login to Alfresco Share you should see that the Web View dashlet now displays the Alfreco.com website.
8 Comments
Active Member
Is there a way to extend a dashlet config file also? for example activity-list.get.config.xml
Intermediate II
Unfortunately at the moment WebScript configuration extensions aren't implemented yet - this is something we hope to introduce in the future.
Active Member
How exactly does this work?  How is your custom JS executed? Does the custom JS execute after the original or before or how?
Intermediate II
The custom JavaScript is executed after the original. The original JavaScript setups up an initial model object which the default FreeMarker template can use to render content, but controller extensions have the opportunity to change that model and thus change the rendered output. Obviously using the approach is dependent upon the template making use of the changed model content (i.e. just adding content to the model will have no effect unless the template is also updated to make use of the additional model data).
Active Member
Just recently (few months ago) read this set of posts detailing 4.x extra share extension points and have a couple questions.
The original need was to be able to extend same js controller from more than one module deployed in same Alfresco instance. This led me to develop a custom controller wrapper (initially for 3.4) configurable from share|web-client-config-custom.xml to be able to run js before or after the existing controller (provided I also configure the custom controller to be the backing Java controller for the targeted scripts). The most common area where extension was needed was in the alfresco and share document library related scripts.
I was hoping I could drop this now, but at first glance, even if I use the new mechanism in Share, it doesn't seem to address the Alfresco app. Before starting to dig, is there any way I could accomplish this in Alfresco with configuration alone? Is the code that wraps js controller even available in alfresco.war or will it ever be? I'm really hoping to drop the dependency all modules have on this custom extension and make them completely independent, while retaining compatibility.
Intermediate II
@Dan - The main difference between Alfresco Repository (alfresco.war) and Share (share.war) is that the former uses just the WebScripts libraries whereas Share uses the whole Surf stack. Most of the extensibility capabilities are handled in the Share stack. However, I did some work to provide extensibility for alfresco.war (primarily for extending JavaScript controllers) which is described in the following blog: https://www.alfresco.com/blogs/ddraper/2012/05/23/webscript-extensibility-on-the-alfresco-repository...

Unfortunately the ability to customize is often limited by the implementation of the Repository WebScripts. Whereas in the Share WebScripts there is a common pattern that is followed that allows changes to be easily achieved by customizing the model created by the JavaScript controller, it is not always the case in the Repository (for example where a JSON response is constructed 'by hand' in the FreeMarker template).

Most of the WebScripts were written before the extensibility capabilities were added (they've not been intentionally written to prevent extensibility), but without the custom FreeMarker directives provides in the Surf layer it does make Repository WebScript customizations that much harder.
Active Member
[…] 4.0 we introduced the ability to apply extension modules that could dynamically manipulate the controller, localization properties and FreeMarker templates. Customizing the FreeMarker templates was by far […]
Active Member
A couple of years too late but since I happened to stumble upon this questions I thought I would answer it...



There is still no support for overriding config, instead the way to do it is to change the 'model' that is passed into the freemarker template. In other words, let the 'original' .get.js file parse the 'original' .get.config.xml and set the 'model'. Since your custom .get.js file that will run before the .get.html.ftl template is exectued you will have the chance of 'configuring the model programmatically' instead, this will you give you more flexibility in terms of logic.



Cheers, Erik