?

Log in

No account? Create an account
Overriding Alfresco webscript library ftl files - Nick [entries|archive|friends|userinfo]
Nick

[ website | gagravarr.org ]
[ userinfo | livejournal userinfo ]
[ archive | journal archive ]

Overriding Alfresco webscript library ftl files [Jan. 30th, 2013|07:04 pm]
Nick
[Tags|, ]

On the whole, Alfresco is pretty good for customising and overriding, and there's been a lot of work done in 4.2 to make it even easier to customise Share and Surf. Overriding the spring beans for Java backed webscripts can be done with a bit of fiddling. One problem we have hit though is with overriding FTL files, especially library ones.

I'll use the Workflow REST API as an example here, as it's one we needed to change, but it applies to a lot of the webscripts too. A common JSON emitting Alfresco REST API has a FTL file somewhat like:

<#import "workflow.lib.ftl" as workflowLib />
{
   "data":
   <@workflowLib.taskJSON task=workflowTask detailed=true/>
}
It imports a library file, then calls one of the functions in there. If you want to inject a few extra bits into the JSON structure, then your only option is to edit the library file, or clone it. For simple libraries with a single macro, you could just clone the whole thing and customise, but for a library with many macros that gets rather nasty especially when upgrading. FreeMarker macros get replaced when a new one is defined with the same name, much like spring beans, so for our hypothetical macro file:

<#macro taskJSON task detailed=false>
<#escape x as jsonUtils.encodeJSONString(x)>
      {
         "id": "${task.id}",
          ....
      }
</#escape>
</#macro>

<#macro propertiesJSON properties>
<#escape x as jsonUtils.encodeJSONString(x)>
{
<#list properties?keys as key>
   "${key}":
   ...
</#escape>
</#macro>
To change taskJSON to inject some extra bits from the model, we'd have to copy the whole file and customise. However, there is a way that makes things a little less evil, which relies on macros overwriting each other. We take the original file, and copy it to the same directory structure in our module, but with a new name. Instead of workflow.lib.ftl we might instead go for workflow-original.lib.ftl. Next, add a new comment to the top, documenting where it originally came from, what version it is taken from etc. Now, create a new workflow.lib.ftl, and copy into that the whole of the macro we want to override. Add in the extra few JSON clauses. At the top of the file, add some documentation saying what version you copied and pasted from, what file it came from, and what changes you made. Trust me, you'll be thankful you did this when you come to upgrade... Finally, at the top of the file, before your customised macro, add in an include (not import, include) of the renamed original. Your new lib, with the name of the old one, now looks something like:

<#-- Customised File -->
<#-- Original: remote-api/config/alfresco/templates/webscripts/org/alfresco/repository/workflow/workflow.lib.ftl -->
<#-- Alfresco Version: 4.1.1.3 -->
<#-- Modification: Added custom1 and custom2 properties to the JSON -->

<#-- This pulls in all the macros we haven't needed to change -->
<#include "workflow-original.lib.ftl">

<#-- Override and customise the one we do need to change -->
<#macro taskJSON task detailed=false>
<#escape x as jsonUtils.encodeJSONString(x)>
      {
         "id": "${task.id}",
          ....
         "myCustom1": ${task.custom1},
         "myCustom1": ${task.custom2}
      }
</#escape>
</#macro>
(It's probably best to put your custom json at the start or end, to make upgrading easier)
linkReply

Comments:
From: Zhi Wang
2018-03-14 04:15 am (UTC)

What's the exact folder path you use for this customised ftl file?

Hi Nick,

I'm struggling with java-end webscripts ftl files override in Alfresco, I couldn't figure out the right path to put my workflow.lib.ftl file to, can you please tell me what's your folder path in your module? Thank you.

Regards,
Zhi
(Reply) (Thread)
From: gagravarr
2018-03-14 05:48 am (UTC)

Re: What's the exact folder path you use for this customised ftl file?

You generally want it to end up as either
WEB-INF/classes/config/alfresco/templates/webscripts/org/alfresco/repository/workflow/workflow.lib.ftl 
or better
WEB-INF/classes/alfresco/extension/templates/webscripts/org/alfresco/repository/workflow/workflow.lib.ftl


The path in your module to get there depends on the folder layout you've picked and the mapping properties you've defined
(Reply) (Parent) (Thread)
From: Zhi Wang
2018-03-14 10:43 pm (UTC)

Re: What's the exact folder path you use for this customised ftl file?

Thank you for your reply, Nick, I tried to add workflow.lib.ftl in my module with the suggested path, but I can't make Alfresco to load it.


However, it does replace the original file if I put the customised workflow.lib.ftl under `tomcat/shared/classes/alfresco/extension/templates/webscripts/org/alfresco/repository/workflow` folder, I don't understand why I can't replace it via module installation because we never failed to replace like spring bean definition by putting customised xml file with required folder structure under alfresco/extension folder in our module, which means the folder layout and the mapping properties are always working well, so I assume maybe Alfresco doesn't like the replace of static file?


Since I know the correct path, thank you for your help, I can use the manually copy as a workaround for the time being and I will try and see if I can override this file via module installation rather than manually copy it to shared folder.


Thank you very much, Nick!

Edited at 2018-03-14 10:44 pm (UTC)
(Reply) (Parent) (Thread)