Obsolete Pages{{Obsolete}}
The official documentation is at: http://docs.alfresco.com
NOTE: This page describes the Alfresco Surf Platform which is included in Alfresco 3.0, 3.1 and 3.2.
If you are looking for information about Alfresco 3.3, please visit Spring Surf.
Back to Alfresco Surf.
__toc__
Alfresco Surf is a lightweight, scriptable web framework built on top of Alfresco's Web Script and Templating runtime. It provides web developers with the ability to quickly create web sites built around Alfresco content while utilizing familiar concepts such as pages, templates, components, themes and chrome.
Alfresco Surf installs as a web application. Typically, this web application is packaged as a WAR file. You might imagine Alfresco Surf as a WAR called 'surf.war' which is installed into a default Tomcat 6 instance. It is that simple.
Alfresco Web Content Management provides a robust Subversion-like repository which can manage all of the files of a web application - right down to the class files and source itself. However, Alfresco WCM doesn't have to do all of that. Rather, it provides us with a reliable tool for any of the following:
With Alfresco WCM, we can place any or all of these into a Web Project.
A Web Project is a workspace for all or some of the collaborators on a web site or web application. This could solely be the content contributors or it could everyone altogether. It's really up to the web site administrator.
Alfresco Web Content Management empowers Surf designers by providing them with the ideal set of tools for building Surf applications. Alfresco WCM automatically provides rich version control, snapshots, workflow, layering, branching and much more.
In addition, Alfresco WCM provides Deployment capabilities which allow your administrators to publish Surf-sites out to test and production. This keeps costs low by reducing the need for additional hardware, personnel or intermediaries.
Alfresco Surf can be configured in a variety of ways.
This section covers building and configuring Alfresco Surf.
As mentioned, Alfresco Surf builds as a WAR file and you can deploy it to a standalone Tomcat application server (or the application server of your choosing). The first thing we should therefore do is to build Surf itself.
Note: Those new to Alfresco should read through the general guide to setting up an Alfresco SVN Development Environment. This will give you access to the latest Alfresco code from our source control tree.
Once you have your environment set up, you should build using the incremental-surf-starter
build target. From a command line, you could run the following:
ant incremental-surf-starter
This will produce:
./projects/web-framework/build/dist/surf.war
This is your war file. It is prestocked with sample components and provides an excellent starting point for your web sites.
These sample components include:
Alternatively, if you didn't want any of the sample components and goodies, you can do the following:
ant incremental-surf
This will produce:
./projects/web-framework/build/dist/surf.war
This will build you a completely empty Surf web application - the bare minimum that you would need to get started.
Which one you use is up to you. If you intend to deploy Surf applications that were built with Web Studio, then you should build using the incremental-surf-starter
target. In general, this is the recommended target for folks to begin with.
Once you have the surf.war file, you can simply deploy it to your application server. Tomcat 6 is one such application server. It is an open-source application server and it is a favorite in the open source world, thus it is covered here.
You may have a different application server and that's fine. Feel free to follow along as this section may serve to provide a general guide.
First, download and set up Tomcat into a convenient place. You can download Tomcat from http://tomcat.apache.org. For the sake of brevity, let's assume that you install tomcat to the following directory:
/tomcat
Second, drop your surf.war
file into Tomcat's webapps directory:
/tomcat/webapps/surf.war
Third, modify catalina.properties so that configuration files are picked up from the /shared/classes and /shared/lib directories. This is a convenient thing to do as it will allow you to customize your Surf environment without modifying surf.war
:
/tomcat/conf/catalina.properties
Adjust the following and save the file:
shared.loader=${catalina.base}/shared/classes,${catalina.base}/shared/lib/*.jar
Alfresco Surf provides quite a lot of configuration options. We can tweak any of them within our Tomcat instance and we can now do so without having to change the surf.war
file at all. We can simply drop files into the /shared/classes
path.
Alfresco Surf has default configuration files which it will normally load. It also checks to see if we've provided any overrides. Our overrides take precedence. As such, we can use these overrides to get Surf to behave however we would like.
Fundamentally, there are two files that we will want to work with:
If we wanted to, we could drop these files into the following path in our Tomcat instance:
/tomcat/shared/classes/alfresco/web-extension
For a detailed overview of Alfresco Surf configuration options, please visit the Alfresco Surf Advanced configuration section of this Wiki.
If we take a look once more at our SVN, we can see that several example files are provided which will be useful in the coming sections. Take a look at the following path:
/projects/web-framework/config/alfresco/web-extension
You will find sample files for the various environments into which Surf can be deployed - preview, test and production. These are:
These can be copied into Tomcat's /shared/classes/alfresco/web-extension
folder. Remove the suffix so that each ends with XML. Tomcat will then pick these up when you next restart.
A very important concept in Surf is the idea of a Store. A store is a place from where Surf objects can be loaded. Surf objects are any of the following:
Another important concept is that of a Search Path. A search path is an ordered collection of stores.
When Surf needs to load objects, it looks through a search path to figure out where the objects are located. The first store that it finds with the object is the store that is used. The object is loaded and Surf moves on to the next thing.
The following types of stores are available:
Search paths consist of an ordered list of stores. You can use this mechanism to 'layer' your stores so that one store supersedes another. This allows you to override some Surf objects with other Surf objects.
In configuring Surf to run on different environments, it is wise to consider how you might architect your search paths to best accommodate the locations of your Surf files. A production server, for example, may be configured with a local file system store so that it can automatically pick up changes from a deployment event.
Stores and search paths are configured via Spring beans in the custom-web-framework-application-context.xml
file.
A good starting point is to consider the case where Alfresco Surf is running purely in standalone mode. This means that it is running completely detached from any Alfresco repository. It runs entirely from the classpath.
When might this be useful? Consider that you've built a web application using the Surf framework and have compiled it into a WAR file. All of the assets needed to run the web application are contained within the WAR. As such, Surf can load everything it needs from the classpath.
You may already be familiar with one web application which is exactly like this - Alfresco Share itself.
Alfresco Surf builds by default with classpath specific settings. That said, we'll focus this section on looking into the contents of the following two sample files:
The file custom-web-framework-application-context.xml provides definitions for how to look up web scripts and templates:
It also provides definitions for how to look up each of Alfresco Surf's model object types. These are defined in the following beans:
Finally, the file provides a few interesting overrides which allow us to control the caching of the web application. Note that by default the Surf application has caching enable. Here, in our configuration files, we turn caching off for both the Web Script and Template processors.
webframework.webscripts.templateprocessor
<bean id='webframework.webscripts.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.searchpath' />
<property name='updateDelay'><value>0</value></property>
<property name='defaultEncoding'><value>UTF-8</value></property>
</bean>
webframework.templateprocessor
<bean id='webframework.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.templates.searchpath' />
<property name='defaultEncoding'><value>UTF-8</value></property>
<property name='updateDelay'><value>0</value></property>
</bean>
The file web-framework-config-custom.xml provides configuration settings for the Surf web framework. This is a configuration service file which is loaded when Surf initializes.
Let's look at what is inside of it:
<persisters>
<cache-enabled>false</cache-enabled>
<cache-check-delay>0</cache-check-delay>
</persisters>
This block tells the Surf persister layer not to cache anything. The cache is disabled. You could also enable the cache and set the cache-check-delay to a positive number of seconds in order to have all model object persister cache using these settings. Finally, you also have the option to adjust caching on a per-model-object basis (not covered here).
<model-type>
<id>chrome</id>
<version>1.0</version>
<name>Chrome</name>
<description>Chrome</description>
<namespace></namespace>
<class>org.alfresco.web.framework.model.Chrome</class>
<search-path-id>webframework.searchpath.chrome</search-path-id>
<default-store-id>webframework.classpathstore.chrome</default-store-id>
</model-type>
This is one of several blocks that defines a Surf model object type. It defines the implementation class (so that Surf can manufacture backing beans) and tells Surf how to look up objects of the given type (which search path to use). It also defines which store to use by default when new objects of this type are created.
Note that this uses the webframework.classpathstore.chrome store for creating instances of type Chrome. This is a classpath store. Thus, if you actually do try to create objects, Surf will inform you that it cannot be done. Read on further to learn of alternative configurations which might better suit you!
Finally, there are a few cache fields that are commented out. You could use these to finely control how Surf loads individual model object types. In general, you will probably deal with the previously mentioned <persister/>
block since that controls all model objects at once.
Note that all of the search paths defined in this file include references to both the classpath and the shared web-extension folder. This allows you to extend the Surf application without having to modify the WAR file, if you so choose.
If you wish to modify Surf files within the WAR file itself, you will need to place the Surf files into the web application classpath so that the classpath store can pick them up. To do so, you would drop them into:
/tomcat/webapps/surf/WEB-INF/classes/alfresco
If you wish to modify Surf files outside of the WAR (recommended), you will need to place the Surf files into the Tomcat shared/classes path. To do so, drop your Surf files into:
/tomcat/shared/classes/alfresco/web-extension
For reference, the following are default classpath locations for each of the Surf file types:
alfresco/site-webscripts
alfresco/web-extension/site-webscripts
alfresco/templates
alfresco/web-extension/templates
alfresco/site-data/chrome
alfresco/web-extension/site-data/chrome
alfresco/site-data/components
alfresco/web-extension/site-data/components
alfresco/site-data/component-types
alfresco/web-extension/site-data/component-types
alfresco/site-data/configurations
alfresco/web-extension/site-data/configurations
alfresco/site-data/content-associations
alfresco/web-extension/site-data/content-associations
alfresco/site-data/pages
alfresco/web-extension/site-data/pages
alfresco/site-data/page-types
alfresco/web-extension/site-data/page-types
alfresco/site-data/page-associations
alfresco/web-extension/site-data/page-associations
alfresco/site-data/template-instances
alfresco/web-extension/site-data/template-instances
alfresco/site-data/template-types
alfresco/web-extension/site-data/template-types
alfresco/site-data/themes
alfresco/web-extension/site-data/themes
With this in mind, you should be able to begin building Surf sites and Surf applications. For guidance on doing so, check out the guides and references provided for the Alfresco Surf Platform.
In the previous section, we saw how you can drop Alfresco Surf files into the classpath of an application and begin building out your web site. Wouldn't it be much nicer if we had the full power of an Enterprise Class WCM solution to help us?
Alfresco WCM provides change-set management, versioning, workflow, auditing, snapshots and security for our web application code. It is the ideal environment for working on our Surf files.
To get started, all we have to do is start up Alfresco. Typically, Alfresco is installed on port 8080. As such, we can access Alfresco using the following URL:
http://localhost:8080/alfresco
Once inside of Alfresco, we can go into the Web Projects directory and we can create a web project. Let's call our web project testsite.
surf-deployment-create-webproject-1.png
Now that we have our Web Project, we can simply map a CIFS drive against and use it as if it were a drive on our desktop! In a Windows world, all you have to do is:
net use Z: \\MYMACHINEA\AVM
...where MYMACHINEA is generally the name of your machine followed by A. This is the default setting but you may have also changed this via CIFS configuration when you set up Alfresco.
Authenticate as admin/admin.
Navigate into your user sandbox and traverse down into the ROOT web application. This path should be the following:
Z:\testsite--admin\HEAD\DATA\v-1\www\avm_webapps\ROOT
Create the following path:
WEB-INF/classes/alfresco
That's where we'll drop all of our Surf files.
surf-deployment-mapped-drive-1.png
Note that we're working against our sandbox. This means that all of the files and directories that we add are not visible to others in the web project until we submit them for approval. This allows for others in the web project to approve or reject changes and for everyone to agree on what gets promoted into the staging area.
As we add files to our sandbox, we would like to have an Alfresco Surf instance up and running somewhere that we can use to instantly pick up our changes and preview our web application.
As before, we can deploy surf.war to an Alfresco Tomcat instance. This time, we can look at two sample files which help describe how we can configure Surf to act as a Preview Server for Alfresco WCM:
The file custom-web-framework-application-context.xml provides definitions for how to look up web scripts and templates. It begins by defining a brand new store to connect to the Alfresco WCM sandboxes. This is a remote store.
We must complete this section by providing the id of our store:
<bean id='webframework.remotestore' parent='webscripts.remotestore' abstract='true' init-method='init'>
<property name='endpoint'>
<value>alfresco-system</value>
</property>
<property name='api'>
<value>/avmstore</value>
</property>
<property name='storeId'>
<value>testsite--admin</value>
</property>
<property name='connectorService' ref='connector.service' />
<property name='storeContext' ref='webframework.context.remotestore'/>
<property name='connectorProvider' ref='webframework.connector.provider' />
</bean>
Note that this store is created as an abstract. It is then extended by two more reomte stores instances which define locations of files for Web Scripts and Templates:
The search paths for Web Scripts and Templates are then defined. The remote stores are incorporated into the search path definitions.
As a result, when Alfresco Surf needs to look up Web Scripts or Templates, it will look to the WCM Sandbox first.
The model objects are then defined. For each model object, we declare a Remote Store instance which tells Surf how to load that model object from the WCM Sandbox. We then tell the model object's search path to first look at our model object's remote store when trying to load objects of that type.
Here is the sample definition for Chrome:
<bean id='webframework.remotestore.chrome' parent='webframework.remotestore'>
<property name='path'><value>alfresco/site-data/chrome</value></property>
</bean>
<bean id='webframework.searchpath.chrome' class='org.alfresco.web.scripts.SearchPath'>
<property name='searchPath'>
<list>
<ref bean='webframework.remotestore.chrome' />
<ref bean='webframework.classpathstore.chrome.custom' />
<ref bean='webframework.classpathstore.chrome' />
</list>
</property>
</bean>
If you look through the file, you'll see similar definitions for all of the other model object types.
Finally, at the bottom of the file, you'll see that we've turned off caching for the Web Script processor and the Template processor. Since this is a Preview server, we don't really want it to cache. We're not as concerned about it being fast - we're much more concerned about it being accurate.
webframework.webscripts.templateprocessor
<bean id='webframework.webscripts.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.searchpath' />
<property name='updateDelay'><value>0</value></property>
<property name='defaultEncoding'><value>UTF-8</value></property>
</bean>
webframework.templateprocessor
<bean id='webframework.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.templates.searchpath' />
<property name='defaultEncoding'><value>UTF-8</value></property>
<property name='updateDelay'><value>0</value></property>
</bean>
The file web-framework-config-custom.xml provides configuration settings for the Surf web framework. This is a configuration service file which is loaded when Surf initializes.
Let's look at what is inside of it:
<persisters>
<cache-enabled>false</cache-enabled>
<cache-check-delay>0</cache-check-delay>
</persisters>
This block tells the Surf persister layer not to cache anything. By defining it here, we tell all of the model objects not to cache. This is a quick way to set them all at once without having to go one at a time.
<model-type>
<id>chrome</id>
<version>1.0</version>
<name>Chrome</name>
<description>Chrome</description>
<namespace></namespace>
<class>org.alfresco.web.framework.model.Chrome</class>
<search-path-id>webframework.searchpath.chrome</search-path-id>
<default-store-id>webframework.remotestore.chrome</default-store-id>
</model-type>
What follows next are all of the model object type definitions. This is pretty much the same as for the standalone configuration. You can adjust settings for cache and so forth on a per-object-type basis, just as before.
The difference here is that default-store-id is now set to webframework.remotestore.chrome. This means that new model objects of type Chrome will be placed into the remote store. Thus, they'll be placed right into our web project sandbox.
Note that all of the search paths defined in this file include references to remote store instances which point back to our Alfresco WCM sandbox. This allows us to work on content inside of our WCM sandbox and see it show up inside of the Surf application right away.
Once we've started our preview instance of Surf, we can go back to using Alfresco WCM to work on our Surf objects.
Using you mapped AVM CIFS drive, navigate to the following path:
Z:\testsite--admin\DATA\v-1\www\avm_webapps\ROOT
Make sure that you have created the following subfolder:
WEB-INF/classes/alfresco
You can edit your Surf files right inside of this folder.
For reference, the following are valid locations:
WEB-INF/classes/alfresco/site-webscripts
WEB-INF/classes/alfresco/templates
WEB-INF/classes/alfresco/site-data/chrome
WEB-INF/classes/alfresco/site-data/components
WEB-INF/classes/alfresco/site-data/component-types
WEB-INF/classes/alfresco/site-data/configurations
WEB-INF/classes/alfresco/site-data/content-associations
WEB-INF/classes/alfresco/site-data/pages
WEB-INF/classes/alfresco/site-data/page-types
WEB-INF/classes/alfresco/site-data/page-associations
WEB-INF/classes/alfresco/site-data/template-instances
WEB-INF/classes/alfresco/site-data/template-types
WEB-INF/classes/alfresco/site-data/themes
To preview, all we have to do is open our Surf application in a browser. The Surf application communicates with Alfresco and presents our sandbox content in the web site.
All of our work-in-progress Surf files are picked up automatically and rendered for us.
Note that this requires that we have provided the storeId
and webappId
in our Spring configuration file if we wish to preview a specific, known sandbox.
If we would like to use the same Surf instance to preview many different sandboxes (virtualized) via a switch, then we can fire the following URLs at the Surf instance:
http://server:port/surf/page?alfStoreId=<storeId>&alfWebappId=<webappId>
An example might be the following:
http://localhost:9090/surf/page?alfStoreId=greenenergy--admin&alfWebappId=ROOT
Using this mechanism, we can preview any of our Surf Web Projects while using a single Surf server! We can switch between web applications and between user sandboxes.
We've now worked on content inside of our Alfresco Web Content Management sandbox and previewed it on our Surf preview server.
Suppose that we're satisfied with our changes. The first thing we would do is submit the content using Alfresco's WCM UI.
surf-deployment-submit-items-1.png
The content is submitted from our sandbox up to the staging store. If we wanted to configure workflow here, we could do that so that the content would need to be previewed and approved by a reviewer. However, in this case we didn't set up a workflow, so it was submitted up to staging.
We would now like to publish this content from our Alfresco Web Content Management authoring environment out to production. On the production tier, we can have a standalone Alfresco Surf server that is waiting for new content to arrive. We publish out from the authoring tier to the production tier.
A production Surf instance is very similar to a Standalone Surf instance. There are only a few differences. Fundamentally, we would like the Surf instance to pick up files that are deployed to the production environment. Surf therefore needs to look outside the classpath (so as to avoid application server restarts). We would also like to configure the Surf Production web application to be a bit more 'performance focused' and so we may opt to tweak a few of the cache settings.
This time, we can look at two sample files which help describe how we can configure Surf to act as a Production Server for Alfresco WCM:
The file custom-web-framework-application-context.xml provides definitions for how to look up web scripts and templates. It begins by defining a brand new store to connect to a directory on the local disk. This is a local file system store.
Note that this section includes a property root which defines the root location where our files will be deployed:
<bean id='webframework.localstore'
class='org.alfresco.web.scripts.LocalFileSystemStore'
abstract='true'
init-method='init'>
<property name='root'>
<value>/deploy/files</value>
</property>
</bean>
Note that this store is created as an abstract. It is then extended by two more local stores instances which define locations of files for Web Scripts and Templates:
The search paths for Web Scripts and Templates are then defined. The local stores are incorporated into the search path definitions.
As a result, when Alfresco Surf needs to look up Web Scripts or Templates, it will look to the local disk location first.
The model objects are then defined. For each model object, we declare a Local File System Store instance which tells Surf how to load that model object from the location on disk. We then tell the model object's search path to first look at our model object's local store when trying to load objects of that type.
Here is the sample definition for Chrome:
<bean id='webframework.localstore.chrome' parent='webframework.localstore'>
<property name='path'><value>alfresco/site-data/chrome</value></property>
</bean>
<bean id='webframework.searchpath.chrome' class='org.alfresco.web.scripts.SearchPath'>
<property name='searchPath'>
<list>
<ref bean='webframework.localstore.chrome' />
<ref bean='webframework.classpathstore.chrome.custom' />
<ref bean='webframework.classpathstore.chrome' />
</list>
</property>
</bean>
If you look through the file, you'll see similar definitions for all of the other model object types.
Finally, at the bottom of the file, you'll see that we've turned on caching for the Web Script processor and the Template processor. This cache will only update every 600 seconds. This cache will allow our requests to process through faster since we won't have to incur the lookup on the search path each time Surf tries to load an object.
webframework.webscripts.templateprocessor
<bean id='webframework.webscripts.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.searchpath' />
<property name='updateDelay'><value>600</value></property>
<property name='defaultEncoding'><value>UTF-8</value></property>
</bean>
webframework.templateprocessor
<bean id='webframework.templateprocessor'
class='org.alfresco.web.scripts.PresentationTemplateProcessor'>
<property name='searchPath' ref='webframework.templates.searchpath' />
<property name='defaultEncoding'><value>UTF-8</value></property>
<property name='updateDelay'><value>600</value></property>
</bean>
The file web-framework-config-custom.xml provides configuration settings for the Surf web framework. This is a configuration service file which is loaded when Surf initializes.
Let's look at what is inside of it:
<persisters>
<cache-enabled>false</cache-enabled>
<cache-check-delay>600</cache-check-delay>
</persisters>
This block tells the Surf persister layer to cache model objects for 600 seconds. This defines a common cache setting across all Surf model object types.
<model-type>
<id>chrome</id>
<version>1.0</version>
<name>Chrome</name>
<description>Chrome</description>
<namespace></namespace>
<class>org.alfresco.web.framework.model.Chrome</class>
<search-path-id>webframework.searchpath.chrome</search-path-id>
<default-store-id>webframework.localstore.chrome</default-store-id>
</model-type>
This is one of several blocks that defines a Surf model object type. It defines the implementation class (so that Surf can manufacture backing beans) and tells Surf how to look up objects of the given type (which search path to use). It also defines which store to use by default when new objects of this type are created.
Note that this uses the webframework.localstore.chrome store for creating instances of type Chrome. This is the local file system store. Thus, if you actually do try to create objects, Surf will create them on the local disk.
Finally, there are a few cache fields that are commented out. You could use these to finely control how Surf loads individual model object types. In general, you will probably deal with the previously mentioned <persister/>
block since that controls all model objects at once.
<resource-resolver>
<id>webapp</id>
<name>Alfresco Web Application Resource Resolver</name>
<description>Resolves data access for web application assets</description>
<class>org.alfresco.web.framework.resource.AlfrescoWebProjectResourceResolver</class>
<alias-uri>/files</alias-uri>
<store-id>STORE_ID</store-id>
</resource-resolver>
If your Surf application binds to Web Application resources, like static files from the web application, the webapp resource resolver will help your runtime application determine the location of the files.
Within your Surf application, you can use resource tags to point at resources within the application. You can acquire a URL to a Surf object's resource binding using a Freemarker directive much like the following:
This might describe a resource within the web application located at:
/a/b/c.gif
With this resource resolver in place, the tag would transform at runtime within your production Surf instance to point to the following:
http://localhost/<webapp>/files/a/b/c.gif
Alfresco provides both File System Receivers (FSRs) and Alfresco System Receivers (ASRs) to support your live web site. Both are pluggable and allow you to provide handlers or 'Runnables' which can handle post-deployment processing and data massaging for your live web site.
In this section, we'll set up an FSR which will listen for deployment events from the Alfresco WCM authoring server. When files arrive to our FSR, they'll be handled by one of two targets:
We do this for convenience as it is often beneficial to separate your application logic from your static files. Static files are things like images, css, flash files and the like.
To get started, download and start the installer for the Alfresco Deployment FSR. This is a relatively small install as it is just a small program that listens for deployment events. You can also install this by downloading the ZIP archive and manually extracting into a directory.
Here, let us assume that the FSR is deployed to the following directory:
d:/deploy
If you're on Linux or a non-Windows platform, you substitute for the appropriate path.
Inside of the deploy folder, let's create a 'files' folder.
</pre>
d:/deploy/files
</pre>
Now let us edit the deployment.properties file. If you've used the installer, this file is automatically generated for you. Otherwise, fill it in as follows:
dep.datadir=d:\deploy\deploy_depdata
dep.logdir=d:\deploy\deploy_deplog
dep.metadatadir=d:\deploy\deploy_depmeta
dep.rmi.port=44100
dep.rmi.service.port=44101
Next, let's set up two deployment targets - one to handle our Surf files and the other to handle our Static files. We define these inside of our application-context.xml file which tells Spring how to load beans when it starts up. Spring loads a configuration bean and we would like to provide two custom targets:
<property name='targetData'>
<map>
<entry key='surf'>
<map>
<entry key='root'><value>/deploy/files/alfresco</value></entry>
<entry key='user'><value>admin</value></entry>
<entry key='password'><value>admin</value></entry>
<entry key='runnable' value-ref='surfRunnable' />
</map>
</entry>
<entry key='static'>
<map>
<entry key='root'><value>/deploy/files/webroot</value></entry>
<entry key='user'><value>admin</value></entry>
<entry key='password'><value>admin</value></entry>
</map>
</entry>
</map>
</property>
Note that the first target (surf) executes a Runnable once the deployment completes. As a final step, let's define that Runnable. Add a bean definition to the end of the file:
<bean id='surfRunnable' class='org.alfresco.deployment.SurfRefreshRunnable'>
<property name='surfLocation'>
<value>http://localhost:8280/surf</value>
</property>
</bean>
Save all of these files and then start up the File System Receiver. You can do this on Windows by using the deploy_start.bat batch file.
We now need to tell our Web Project how to deploy to our File System Receiver. The File System Receiver is sitting out there, waiting for a deployment event to be sent to it. We must tell our web project how to contact the FSR and also tell it how it should go about sending files to it.
To begin, edit your web project settings from within the Alfresco Explorer. You will arrive at a screen where we can tell our Web Project about the file system receiver and targets that we just defined.
Let's add a File System Receiver that will be responsible for sending Surf files to Production. We can use the following properties:
Next, let's add a File System Receiver that will be responsible for sending Static files to Production. We can use the following properties:
Note: For FSR Excludes field, the syntax looks like
[A-Za-z0-9:/_]*ROOT/WEB-INF/*
Save your changes and your web project will be configured to publish out to the File System Receiver!
By configuring the FSR targets in the previous section, we've told our web project how to publish out both Alfresco Surf objects as well as static things (like images and so forth).
The static bits arrive on disk in a place like:
/deploy/files/webroot/ROOT
We want to tell our production Tomcat server how to pick up these assets by basically creating a virtual directory (or alias) which maps a web application path over to this deployed assets directory. That way, things get picked up automatically on deployment and Tomcat knows how to serve things back straight away.
Inside of your production Surf Tomcat instance, go to the following directory:
/tomcat/conf
And then create the following path and file (for Tomcat 6):
/tomcat/conf/Catalina/localhost/files.xml
Add the following content to the file:
<Context reloadable='true' docBase='d:\deploy\files\webroot\ROOT' debug='1'/>
Save the file. When you restart Tomcat, you'll now have a virtual directory that serves back the deployed static assets. You can access this by using the following URL:
http://<server>:<port>/files
Once the web project is set up correctly, we can use Alfresco Web Content Management's deployment capabilities to either schedule publishing or manually publish a snapshot of our web site to production.
To begin, we should make sure that all of our changed files are successfully submitted up to the staging area. Let's take a look at our modified items:
surf-deployment-submit-items-2.png
By clicking on submit, we can submit these items to staging:
surf-deployment-submit-items-3.png
Since we have no default workflow configured, these will be automatically promoted up to the staging store. We should now see that a snapshot has been generated:
surf-deployment-snapshots-1.png
By clicking on the Deploy button, we can now deploy this snapshot to production. On the next screen, pick the receiver target (your file system receiver):
surf-deployment-receivers-1.png
The deployment will then proceed. Your files will be sent over to the file system receiver and will be written to disk in the appropriate locations.
surf-deployment-deployment-finished-1.png
Alfresco Surf on the production machine will be refreshed and your new web site will be live.