Month: September 2010

Book Review: Alfresco 3 Web Services

I’ve just finished reading Alfresco 3 Web Services, by Ugo Cei and Piergiorgio Lucidi, which Packt sent me to read and comment on.

Alfresco 3 Web Services is meant for developers with a very specific focus: Remotely talking to Alfresco. That might mean communicating via SOAP-based Web Services, RESTful web services (Web Scripts), or either protocol through CMIS. Whichever you choose, Ugo and Piergiorgio have you covered. I really like that the authors set out to write such a focused piece and stuck to it–it allows them to go deep on their topic and keeps the chapter length and total book length digestable.

The book is written very clearly and follows a logical progression. It starts out with SOAP-based services (first 5 chapters), including a chapter on .NET, and then moves on to web scripts (3 chapters). After that, the authors discuss AtomPub, which is an interesting, but not critical, background for the remaining 5 chapters of the book which focus on CMIS.

The discussion on web scripts covers both Java and JavaScript controllers, but JavaScript definitely gets more attention. Something developers new to the platform will find helpful is the chapter on FreeMarker. Most of Alfresco’s documentation and the books that are out there (including mine) relegate the FreeMarker API to appendices or just show examples and assume you’ll look up details later when you need it. Because it is typically such a key component of web scripts and other aspects of Alfresco, it was a good call to include it in the book.

The book comes with several small examples and a couple of tie-it-together examples. None of it runs out-of-the-box without some tweaking which isn’t a surprise given how rapidly things are changing in this area, particularly with regard to CMIS. At the time the book was written, OpenCMIS, the Java API for CMIS available as part of Apache Chemistry, had not been officially released. As I write this, the Chemistry team is about to release their second tagged build. The differences aren’t significant enough to cause confusion–most readers will be able to fidget with the import statements and the other changes required to get the sample code running.

I thought there was a little too much time devoted to SOAP-based Web Services, but that’s just personal preference and the fact that nearly all of my clients over the last four years have gone the RESTful route. The authors note that others may have the same preference and they make it easy to skip over those chapters if the reader wants to.

Although the chapters logically progress and build on each other, the code samples don’t–for the most part, each chapter’s code samples are self-contained. For example, I thought it was kind of strange that the code built in Chapter 13 for the CMIS Web Services binding examples isn’t used in Chapter 14 to build the CMIS Wiki example.

Many Alfresco implementation teams are divided into at least back-end and front-end teams and when the project is large enough, you can definitely have people focused on the middle. This book is perfect for that middle-ware team or for anyone who’s got a handle on the back- and front-ends and just needs to learn how to stitch them together. Nice job, Ugo and Piergiorgio.

7 mistakes developers make when customizing Alfresco Share

I’ve seen more than my–ahem–fair share of Alfresco Share over the last several months. Many clients feel that their needs are so close to what Share provides out-of-the-box, that they can save time and money by starting with Share as the basis for their custom content-centric application. Whether or not that’s a good idea is the subject of another post. This post assumes that, for whatever reason, you find yourself customizing Alfresco’s Share client and wondering what are some of the common pitfalls to avoid. Here’s seven. Feel free to add to the list.

1. Ignoring client-side JavaScript minification

Here is a massive understatement for you: Alfresco Share has a lot of client-side JavaScript files. Most, if not all, of these are minified, or compressed, to reduce the size of a given page and increase client-side performance. If you’ve ever looked at the FreeMarker source for one of Alfresco’s pages, you may have seen something like this:

<@script type="text/javascript" src="${page.url.context}/components/blog/blog-common.js">

It looks like an everyday JavaScript reference but what’s up with that “@script” tag? It’s a FreeMarker macro. It switches out the JavaScript source file for the minified version when debug is turned off and uses the original uncompressed source when debug is turned on, which makes stepping through the client-side JavaScript much more pleasant.

There are two things you need to be aware of here. First, if you find yourself tweaking Alfresco’s client-side JavaScript, you’ll need to remember to deploy both the expanded and minified version of the file. Otherwise, when people turn debug on and off, they’ll see different results. Second, when you create your own client-side JavaScript, you need to minify your own code for the same reason.

You could turn debug on and leave it on (bad idea) or you could use a “normal” script tag and point to the non-minified versions of your JavaScript, but it is really easy to add minification as a part of your build, so you might as well set that up early in the project and you won’t have to worry about it later.

There are several JavaScript compressors out there. Here’s a link to the YUI Compressor. You can drop the JAR into your project and then invoke it from Ant quite easily. Ask Google for some examples.

2. Assuming Alfresco and Share are on the same host

When you install Alfresco it deploys a web application in the “/alfresco” context–that’s your repository and the old Alfresco Explorer client–and a second web application in the “/share” context. Depending on what you’re doing you might deploy numerous additional web apps based on Share or Surf.

Regardless of how you choose to deploy, you need to remember that there is no guarantee your app and Alfresco will be on the same machine, app server, or port number. One of the beauties of the Surf architecture is that you can scale it out across multiple app servers and they can all talk to the same (or multiple) Alfresco repository servers. The underlying Surf framework on which Share is based has configuration and helper variables you can leverage to deal with this. You should not be hardcoding “localhost” or any other hostname in your Share code.

3. Incomplete theme customization

Alfresco Share 3.3 has user-selectable themes. As part of your customization effort you can define your own theme and then configure that to be the default. An easy way to create your own theme is to copy one of the out-of-the-box themes and then modify it to suit your needs. The keys to cloning a theme successfully are:

  1. Copy one of the themes other than “Default”
  2. Search and replace references to the old theme name in the new CSS files (login.css, presentation.css, and yui/assets/skin.css)
  3. In the previous step, don’t forget yui/assets/skin.css!

4. Duplicating, rather than extending, Alfresco web scripts

Suppose you want to change something in one of Alfresco’s web scripts. You may be tempted to change the out-of-the-box controller JavaScript or FreeMarker views, but don’t do it. A nice thing about the web script framework is that you can override even just a single file that is part of a web script by placing your version of the file with the same name in the same folder structure under web-extension. This also works on the repository tier, but instead of web-extension you use the “extension” directory.

For example, maybe I want to extend the document-actions config XML in Share with my own settings. I will NOT copy my version over the top of Alfresco’s. Instead, I’ll put my copy in a file named “document-actions.get.config.xml” under WEB-INF/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/document-details. When Alfresco loads the web script, it will use my version of the config.

5. Not using the web-extension directory

While we’re on the topic, all of your custom Share config files go in web-extension under the Share web application. Don’t put them in $TOMCAT_HOME/shared/classes and don’t put them in the Share web app’s classes/alfresco directory. Use the web-extension directory to keep your stuff separate from Alfresco’s. I also recommend doing the same with your client-side files–create a directory called “extension” for your client-side JavaScript, images, CSS, and so-on.

6. Using the same Tomcat server as the Alfresco repository during development

This one isn’t going to cause you problems, but it sure will slow you down. Even if your production Share web app will run on the same Tomcat as the Alfresco WAR, do yourself a favor: While you’re coding, use two Tomcats. On port 8080, you’ll run Alfresco and out-of-the-box Share. On some other port you’ll run a second Tomcat server with your custom Share- or Surf-based web app. That way, when you need to restart your custom Share app, you don’t have to wait for the repository to start back up. You’ll cut way down on the time you spend waiting for Tomcat to restart which, over time, can speed up your development cycle tremendously.

7. Failing to test on Alfresco’s supported browsers

Have I mentioned how much client-side JavaScript there is in Share? Every time you touch Alfresco’s JavaScript or create your own, you’ll need to test it on the browsers your client intends to use. So there are two recommendations here: First, make sure you are testing across Alfresco’s supported browsers. Second, make sure your clients only expect to use Alfresco’s supported browsers. Failure to do both of these can lead to some missed expectations on both sides. The browsers Alfresco supports for 3.3 are on the supported stacks page on the Alfresco web site.

What am I missing? Add a comment with your Alfresco Share street smarts.