Skip to content

Beginners Guide to Share and SURF

Dave Draper edited this page Jun 17, 2016 · 6 revisions

Alfresco Share is a Spring MVC web application. It includes the SURF view resolver. SURF views are defined with five key things:

  1. A system for expressing and layering XML configuration
    • These configuration files are found in many locations, primarily in the root of the classpath and in a subfolder of the same called Alfresco. The classpath includes /WEB-INF/classes, but also META-INF from JAR files and a few other locations.
  2. A way to describe domain objects such as pages, templates, regions, components, etc via XML files
    • These are found in the Share WAR under /WEB-INF/classes/alfresco/site-data
    • ??? Apparently there is a way to define custom domain objects that can then be expressed via similar XML configuration files
  3. A way to provide custom REST services via the WebScripts framework
    • WebScripts are found in the Share WAR under /WEB-INF/classes/alfresco/site-webscripts
  4. A declarative way to define how to connect to and authenticate with remote systems
  5. A way to describe view rendering templates with FreeMarker
    • These templates are found in the Share WAR under /WEB-INF/classes/alfresco/templates

This separation of concerns is not completely clean in-as-much-as WebScripts have their own dedicated XML configuration scheme and and FreeMarker based templating. Domain objects may also contain some configuration elements. Even so, as you would expect, the common configuration system is used to control many aspects of how Share and SURF work. Similarly domain objects reference WebScrtips and templates and WebScripts can use remote system definitions to obtain and format information for display.

So, when you browse to /share/page/<extra path info>, the SURF view resolver will review the page domain objects that have been defined and see if they match the <extra path info>. If so, SURF will begin to compose a page by recursively resolving domain objects referenced in the page. One of the lowest level domain objects is the component. Components, map to WebScripts. WebScripts then produce potentially dynamic elements for the page; often times using remote system definitions that were defined via the common configuration system to obtain dynamic information. Domain objects that are associated with templates are fed through FreeMarker and combined together to create the final page that is rendered to the browser.

Share includes default configurations for reaching the Alfresco repository as a remote system. It also includes, many pre-canned domain objects, WebScripts, templates and configuration files. All of these items together provide a feature packed web application for content management.

In addition Share adds a forms engine (???validate that this part of Share rather than SURF) that is used to present properties when creating and editing content. It is also used to define search forms among other things.

There are a number of ways to change and extend Share. Of course you can update and add to the files in place in the Share WAR file. If you ever need to upgrade Share and re-apply your customizations, this approach will be both time-consuming and error-prone. A better alternative is to use the (web-)extensions folders either in the WAR (packaged or exploded) or under tomcat/shared. For both of these approaches, we have historically packaged our customizations into AMP files.

The emerging best practice is to package our customizations into JAR files. And to use SURF extension modules to describe the components, webscripts and configurations we wish to add, update or delete. We can enable/disable these extensions at runtime. We can even use evaluators to enable/disable based on certain conditions dynamically (e.g. only apply for users in certain groups.) We have more control over the load order of extensions which can help with predictability. We are also able to target our customizations more precisely so that we don't have to copy-paste as many OOTB files. This is a huge deal as it reduces the number of files that have to be reviewed whenever we are upgrading our systems.


COMMENTS FROM DAVE DRAPER (I wasn't sure where to put these Bindu!)

I think it's going to be tricky to try and summarize Surf as an entity if you expect it to be a completely rational implementation. It has a very unusual history (which I won't go into) but suffice to say there were some ideas that were added by employees that have long since left Alfresco (before I even joined) that just don't make a lot of sense and aren't implemented properly. Part of the problem is that we've (Alfresco Engineers) have never had the opportunity to go back and fix or remove some of the more crazy stuff because all that has really been important is in making sure that it continued to support Alfresco Share (and it not being part of the main Alfresco code base for such a long time didn't help).

Basically there is a golden path through Surf that provides some really great things - and I would recommend that you try to focus on those things... yes, you can define your own Surf objects and configure different configuration paths and view modes and renderers - but frankly, why would you want to? In some ways this is what Aikau has attempted to do - to simply hide away the complexities and let Surf do the stuff that it does really well.

In my opinion the region/component model has never worked brilliantly - I remember being surprised at the inability to nest them. I've also never managed to get the any benefit out of trying to use scoping to try and get different behaviours out of templates/regions, etc.

The core capabilities I think to focus on are WebScripts (in particular the most useful thing would be a single resource outlining how to use all the in-built objects for getting things like arguments/request parameters/object properties and to explain how they can work in different contexts).

Other things that are useful are the URI templates for page matching as well as the authentication and security capabilities. The forms engine part of Share rather than Surf but it builds on the basic Surf XML configuration model.

It might also be useful to look at some of the ways in which you can reconfigure key beans (such as the "dependency.aggregator" and "css.data.image.handler" to exclude files from compression and LESS processing and the "css.theme.handler" for configuring an external Node server for LESS compression).

Describing how to switch between debug and production modes via config might be useful as well.

I'm not sure if these comments are helpful or not - apologies for just dumping them here!