Implementing Multiple Project Customisations in one Alfresco instance

Introduction

Working on an Alfresco project for a client I experienced a number conflicts when deploying the project on an existing Alfresco server where other customisation projects were already deployed.

The conflicts occurred primarily on the share instance when common configuration files were used, but also on the repository instance.

The conflicts that occurred were:

  1. A content model was not loaded because the same bean-id was used in two different projects.
  2. Only viewable aspects defined for project A was visible, not those defined for project B
  3. When selecting “change type” only types defined in project A was available, not those defined in project B

I am sure more conflicts which we haven’t discovered might occur. In this post I will describe the nature of the conflicts we did discover and how they may be avoided.

Research

In order to support and verify the recommendations in this post I have created 5 customisation projects. In these projects I have done some “standard” customisations. In the repository projects I have created customised content models. In the share projects I have added dashlets, pages and sites. These projects are all deployed on the same Alfresco server instance on which both alfreso.war and share.war are deployed. The table below shows a resume of the customisations done in each projects. The customisations are described in further details in the blog:

Project / Customisation

Custom Repo A

Custom Share A

Custom Repo B

Custom Share B

Master Share

Content Model

folderA extending cm:folder with
mandatory aspect A

 

documentB extending cm:content
with mandatory aspect B

 

 

custom-slingshot-[project]-context.xml

 

Resource
BundleBootstrap
Component=
alfresco.message.
customA

ConfigBootStrap=
share-
config-customA.xml

 

Resource
BundleBootstrap
Component=
alfresco.message.customB

ConfigBootStrap=
share-
config-customB.xml

 

share-[project]-config.xml

 

DocumentLibrary
subtype=folderA

visible
aspects=emailserver:aliasable

 

DocumentLibrary
subtype=documentB

visible
aspects=cm:generalclassifiable

 

Dashlet:

 

HelloWorld

http://code.google.com/p/share-extras/

 

 

MultipleRSS

http://code.google.com/p/share-extras/

 

 

Site:

1. presets.xml

2. create-site.get.js

3. <msg>.properties

 

 

 

 

customA.properties
title.CustomASite=…

 

 

 

 

customB.properties
title.CustomBSite=…

 

presets.xml

create-site.get.js

 

Page

 

Site-data/pages/
pageA.xml

 

site-data/template-instances/
templatePageA.xml

 

template/org/myCompany/pageA.ftl

 

site-data/components/page.content.pageA.xml

 

Site-data/pages/
pageB.xml

 

site-data/template-instances/
templatePageB.xml

 

template/org/myCompany/pageB.ftl

 

site-data/components/page.content.pageB.xml

 

Customising Alfresco Repository

Bean naming convention

The conflict that occurred when deploying multiple repository customisations (conflict #1 described above) was due to improper naming convention.

In order to avoid these errors in the future we agreed to prefix bean id’s with myCompany.myProject.

It would be natural to name the content model myCompany.myProject:model. This is unfortunately not possible. Alfresco will show an error in the log when you try to submit changes via the edit metadata form (WARN [processor.node.NodeFormProcessor] Ignoring unrecognised field ‘prop_myCompany#dot#CustomB_myName’) and the metadata will not be persisted.

For our models we have instead adopted the following naming convention: myCompanyCustom:model

Customising Share

In this section I will list some best practices for customising share still with focus on avoiding conflicts between different customisation projects

custom-slingshot-application.xml

Instead of overriding the standard custom-slingshot-application.xml you should create a project specific custom-slingshot-[project].xml configuration file for defining your beans.

share-config-custom.xml

Customising Share is for a great part done in the file share-config-custom.xml but rather than using this file I would recommend to create a project specific version (share-[project]-config.xml) and load this file from within custom-slingshot-[project].xml. This is illustrated below:

<!– Override the config source to include Web Framework Commons and Share config –><bean id=“customA.custom.config” class=“org.springframework.extensions.config.ConfigBootstrap” init-method=“register”>
<
property name=“configService” ref=“web.config”/>
<
property name=“configs”>
<
list>
<
value>classpath:alfresco/web-extension/share-config-customA.xml</value>
</
list>
</
property>

</
bean>

The most import thing to remember when defining your share-[project]-config.xml is not to specify the replace=”true” attribute in the <config> element. This attribute will cause your configuration to override similar configuration specified in other customisation projects. This was the cause of both conflict #2 and conflict #3 described above.

Dashlets

A dashlet typically consist of several parts: web-tier web scripts and repository-tier web scripts. The recommendation here is to follow the guidelines from the Sample Project http://code.google.com/p/share-extras/wiki/SampleProject

custom developed web-tier web scripts are placed in:

  • alfresco/site-webscripts[/org/myCompany/myProject ]

existing web-tier scripts that you want to override are placed here:

  • alfresco/web-extension/site-webscripts[/org/myCompany/myProject ]

For repository-tier web scripts, place scripts under

custom developed repository web scripts are placed in:

  • alfresco/templates/webscripts[/org/myCompany/myProject]

existing repository scripts that you want to override are placed in:

  • alfresco/extension/templates/webscripts [/org/myCompany/myProject]

Furthermore a dashlet component may consist of additional resources (js, css, images, etc.). These can be located in:

  • share[/org/myCompany/myProject ]

In this case you should link to the resources from you freemarker template using the syntax:

<img src="${url.context}/res/myCompany/myProject/components/dashlets/image.png" alt="Image description here" />

Sites

Defining a site in Alfresco involves customising three files. These are:

presets.xml ../tomcat/shared/classes/alfresco/web-extension/site- data/presets

create-site.get.js ../tomcat/shared/classes/alfresco/web-extension/site- webscripts/org/alfresco/modules

<msg>.properties (configurable location)

You will notice that presets.xml and create-site.get.js are located in the shared directory and it is unfortunately not possible to use individual names for each project. The consequence is that if a new project is deployed it will overwrite previously deployed projects customisations!

There are a couple of methods to circumvent this problem:

  1. Create the site using bootstrap. This is method is best suited when there must exist exactly one site
  2. Create a master project which contains customisations which are common across projects. This is the approach I will describe in this blog.
  3. Create a customised dashlet with the purpose of creating the project specific site
    This approach is used in the Alfresco's Record Management Module (see
    http://forums.alfresco.com/en/viewtopic.php?f=51&t=22461)

Master share and repo projects:

A Master share and repo project should contain the configuration files of which only one can exist.

There are several benefits using a master share and project. The master share project can contain configuration which is common for all projects e.g. single-sign on configuration.

The sites I have created for the custom share A and custom Share B projects are referred in presets.xml like this:

<presets>
<!-- CustomA Site
dashboard -->
<
preset id="customA-site-dashboard">
<
components>

............
<
sitePages>[{"pageId":"pageA"}, {"pageId":"documentlibrary"}]</sitePages>
</
properties>
</
page>
</
pages>
</
preset>
<
preset id="customB-site-dashboard">
<
components>
<!-- title -->
<
component>

............
<
properties>

<sitePages>[{"pageId":"pageB"}]</sitePages>

</properties>
</
page>
</
pages>
</
preset>

Also the create-site.get.js is defined in the common master share project like this:

var sitePresets = [{id: "customA-site-dashboard", name: msg.get("title.customASite")},
{id:
"customB-site-dashboard", name: msg.get("title.customBSite")},
{id:
"site-dashboard", name: msg.get("title.collaborationSite")}];

model.sitePresets = sitePresets;

I also created a master repo project. However I did not use it for this post. I envision that a master repo project could be used to define a common content model which the individual customisation projects could inherit from. I haven't tried it though.

Conclusion:

After developing and deploying the 5 projects using the guidelines described in this post I did not discover any conflicts. I am able to create sites of both type “Custom Site A” and “Custom Site B”. However the developed components are not project specific. This means that if I create a Site of type “Custom Site A” I am still able to add a page B (defined in Custom Share B project) to this site. I am also able to able to add dashlet MultipleRSS to site A (MultipleRSS is defined in Custom Share B). Visible aspects defined both project A and project B are visible for all documents.

I don't see this is a problem. It is the responsibility of the site administrator to add relevant components to a site.

An alternative method to avoid conflicts in the share instance is of course to have a dedicated war file for each customisation project. This might be a good solution in some cases even though there a some overhead involved with this solution. However following the guidelines in this post you a free to decide if your project should be deployed in the common share instance with other projects or if you decide to have an individual [project].war file. [project].war is a copy of share.war with your customisations applied.

This entry was posted in Uncategorized. Bookmark the permalink.

11 Responses to Implementing Multiple Project Customisations in one Alfresco instance

  1. Wiley says:

    This post will help the internet visitors for creating new bllog orr even a bloog from start to end.

  2. Pat says:

    Spot on with this write-up, I truly believe that this web site needs a lot more attention. I’ll probably be back again to read through
    more, thanks for the information!

  3. Magnificent website. A lot of useful information here.
    I am sending it to several pals ans also sharing in delicious.
    And obviously, thanks on your effort!

  4. It’s very trouble-free to find out any topic on web as compared to books, as I found this paragraph at this site.

  5. Niby obszyć pokrycia na miejsca ażeby obszyć owinięcie na miejsce wymyśliła
    trwające skrawki środków Fragmenciki ucinała na podwalinie zasług krzesła,
    spajając po 1 cm na przeszycie + ew. 1,5 na zakończenie.

    W fundamentalnej chronologii wykończyła dookoła falbankę Po przeniknięciu również Po przeszyciu brzegów futerału w rezultacie schyłkowym bieżąca transza winna spoglądać Gdy zaraz wsio
    obszyjemy kumulujemy dwa kawałki: siedzisko+oparcie Bieżąco znając prędko rozciągłość falbanki potrafimy
    dopasować odległość wezgłowia
    zaś obrobić nie zaszyte niskie podzespoły podtrzymania -
    oraz odtąd przygotować peryferyjne zakuwania (moje spajania stanowiły ślepiów 40cm

  6. inaczej wcale nie egzystowałoby one eksploatowane. Zaklep agregatu second hand pragnie przechodzić serdeczny
    reżim do eksploatacji tychże darowizn tudzież sklepy
    te przeważnie oferują wielostronne gratek gwoli niekiepskich sprawiających,
    aby potrafili wystać dotychczas ciekawsze bitwy naciągaj naturalnie.

    Inteligentni odbiorcy umieją w szczytowi wyłudzić współczesne wykonalności.
    Żyje chwila manier, które silna wyłudzić, ażeby zjadać

  7. Przyległe oczyszczalnie rynsztoków są jeszcze srodze tanią możliwością
    dla rozpasań bezodpływowych w stanowiskach, gdzie
    nie planuje kanalizacji. Wbrew wydatniejszych nakładów armaturze jeszcze ławica dam się na takie wyładowanie

  8. Oczywiście także tyle wygłosiła, gdyż uderzyła najzdrowsza latorośl mojej podopiecznej również
    przyniosła nam zarąbiste ciasto śliwkowe,
    mniam. Z następującego tygodnia dotykają się wakacje jesienne i dwie spośród nich pozostawiają na ferie

  9. Zarobione baksy, niekwitnące flory (najczęściej pokrzywy) składamy pojedynczo w kadzi
    przyciężkiej, plastikowej ceń wiadru zaś skrapiamy starką (celująco deszczówką

  10. Lowell says:

    Both stimulants and appetite suppressants Appetite suppressant medications on the bright side.
    And a lot about fat loss should not go empty for a year.
    Preparing it self for another” starvation” mode.
    There’s more.. much more success by simply pulling out the bookstore.
    Like every human body that makes it a perfect chance to rob you of the weight problem!

  11. Tamera says:

    Das alleine reicht schon aus, denn kurz nach der Anmeldung könnt ihr Frauen zum
    ficken in eurer Nähe suchen Ihr könnt entweder selbst auf die Suche
    gehen, oder euch die Mitglieder anzeigen lassen, die am besten zu euren Wünschen passen.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>