Visualising Geotagged Content with Google Maps

February 28th, 2011 by Will Abson

Following Steve Reiner’s Twitter post last week, I was inspired over the weekend to add a similar Google Maps-based dashlet to share-extras, to show the locations of geotagged content items on a map view.

Since the repository has full support for extracting geographic data using Tika in version 3.4, all I needed to do to assemble some test content was upload a few photos taken on my phone into the site Document Library.

If you look at the Document Details page of a geotagged photo, you’ll see that this displays a latitude and longitude value at the end of the item’s properties list. These are part of a new aspect named Geographic.

Latitude and Longitude on the Document Details page

Latitude and Longitude

Using Firebug’s Net console, I noticed that the JSON data for the document list view makes these values available on a new geographic property placed on each list item.

Firebug Net Console

Firebug's Net Console

So to keep things simple the initial version of the dashlet simply re-used the doclist web script to grab a list of all content items in the root of the document library space, but the final version now on share-extras comes bundled with a dedicated webscript to list all items in the site that have the Geographic aspect applied.

Using this data, the dashlet displays a marker for each geotagged item, auto-centering itself on the centre point of all the items.

Clicking on a marker takes you to the Document Details page for that item. In the next update I’ll look at displaying a snippet of information for the item, which the Google Maps API makes pretty easy.

From Web Scripts to Portlets with Alfresco 3.4

February 17th, 2011 by Will Abson

Since Alfresco 3.2r the ProxyPortlet support in Alfresco Share has allowed developers to easily embed specific bits of Share functionality into a portal such as Liferay, using only a small amount of XML configuration to wire in existing web scripts.

This support has been substantially improved in version 3.4 of Alfresco, in order to allow the entire Share Document Library page to be embedded within a portal. Unfortunately the changes mean that the steps in Luis’s original tutorial no longer work in the latest version.

As one of the features we demonstrated today at our Madrid event was the Doclib portlet, I managed to get five minutes to get the original web script-backed method working too.

Since the CMIS repository browsing web scripts used in Luis’s example are no longer shipped with Share, I used my own Hello World dashlet from share-extras as a starting point instead. The web script is basic, but demonstrates displaying a simple greeting to the user including their user name.

Hello World Portlet

The following steps should work using a recent version of Alfresco 3.4 and Liferay 5.2.3 running as the portal, provided that the two components are first set up as per the Installing and Configuring instructions for the Doclib Portlet.

Once you’ve set everything up, the first thing to do is to add the web script files to the instance of Share that you have already deployed to Liferay. Since you should already have created some directories in Liferay’s tomcat-x.x.x/shared/classes directory to define your share-config-custom.xml, the easiest thing is to create a new directory named site-webscripts within the existing tomcat-x.x.x/shared/classes/alfresco/web-extension and place the following files in it.

org/alfresco/test/hello-world.get.desc.xml

<webscript>
   <shortname>Hello World</shortname>
   <description>Displays Hello World text to the user</description>
   <authentication>none</authentication>
   <url>/test/hello-world</url>
</webscript>

org/alfresco/test/hello-world.get.html.ftl

<html>
   <head>
      <title>${msg("header")}</title>
   </head>
   <body>
      ${msg("label.hello", user.id)}
   </body>
</html>

org/alfresco/test/hello-world.get.properties

header=Hello World!
label.hello=Hello {0}

With those files added, you’ve successfully defined the web script that we’ll wire into Share in the next section.

Now although the web script itself will be automatically picked up by Share at load-time, some additional config is also needed in web.xml for the ProxyPortlet to work in version 3.4.

The following lines, which define a custom servlet and servlet mapping which will be invoked by the ProxyPortlet, should be placed in the web.xml file belonging to the Share instance which has been deployed in Liferay. You should find the path to this will be something like <LIFERAY_HOME>/tomcat-6.0.18/webapps/share/WEB-INF web.xml (if you have not already started Liferay you will need to do so to force it to deploy share.war and create this structure).

   <servlet>
      <servlet-name>HelloWorld</servlet-name>
      <servlet-class>com.liferay.portal.kernel.servlet.PortletServlet</servlet-class>
      <init-param>
         <param-name>portlet-class</param-name>
         <param-value>org.alfresco.web.portlet.ProxyPortlet</param-value>
      </init-param>
      <load-on-startup>0</load-on-startup>
   </servlet>
   <servlet-mapping>
      <servlet-name>HelloWorld</servlet-name>
      <url-pattern>/HelloWorld/*</url-pattern>
   </servlet-mapping>

You can place these two definitions anywhere within the top-level <web-app> element, but for consistency I always try to add them next to the existing <servlet> and <servlet-mapping> definitions.

Now you’ve done all you need to do to configure the scripts, we can move onto configuring the matching portlet definition which will be picked up by Liferay.

In the same WEB-INF directory where you modified web.xml you should find a file named portlet.xml, to which we add our new definition.

   <portlet>
      <description>Hello World</description>
      <portlet-name>HelloWorld</portlet-name>
      <portlet-class>org.alfresco.web.portlet.ProxyPortlet</portlet-class>
      <init-param>
         <name>viewScriptUrl</name>
         <value>/page/test/hello-world</value>
      </init-param>
      <supports>
         <mime-type>text/html</mime-type>
         <portlet-mode>VIEW</portlet-mode>
      </supports>
      <portlet-info>
         <title>Hello World</title>
         <short-title>Hello World</short-title>
      </portlet-info>
      <security-role-ref>
         <role-name>administrator</role-name>
      </security-role-ref>
      <security-role-ref>
         <role-name>guest</role-name>
      </security-role-ref>
      <security-role-ref>
         <role-name>power-user</role-name>
      </security-role-ref>
      <security-role-ref>
         <role-name>user</role-name>
      </security-role-ref>
   </portlet>

Add this right after the existing <portlet> definitions (which if you look at further it should be obvious define the three Doclib portlets) and save your changes.

Getting these details right is crucial if you’re deploying your own web scripts, so a couple of notes on this are probably useful.

  1. The contents of the <portlet-name> element must match the name of the servlet mapping you have defined in web.xml
  2. The viewScriptUrl parameter must match the URL of your web script, with a prefix of /page added to the beginning (note that in 3.2r the web app context path was also required in the URL, but this now causes an error if supplied)

Lastly you should add the portlet to the two Liferay-specific configuration files in WEB-INF to ensure that authentication is handled correctly and also that the portal appears in the correct category in Liferay’s Applications menu.

In liferay-portlet.xml add the following definition after the existing <portlet> elements

   <portlet>
      <portlet-name>HelloWorld</portlet-name>
      <user-principal-strategy>screenName</user-principal-strategy>
   </portlet>

In liferay-display.xml, add the following within the existing <category> element – it should be obvious that this is adding your portlet to the ‘Alfresco’ category.

<portlet id="HelloWorld"></portlet>

You’ll need to restart Liferay to get it to pick up the new portlet, and for Share in turn to load the additional web script. Once it’s finished loading you should be able to follow the configuration steps in the Doclib Portlet guide to walk you through adding it to a page.

The example is basic, but shows how you can add a web script as a portlet, with a small amount of personalisation based on the identify of the user.

It’s possible to add more complex web scripts, for example to load data from the Alfresco repository or other back-end data sources, but as Luis points out you should be careful how you render any hyperlinks within your scripts, to ensure that they are portal-safe.

To make sure that your URLs are correctly generated, please use the “scripturl()” function in your Freemarker templates to wrap them:

<a href=”${scripturl(url.serviceContext + “/sample/cmis/repo”, false)}”>CMIS Repository</a>

You can download the web script files used in this example in JAR format, which you can extract using any unzip program into the directories specified above (or even easier – simply drop the JAR file itself into Liferay’s tomcat-x.x.x/shared/lib folder).

Share Import-Export 1.1 released

February 11th, 2011 by Will Abson

The v1.1.1 release of Share Import-Export has been up for a few days now, but I wanted to summarise some of the changes in the new version.

The most significant addition is support for importing and exporting security groups in JSON format, via the new import-groups.py and export-groups.py scripts.

As well as this the import-users.py script has been made slightly more flexible, with the addition of a --users argument to allow you to import just a few users from a larger set. Since the sample data contains a large number of users that are used across all the different sample sites, you can now import just the users you need for a particular site.

As well as these functional improvements I’ve started cleaning up the code internally, an area I intend to focus a little more on over the next few weeks. For now I’ve just cleaned up the docstrings within each script, and updating the --help flags to re-use the usage information in there.

Last but not least, I should thank Dick from Formktek for reporting an issue with the user export script, which was causing some exported profile images to become corrupted when saved.

Beyond a few more tidy-ups the code is almost where I want it to be within the current constraints of the repository. But there have been a couple of ideas suggested for future uses of the scripts, so if there’s a particular purpose you think the scripts could have or you just want to share your experiences, please leave a comment below.

Importing and Exporting Share sites

December 3rd, 2010 by Will Abson

I managed to get a bit of time on my flight to Lisbon the other day to make a few last changes to a tool I’ve been working on on and off for the last few weeks, to provide a standard way of loading (and dumping) the contents of Share sites for demonstration content.

I’d considered ways of doing this in the past, mostly when I’ve got frustrated with setting up sample content in the new Share instances I usually create for demos. Bootstrapping content via ACP files is the usual method of loading content that’s employed by Alfresco’s own patches, but that didn’t really feel flexible enough and in any case, isn’t able to package up some of the data which makes up a Share site, such as configuration stored in the sitestore AVM store.

I also wanted a tool which allowed content to be imported into an Alfresco instance running on a local machine, but also on remote machines as well. Sometimes I demo locally but other times I fire up one of my Amazon images instead. So it seemed like an external process was required.

Then we started discussing a few weeks ago what additional tutorials and sample content we could provide to partners to coincide with the upcoming Enterprise 3.4 release, and the possibility of reusing some of the great demo content from the Alfresco Cloud Trial. There seemed some overlap.

The result is this project, which I’m tentatively naming Share Import-Export, and which provides a set of Python scripts that can export site-based content and user information from Alfresco Share, and import that content into another Alfresco Share server. Some sample content is also provided from the Cloud Trial environment, kindly supplied by Paul Hampton.

The package is intended to help set up demonstration environments quickly, reliably and consistently. The scripts are not suitable for importing or exporting large volumes of content or for any general production use such as system backups.

The scripts work with versions 3.3 and 3.4 of Alfresco, and can work against 3.2 with a couple of small tweaks. No additional customisations are needed in Alfresco or Share, so you can export data from existing systems without any fuss.

What can be imported/exported?

For sites

  • Site configurations
  • Site members (users only at present)
  • Site dashboards, including dashlet configuration
  • All content held within the site (manual export via ACP)
  • Records Management sites (must have RM installed)
  • Web Quick Start sites (must have WQS installed)

For users

  • All profile information, including profile images
  • User dashboard configurations
  • User preferences
  • User groups and group memberships

What is not imported/exported?

  • Document categories and tags (not currently supported by ACP format)
  • User passwords and account enabled flags (all accounts enabled)
  • Activity feed entries
  • File system-level customisations (e.g. custom dashlets) and configuration

How does it work?

The scripts mimic a web browser logging into the Share web application, then invoke a number of mostly JSON-based web scripts to read and write data to and from the application. JSON is also used as the format for storing exported metadata and user information, since it is well-structured, human readable and lightweight. Python has strong support for JSON data via the json module. ACP format is used to package up site content.

Download and Usage

Downloads and more information can now be found on the Share Import-Export project page.

Contributing

You can help by testing the scripts against your own test data and posting feedback, either by adding a basic comment below or (even better) by posting feedback in the Issues section.

You are welcome to redistribute the tools under an Apache 2.0 license and encouraged to submit any enhancements you make.

Demo Tomcat Packages for Alfresco 3.4

September 30th, 2010 by Will Abson

Downloads and more information can now be found on the dedicated Tomcat Bundles page.

The eagle-eyed amongst you will have noticed that starting with Alfresco 3.4 a number of changes have been made to the way in which Alfresco binaries are packaged for distribution.

The new Bitrock installer makes installing the server much less challenging for new users and offers more control for power users. Also welcome should be the general tidying up that has gone on, with most packages now standardised as ZIP files, hopefully ending the which-file-should-I-download confusion.

The only casualty has been the Tomcat bundle packages, which are no longer shipped due to the overhead in maintaining these separately from the Bitrock stack and WAR bundles.

Now while they’re both great for experimental users and system admins respectively, it doesn’t beat the sheer speed of unzipping a ZIP file and double-clicking alf_start.bat, the method I’ve always used to quickly spin up demo or test instances on my Windows system. So, I packaged up my own unofficial Tomcat demo bundle for 3.4.

From 3.4.b I’ve added a Linux bundle based on the same components, but with my own alfresco.sh script that can be used to stop and start the server. It should work exactly the same as the old Alfresco Tomcat .tar.gz bundles, but with a dedicated MySQL also included.

Downloads and more information can now be found on the dedicated Tomcat Bundles page.

Adding dates in alfresco.log

July 20th, 2010 by Will Abson

By default, Alfresco’s log4j configuration specifies that only the current system time, and no date, are output as the first entry in log messages output in alfresco.log, producing output such as the following.

12:21:23,658 INFO [org.alfresco.config.JndiPropertiesFactoryBean] Loading properties file from URL [file:/home/wabson/Downloads/alfresco-enterprise-tomcat-3.3.1/tomcat/shared/classes/alfresco-global.properties]
12:21:24,009 INFO [org.alfresco.config.JndiPropertyPlaceholderConfigurer] Loading properties file from class path resource [alfresco/alfresco-shared.properties]
12:22:40,726 INFO [org.springframework.extensions.webscripts.TemplateProcessorRegistry] Registered template processor Repository Template Processor for extension ftl
12:22:40,747 INFO [org.springframework.extensions.webscripts.ScriptProcessorRegistry] Registered script processor Repository Script Processor for extension js
12:23:09,470 INFO [org.alfresco.repo.domain.schema.SchemaBootstrap] Schema managed by database dialect org.hibernate.dialect.MySQLInnoDBDialect.
12:23:11,774 INFO [org.alfresco.repo.domain.schema.SchemaBootstrap] No changes were made to the schema.

This is the line responsible for setting the configuration in log4j.properties (found in the root of the classpath in the alfresco webapp)

log4j.appender.File.layout.ConversionPattern=%d{ABSOLUTE} %-5p [%c] %m%n

That’s fine in theory, since the configuration also specifies that the log file should roll over using a date-based suffix on a nightly basis. However, in practice the log rotation can sometimes fail on running systems, leaving log entries spanning more than one day in a single log file and ambiguity over which day a particular message was output on.

Fortunately, log4j’s PatternLayout is quite flexible, and allows you to specify a date-time format instead (in fact, this is the default if no date format specifier is given.

To print the date in ISO-8601 format, e.g. “1999-11-27 15:49:37,459″, use

log4j.appender.File.layout.ConversionPattern=%d{ISO8601} %-5p [%c] %m%n

For classic date format, e.g. “06 Nov 1994 15:49:37,459″, use

log4j.appender.File.layout.ConversionPattern=%d{DATE} %-5p [%c] %m%n

To also add dates into the console logging output (which is redirected into Tomcat’s stdout logs when running as a service), update the property log4j.appender.Console.layout.ConversionPattern.

Refreshing Site Tags in Share

July 7th, 2010 by Will Abson

Sometimes the site tag data used in Share’s document library can get out of sync with the tags on the content itself, especially in older versions of the 3.x product.

I came across this today on the Partner Sales Enablement site that we’ve just launched fully today on partners.alfresco.com, but fortunately the tag scope data is easy to rebuild.

To do this, you need to create a small JavaScript file that will execute the ‘refresh-tagscope’ action against a space.

var refresh = actions.create("refresh-tagscope");
refresh.execute(space);

Once you’ve created this file (I called mine refresh-tagscope.js) in Data Dictionary > Scripts, use Alfresco Explorer to navigate into the documentLibrary space within the site you want to refresh, and click View Details from the More Actions menu.

You can then use the Run Action dialogue to execute the JavaScript file you’ve just created. You might also want to do the same for the site space itself, which also collects tag scope data.

Once that’s done you should be able to navigate back into the site document library in Share and you should find that the tag data has been fully refreshed!

Site Blog Dashlet for Alfresco Share

June 29th, 2010 by Will Abson

Updated December 2010: Site Blog Dashlet is now hosted on Share Extras.

This extension to Alfresco Share provides a custom Site Dashlet, which displays the most recent ten posts from the site blog component.

Site Blog Dashlet

Site Blog Dashlet

To install the dashlet download the ZIP file package the latest blog-dashlet.jar file from the Share Extras project and extract the contents into the tomcat directory of your Alfresco installation drop it into tomcat/shared/lib or WEB-INF/lib inside the Share webapp. The package will install the dashlet web script and a single CSS file.

Also pictured in the screenshot is the Site Tags Dashlet, which displays a tag cloud visualisation for all the tags within a site.

Share Custom Actions in a JAR

February 28th, 2010 by Will Abson

Update, 4th May 2011: The Backup action is now part of Share Extras and documentation and downloads are now available on the Custom Backup Action page.

Since the ability to package Share extensions was added in the HEAD codeline some weeks ago, both Kev and myself have demonstrated how you can package up dashlets in a JAR file for deployment into Share.

The example we both used was my Site Tags dashlet that we showed at the Alfresco Meetups last year, but at the Madrid meetup we also showed an example of how Share’s Document Library can be extended with a custom ‘backup’ action.

Custom backup action

Document Library actions have no web-tier webscripts, but hook into the client-side actions framework using a bit of custom JavaScript. Each action has a small 16×16 icon and a bit of CSS code to apply this image, one or more text labels (which should of course be externalised for i18n goodness) and a bit of config to hook them into the app. Lastly, since most actions by their nature do something, it’s likely that they will make a RESTful call back to the repository to perform their work, which may require a custom webscript there.

That’s quite a few files, but fortunately we can use the JAR extension mechanism to package everything up nicely.

Just like the Site Tags dashlet, I set this up in Eclipse using a standard project layout and my share extensions build script (with a couple of minor changes) to build the JAR file.

To make it easy to copy this structure, I’ve uploaded a ZIP of the project directory, containing the following files

  • build.xml – the extensions build script
  • config/alfresco/messages/slingshot-custom-backup-action.properties – contains the strings used for the action label and confirmation/failure messages
  • config/alfresco/templates/webscripts – contains the repository-tier webscript used to create a back-up copy of the file
  • config/org/springframework/extensions/surf/slingshot-custom-backup-action-context.xml – Spring config used to initialise the i18n messages
  • config/spring-surf-config-custom.xml – not used at present, but could define additional Surf endpoints for calling third-party RESTful services
  • web – contains all client-side resources used by the action

It should be relatively easy to copy this structure to define your own custom action, following the custom action wiki document to understand what each file does. This will help you to build other actions that call back to the repository via a web script, but actions aren’t limited to calling Alfresco services only. For some examples, take a look at my own list of Share action ideas.

Once you have your structure you can build the JAR file using Ant, e.g.

ant -Djar.name=share-backup-action.jar

The JAR file can then be dropped into Tomcat’s shared/lib directory, and all that remains is to configure the document actions web scripts to pull in the action definition. This is the slightly fiddly bit.

Firstly, copy the web script configuration file WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/documentlibrary/documentlist.get.config.xml from the Share webapp into the directory alfresco/web-extension/site-webscripts/org/alfresco/components/documentlibrary in Tomcat’s shared/classes to override it. You should see a section <actionSet id="document"> which defines all the actions shown for a normal document in the document list view.

To add the backup action to this list, add the following line just before the </actionset> element for that block.

<action type="action-link" id="onActionBackup" permission="" label="actions.document.backup" />

If you also want the action to show up in the document details view, you need to copy the file WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/document-details/document-actions.get.config.xml into alfresco/web-extension/site-webscripts/org/alfresco/components/document-details in shared/classes in the same way.

Lastly, we need to ensure that the client-side JS and CSS assets get pulled into the UI as unfortunately the config files do not allow us to specify these dependencies.

To do this, we must override the file WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/documentlibrary/actions-common.get.head.ftl. Again, copy this into the corresponding directory in shared/classes/alfresco/web-extension and add the following lines at the bottom of the file.

<@link rel="stylesheet" type="text/css" href="${page.url.context}/res/components/documentlibrary/backup-action.css" />
<@script type="text/javascript" src="${page.url.context}/res/components/documentlibrary/backup-action.js"></@script>

That’s it. Now you can restart Tomcat and you should see the ‘Backup’ action – complete with UI labels and icon – in the Document Library.

Downloads

Adding Custom Aspect Support in Alfresco Share

February 25th, 2010 by Will Abson

Since Alfresco 3.2 introduced the ability to configure the metadata forms used in the Document Library, there have been several good articles published on how to add support for custom document types.

One of the first questions people often ask when they see Share is how they can easily extend the metadata fields that are stored against a document. Whilst this can be done using custom document types, aspects often provide a more agile solution.

So this article should explain how Share can be easily extended to support custom aspects using good practice techniques, specifically

  • Ensuring all extended configuration is placed outside of the share webapp, so protecting it from upgrades and redeployments, and
  • Using i18n labels for all text strings that appear in the UI, thus allowing translation of the labels.

The example provides a number of files, all of which should be placed below the tomcat/shared/classes directory of your Alfresco installation. If you are not using the Alfresco-bundled version of Tomcat then you may need to create this directory yourself and configure Tomcat’s shared classloader to use it.

First you will need to configure the repository with your custom model definition. In my case I am using a simple knowledge base model that defines a single aspect kb:referencable. The aspect adds a new text property that allows a unique KB reference number to be added to documents.

First, the Spring configuration defined in alfresco/extension/kb-model-context.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

    <!-- Registration of new models -->
    <bean id="extension.kb.dictionaryBootstrap" parent="dictionaryModelBootstrap" depends-on="dictionaryBootstrap">
        <property name="models">
            <list>
                <value>alfresco/extension/kb-model.xml</value>
            </list>
        </property>
    </bean>

     <bean id="extension.kb.resourceBundle" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
       <property name="resourceBundles">
          <list>
             <value>alfresco.messages.knowledgebase</value>
          </list>
       </property>
    </bean>

</beans>

Then, define the model itself in alfresco/extension/kb-model.xml

<?xml version="1.0" encoding="UTF-8"?>

<!-- Definition of Knowledge Base Model -->

<model name="kb:knowledgebase" xmlns="http://www.alfresco.org/model/dictionary/1.0">

   <!-- Optional meta-data about the model -->
   <description>Knowledge Base Model</description>
   <author>Will Abson</author>
   <version>1.0</version>

   <!-- Imports are required to allow references to definitions in other models -->
   <imports>
      <!-- Import Alfresco Dictionary Definitions -->
      <import uri="http://www.alfresco.org/model/dictionary/1.0" prefix="d"/>
      <!-- Import Alfresco Content Domain Model Definitions -->
      <import uri="http://www.alfresco.org/model/content/1.0" prefix="cm"/>
   </imports>

   <!-- Introduction of new namespaces defined by this model -->
   <namespaces>
      <namespace uri="http://www.alfresco.com/model/knowledgebase/1.0" prefix="kb"/>
   </namespaces>

    <aspects>
      <!-- Definition of new Content Aspect: Knowledge Base Document -->
      <aspect name="kb:referencable">
         <title>Knowledge Base Referencable</title>
         <properties>
            <property name="kb:documentRef">
               <type>d:text</type>
            </property>
         </properties>
      </aspect>
   </aspects>

</model>

The last file in our model definition adds some i18n labels for the aspect and property names. Add the following content to the file alfresco/messages/knowledgebase.properties.

# Custom knowledge base messages
kb_knowledgebase.property.kb_documentRef.title=KB Reference
kb_knowledgebase.aspect.kb_referencable.title=Knowledge Base Referencable
aspect.kb_referencable=Knowledge Base Referencable

With the model added the repository should start up without errors and will know about the new aspect. In order to use it, we need to configure Share to show this aspect in the Manage Aspects dialogue and to display the KB Reference field in forms, when a node has the aspect applied.

The file alfresco/web-extension/share-config-custom.xml can be used to do both these things.

<alfresco-config>

   <!-- Document Library config section -->
   <config evaluator="string-compare" condition="DocumentLibrary">

      <!--
         Used by the "Manage Aspects" action

         For custom aspects, remember to also add the relevant i18n string(s)
            cm_myaspect=My Aspect
      -->
      <aspects>
         <!-- Aspects that a user can see -->
         <visible>
            <aspect name="cm:generalclassifiable" />
            <aspect name="cm:complianceable" />
            <aspect name="cm:dublincore" />
            <aspect name="cm:effectivity" />
            <aspect name="cm:summarizable" />
            <aspect name="cm:versionable" />
            <aspect name="cm:templatable" />
            <aspect name="cm:emailed" />
            <aspect name="emailserver:aliasable" />
            <aspect name="cm:taggable" />
            <aspect name="app:inlineeditable" />
            <aspect name="kb:referencable" />
         </visible>

         <!-- Aspects that a user can add. Same as "visible" if left empty -->
         <addable>
         </addable>

         <!-- Aspects that a user can remove. Same as "visible" if left empty -->
         <removeable>
         </removeable>
      </aspects>

   </config>

   <!-- cm:content type (existing nodes) -->
   <config  evaluator="node-type" condition="cm:content">
      <forms>
         <!-- Default form configuration used on the document details and edit metadata pages -->
         <form>
            <field-visibility>
               <show id="kb:documentRef" />
            </field-visibility>
         </form>

         <!-- Document Library pop-up Edit Metadata form -->
         <form id="doclib-simple-metadata">
            <field-visibility>
               <show id="kb:documentRef" />
            </field-visibility>
            <edit-form template="../documentlibrary/forms/doclib-simple-metadata.ftl" />
         </form>

         <!-- Document Library Inline Edit form -->
         <form id="doclib-inline-edit">
            <field-visibility>
               <show id="kb:documentRef" />
            </field-visibility>
         </form>
      </forms>
   </config>

</alfresco-config>

This configuration will add the KB reference field at the bottom of the main Edit Metadata form, the pop-up edit form used in the document list view and lastly the in-line edit form used for HTML, text and XML content (introduced in Alfresco 3.3).

Note: More advanced control is possible over the placement of the field within the form, but this requires copying over the full form definitions for the cm:content type from the file alfresco/web-framework-config-commons.xml (or alfresco/share-form-config.xml in 3.3 onwards) inside the Share webapp and adding the attribute replace="true" on the <config> element.

Now that you’ve configured Share, you must restart Tomcat so that the changes are picked up. The application should start up and you should be able to add the aspect to some content and see the document reference field appear in forms.

The last thing to do is to add an i18n label for the Knowledge Base aspect in the Manage Aspects dialogue. To do this we need to define a small bit of Spring configuration in the file alfresco/web-extension/custom-slingshot-application-context.xml, which will wire the knowledgebase.properties file we created earlier into Share.

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

   <!-- Add Knowledge Base messages -->
   <bean id="webscripts.kb.resources" class="org.springframework.extensions.surf.util.ResourceBundleBootstrapComponent">
      <property name="resourceBundles">
         <list>
            <value>alfresco.messages.knowledgebase</value>
         </list>
      </property>
   </bean>

</beans>

In versions prior to Alfresco 3.3 (when some changes were made to the Share resource bundle classes) the following configuration must be used instead (note the different class name)

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE beans PUBLIC '-//SPRING//DTD BEAN//EN' 'http://www.springframework.org/dtd/spring-beans.dtd'>

<beans>

   <!-- Add Knowledge Base messages -->
   <bean id="webscripts.kb.resources" class="org.alfresco.i18n.ResourceBundleBootstrapComponent">
      <property name="resourceBundles">
         <list>
            <value>alfresco.messages.knowledgebase</value>
         </list>
      </property>
   </bean>

</beans>

This configuration tells Share to look in the file knowledgebase.properties for aspect labels, in addition to the core message bundles.

With that file added you should be able to restart Tomcat again and see the correct label in the Manage Aspects dialogue. You’ve now fully-customised Alfresco Share to support additional custom aspects.

Update: Thanks to Brian Ochs, who pointed out that the additional message aspect.kb_referencable is also required in knowledgebase.properties.

Update: The configuration files in this tutorial can now be downloaded in ZIP format. To use them directly extract the archive into tomcat/shared/classes and restart the server.


Alfresco Home | Legal | Privacy | Accessibility | Site Map | RSS  RSS

© 2012 Alfresco Software, Inc. All Rights Reserved.