Custom Web Previews in Share

Note: This post discusses how document previews may be customized in Alfresco Share 3.x. In version 4.0 onwards, an improved method is available, based on a plugin framework. See my presentation Customizing Web Previews at Alfresco’s DevCon 2012 event for more details.
I was asked by a partner today how one would go about enhancing the document details page in Share to better support previewing of specific file types.
Share’s built-in Flash previewer provides great browser-based previews across a whole range of different document types, from PowerPoint files to PDFs. But often you may only be dealing with a couple of different content types, and you may need a wider set of features in your viewer, specific to those content types.
Or, you may want to add support for an additional content type, not supported by the built-in web previewer.
Either way, it is not difficult to add support for other types of previewers. These could be based on Flash widgets, similar to the web previewer, or other technologies such as Java applets or ActiveX controls. Increasingly the HTML5 support in modern browsers, coupled with modern processors, can perform a lot of heavy lifting that previously required a plug-in.
A good example is provided by Share Extras, in the form of the Media Previews add-on. This uses a third-party Flash component to preview video and audio content in the browser, wrapped by a client-side JS module, but the basic approach is the same regardless of the technology you’re choosing. Basically, if you can embed a previewer or player on a website, you can integrate it into Share.

The first step is to read the documentation for the previewer you’re using. Work out which files are required to make it work and how they are referenced in the HTML mark-up on the page.
The files may consist of static resources such as Flash files, JavaScript scripts, CSS files and even compiled code packages (for Java/ActiveX). Sometimes they may be hosted on third-party servers, but normally you will need to bundle them yourself.
Assuming the latter case, you should add them into a new directory inside the Share webapp, and ideally in a collection of sub-directories within that. For example, the Media Previews files are placed in the directory /extras/components/preview, mirroring the structure used by Share’s web preview, but in a separate subdirectory reserved for Share Extras add-ons.
The next step is to modify the web script that hooks in the web previewer. You can find the files for this web-preview.get web script in the following directory in the Share webapp
WEB-INF/classes/alfresco/site-webscripts/org/alfresco/components/preview
Take a look in web-preview.get.html.ftl. You should see that it inserts the standard web previewer using a JavaScript module, instantiated inside a <script> element.
Now look inside the customised web-preview.get.html.ftl in the Media Previews source code. You will see that it uses a Freemarker <#if> directive to choose between the standard previewer and the custom ones, based on the content item’s MIME type.
Although the two custom previewers used here also use client-side code to instantiate themselves on the page, you could equally just use an <object> tag to reference the Flash .swf files directly. The benefit of wrapping the previewer with JavaScript code is that it allows you to apply more complex logic, such as detecting if the user has the correct version of Flash installed, or hooking the previewer into page events to update the preview when a new version of the content is uploaded.
Once you’re happy with the mark-up you want to add into the Freemarker file to insert your custom previewer, you can insert this into the file. But rather than overwriting the original, you should use Spring Surf’s override mechanism to separate your custom code from the original version.
To override the HTML template, take a copy of the web-preview.get.html.ftl and place it into the following directory, after first creating any missing directories.
<TOMCAT>/shared/classes/alfresco/web-extension/site-webscripts/org/alfresco/components/preview
When you reference your static files that you added into the webapp earlier, you should use URLs such as ${url.context}/mydir/path/to/asset.swf, or in 3.4 ${url.context}/res/mydir/path/to/asset.swf. The url.context variable will automatically resolve to Share’s webapp context path, i.e. share by default, and mydir/path/to should be the directory structure you created in the webapp.
To reference the item’s content by URL, you can use an expression such as ${url.context}/proxy/alfresco/api/node/${node.nodeRef?replace("://", "/")}/content in your Freemarker markup. To reference the content of a named thumbnail, add /thumbnails/imgpreview to the end of the URL, where imgpreview is the name of the thumbnail.
If your previewer does use some JavaScript code or custom CSS styles from additional files which you’ve bundled, you will need to reference these files in web-preview.get.html.ftl. See the customised web-preview.get.html.ftl in Share Extras for an example, and note the override mechanism is exactly the same as for the .html.ftl template. You are recommended to use the <@script> and <@style> macros provided by component.head.inc, but note that with <@script> you will need to bundle a compressed version of your JavaScript file(s) with the -min.js suffix.
When you’ve finished making changes in your override files you can put these into effect by refreshing Share’s list of web scripts or by restarting your Tomcat server.
Once you’re happy with your customisation, you’ll want to create a dedicated project structure to manage your source files. So Share Extras also provide a sample project, complete with directory structure and an Ant build script that can be used to package up your add-on in JAR format.