Surf Platform - Advanced Customization

Document created by resplin Employee on Jun 6, 2015
Version 1Show Document
  • View in full screen mode

Obsolete Pages{{Obsolete}}

The official documentation is at: http://docs.alfresco.com



Draft PagesDeveloper GuideSurf Platform
Labs 33.0

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.




Table of Contents


Web Application Basics


This section describes a Surf platform web application. A Surf platform web application is generally packaged as a WAR. The alfwf.war file that builds by default is an example of such a WAR file.


Structure


When the WAR file expands, it has a structure much like the one shown here:



/core
/css
/images
/WEB-INF
/WEB-INF/classes/alfresco
index.jsp

You may have some additional directories, but these are the essential ones. It is a very straightforward web application.

The first file to look at is the web.xml file, located under WEB-INF.  The servlet container begins by reading this file.  Within web.xml, there are declarations for servlets and Spring objects. It is kept lightweight, but you should note some of the sections.

The following section tells the Spring Framework context how to load. Spring is included with the Surf platform and is responsible for bean management and instantiation. The section bootstraps webscript-framework-application-context.xml (which loads the Web Script Engine configuration). It then bootstraps web-framework-application-context.xml (which loads the Surf platform config).



   <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>
         classpath:alfresco/webscript-framework-application-context.xml
         classpath:alfresco/web-framework-application-context.xml
      </param-value>
      <description>Spring config file locations</description>
   </context-param>

Once the web application starts up, several servlets are made available. One such servlet is the DispatcherServlet which is the main handler for requests that enter the Surf platform:



   <servlet>
      <servlet-name>pageRendererServlet</servlet-name>
      <servlet-class>org.alfresco.web.site.servlet.DispatcherServlet</servlet-class>
      <load-on-startup>1</load-on-startup>
   </servlet> 
   <servlet-mapping>
      <servlet-name>pageRendererServlet</servlet-name>
      <url-pattern>/page/*</url-pattern>
   </servlet-mapping>
   <servlet-mapping>
      <servlet-name>pageRendererServlet</servlet-name>
      <url-pattern>/p/*</url-pattern>
   </servlet-mapping>

Requests that arrive to the web application hit index.jsp, which forwards the request to the dispatcher servlet (a forward to /page).


Dispatcher Servlet


The Dispatcher Servlet is responsible for rendering back a page to the user. It must consider the incoming request context and figure what and how to render. The dispatcher can receive requests for the following:


A specific page :A page id may be given to the dispatcher directly.
A type of page :For instance, the user may be requesting the login page. The application may actually have several login pages (one for customers, one for partners, one for employees, and so on) and it must select one and render it back.
An object :An object id may be given to the dispatcher. The dispatcher must then figure out which page to use to render this object.

There are other combinations; the permutations are numerous.   As such, the Dispatcher Servlet has been implemented in such a way as to allow developers to customize its behavior with a minimal amount of work.   The exact nature of these extensions is covered in the Advanced section.


Model Objects


The Surf platform contains a data model for objects that it must manage and refer to in order to properly render the web application.  These model objects are managed in memory as standard POJOs (Plain Old Java Objects). When written to disk, they are serialized as XML.

The XML is stored in subdirectories within the following location:



   /WEB-INF/classes/alfresco/site-data

Within this directory, you see the following subdirectories, one for each type of model object that is managed by the Surf platform:



   /site-data/chrome
   /site-data/component-types
   /site-data/components
   /site-data/configurations
   /site-data/content-associations
   /site-data/page-associations
   /site-data/page-types
   /site-data/pages
   /site-data/template-instances
   /site-data/template-types
   /site-data/themes

Inside each subdirectory, you may find XML which represents a serialized model object. For instance, within the default alfwf.war file, there is a file called welcome.xml. This is a page with id welcome and it contains the following XML:



   <page>
      <title>The test welcome page</title>
      <template-instance>welcome-main</template-instance>
      <authentication>none</authentication>
   </page>

The exact semantics of each object type is covered in the section on the Object Model, but this should give you a general feel. From looking at the XML, you can see that this is a page whose title is The test welcome page and which points to a template that has the id welcome-main. No authentication is required to access this page.

As you create new pages, new components, or any model object, you do so by dropping new XML into these directories. This means there is no need to access databases or customize web clients.


Renderers


As you define new templates and new components, you write XML to describe the model objects for the Surf platform. A model object tells the Surf platform that a component exists and how to handle the component.  However, after doing that, you must then tell the template or component how to render.  For that, you must provide a renderer.

There are few renderer provided to you out of the box, although you could add your own renderers.  The supported out-of-the-box renderers are


  • Web Scripts
  • Freemarker
  • JSP
  • HTML

Web Script Renderers


A web script renderer is the most advanced renderer since it allows you to take advantage of both JavaScript (for pre-render processing) and Freemarker (for presentation processing). If you have built web scripts using Alfresco's web script engine before, then you will already be familiar with this.  Otherwise, take a look at the Web Scripts guide.

Within the Surf platform, web scripts are used most commonly to render components. You build your own web scripts and then drop them into the /WEB-INF/classes/alfresco/site-webscripts directory. They will then be picked up by the container and can be used by your model objects.

To tell a component to use a web script, set the url property to the URL of the web script.


Freemarker Renderers


The Freemarker renderer is used most commonly to render templates. It is also automatically used in conjunction with the web script renderer, but that is only applicable to components. With templates, you can use Freemarker directly.

If you have built Freemarker templates before and used them within Alfresco, then you will already be familiar with what they can do. If you are not familiar with Freemarker templates, see the Alfresco Freemarker Template Guide.

Within the Surf platform, your Freemarker .ftl template files can be placed into the /WEB-INF/classes/alfresco/templates directory. Then they will be picked up by the template processor and will be accessible by your model objects.

To tell a template to use a Freemarker .ftl file, set the template-type parameter to the file's path (relative to /templates).


JSP Renderers


The JSP renderer is used to render either components or templates, and provide you with access to the full Java language and the Surf platform Java API.  They require knowledge of Java programming.

To use a JSP renderer, you have to write your .jsp file and place it anywhere within your web application, though we recommend a convention of placing them under the /app/components directory.

Once you have done that, you set the renderer property to the path of the JSP (relative to the web application). This is covered in greater detail later on.


The Object Model


The Web Application Basics section provides a high level overview of the Surf platform data model. This section goes into detail concerning each object type.


Chrome


Chrome describes the border elements around a region or a component. These border elements may include styling elements like shadows,  or they may introduce drag and drop capabilities into the page. They may also introduce user-functionality like buttons for popping up component settings (as you frequently see in portals).

By default, chrome is kept to a minimum within the Surf platform. New components that are dropped onto a page will receive the default chrome for the web application (which is empty out-of-the-box).


Storage location :/WEB-INF/classes/alfresco/site-data/chrome
Properties

  • id  => the id of the object (optional)
  • title  => the title of the chrome
  • description  => the description of the chrome
  • renderer-type  => the id of the renderer (as defined in the config)
  • renderer  => the path to the file to be executed by the renderer

Sample JSP Chrome



   <chrome>
      <title>Sample Chrome 1</title>
      <renderer>/app/sample-chrome-1.jsp</renderer>
      <renderer-type>jsp</renderer-type>
   </chrome>

Note: renderer is the path to the JSP file (relative to the web application)


Sample Web Script Chrome



   <chrome>
      <title>Sample Chrome 2</title>
      <renderer>/sample/chrome-2</renderer>
      <renderer-type>webscript</renderer-type>
   </chrome>

Note: renderer is the URL to the web script as defined in the web script's XML description document.


Sample Chrome Template for Region


Use @component to include the component in the region. 




  


Sample Chrome Template for Component


Use @componentInclude for the place where the component is to be rendered.




  
${htmlid}

  

    



Component Type


A component type is something that the web site builder can grab at and instantiate in many places across their web application.  They bind the new instances into pages by snapping them into regions (or slots). In other frameworks it is sometimes called a widget, a gadget, a portlet, or a dashlet.


Storage location :/WEB-INF/classes/alfresco/site-data/component-types
Properties

  • id  => the id of the object (optional)
  • title  => the title of the component type
  • description  => the description of the component type
  • renderer-type  => the id of the renderer (as defined in the config, typically one of: webscript, jsp, java)
  • renderer  => the path to the file to be executed by the renderer

Sample Web Script Component Type



   <component-type>
      <title>Alfresco RSS Newsfeed Component</title>
      <description>Displays a configurable number of Alfresco news items</description>
      <renderer-type>webscript</renderer-type> 
      <renderer>/sample/alfresco-newsfeed</renderer>
   </component-type>

Note: renderer is the URL to the web script as defined in the web script's XML descriptor file


Sample JSP Component Type



   <component-type>
      <id>jsp-sample-component-type</id>
      <title>Alfresco RSS Newsfeed Component</title>
      <description>Displays a configurable number of Alfresco news items</description>
      <renderer-type>jsp</renderer-type> 
      <renderer>/app/components/alfresco-newsfeed</renderer>
   </component-type>

Note: renderer is the path to the JSP file (relative to the web application)


Sample Java Bean Component Type



   <component-type>
      <title>Alfresco RSS Newsfeed Component</title>
      <description>Displays a configurable number of Alfresco news items</description>
      <renderer-type>java</renderer-type> 
      <renderer>org.alfresco.web.site.ui.AlfrescoRSSNewsFeed</renderer>
   </component-type>

Note: renderer is the class name of the Java Bean to be instantiated. This Java class must implement the Renderable interface.  This is covered in a greater detail in another section.


Component


A component is an instance of a component type that has been 'bound' into a region or a slot. It represents a binding along with the instance-specific state for that component instance.


Storage location :/WEB-INF/classes/alfresco/site-data/components
Properties

  • id  => the id of the object (optional)
  • title  => the title of the component (optional)
  • description  => the description of the component (optional)
  • component-type => the id of the component type (optional)
  • scope  => the scope of the binding (either global, template or page).
  • region-id  => the id of the region (or slot) into which the component is bound
  • source-id  => either global or the id of the page or template to which the component is bound.
  • url  => the path to the file to be executed by the renderer

Sample Web Script Component



   <component>
      <scope>page</scope>
      <region-id>content</region-id>
      <source-id>welcome</source-id>
      <url>/test/configtest</url>
   </component>

Note: A page-scoped component that is bound to content region of the welcome page. The component type is not specified, so the url property is inspected and determined to be a web script. Therefore, this component will execute the web script at url /test/configtest.


Sample JSP Component



   <component>
      <component-type>jsp-sample-component-type</component-type>
      <scope>template</scope>
      <region-id>news</region-id>
      <source-id>product</source-id>
   </component>

Note: A template-scoped component that is bound to news region of the product template.  The component type is jsp-sample-component-type which is from a previous sample.  This is a JSP renderer and all of the rendering information is contained on the component type.




Configuration


A Configuration object is a collection of XML, the purpose of which is general in nature. As opposed to Model objects that have structured XML persistence (with known properties and members), a Configuration has only one requirement - an id.  This id can either be specified in the XML or determined from the file name.

In general, other for advanced customization, you will not need to deal with Configuration objects. They are mostly used internally by the system.


Storage location :/WEB-INF/classes/alfresco/site-data/configurations
Properties

  • id  => the id of the object (optional)
  • title  => the title of the component (optional)
  • description  => the description of the component (optional)

Sample Configuration


One place where Configuration objects are used is to store information that pertains to the global site. At present, there does not exist the notion of a 'web site' object. Instead, web site configuration stored as a Configuration XML file. An example is shown here (note the root-page element that specifies first page to be invoked):



  <configuration>
    <title>Surf Platform 3.0 Sample Site</title>
    <description>Surf Platform 3.0 Sample Site</description>
    <source-id>site</source-id>
    <properties>
      <root-page>welcome</root-page>
    </properties>
  </configuration>

Note: This XML could have any structure that you wish. In this sense, you can think of a Configuration object as a general purpose Model Object.


Content Association


A Content Association object describes to the Surf platform how it should handle the rendition of a view for a given piece of content.

To put it another way, imagine that an end-user clicks on a link to view details about a given document. Their objective is not to open up the document, but rather to view its metadata and properties.

With the Surf platform, you might define a general purpose page called document-details-viewer. Your intention would be to use this page anytime an end-user wants to view the details about any document in the system.

You can do this by creating a Content Association that associates the document to the Page. It can associate either a specific document (by object id) or all documents of a specific type (by object type id). It can associate to a Page instance or it could also associate to a Page Type.

The Surf platform will realize that the end-user clicked on a document and will then look to the Content Association instance to tell it where to go in order to render this content. The rendering Page and all downstream components will have the Content object available to it so that no reloads are necessary.


Storage location :/WEB-INF/classes/alfresco/site-data/content-associations
Properties

  • id  => the id of the object (optional)
  • title  => the title of the Content Association (optional)
  • description  => the description of the Content Association(optional)
  • source-id  => the content type to be associated
  • dest-id  => the page or component that will render the content type
  • assoc-type  => the type of association, i.e. page, etc.

Sample Configuration



  <content-association>
    <title>details: cm_content</title>
    <source-id>{http://www.alfresco.org/model/content/1.0}content</source-id>
    <dest-id>page.content.details</dest-id>
    <assoc-type>page</assoc-type>
  </content-association>

Note: Association between content of type {http://www.alfresco.org/model/content/1.0}content and the page with id page.content.details, which will be used to render it. This is an example of how you might use the Surf platform to render Alfresco content into a page.


Page


A page is a navigable page in your web application. It may have associations to other pages and multiple formats keyed from it to templates. A page is a top-level object from which you can traverse either additional navigation or rendering paths.


Storage location :/WEB-INF/classes/alfresco/site-data/pages
Properties

  • id  => the id of the object (optional)
  • title  => the title of the component (optional)
  • description  => the description of the component (optional)
  • template-instance => the id of the template instance to render this page
  • authentication  => authentication required to view this page (either none, user, or admin)

Sample Home Page



   <page>
      <title>My Home Page</title>
      <template-instance>home-main</template-instance>
      <authentication>none</authentication>
   </page>

Note: A simple unauthenticated home page. When rendering, the page will delegate to the home-main template to render the page markup.


Sample Home Page (two formats, user authentication required)



   <page>
      <title>My Home Page</title>
      <template-instance>home-main</template-instance>
      <template-instance format='print'>home-print</template-instance>
      <authentication>user</authentication>
   </page>

Note: Requires user authentication to access. If the print format is requested, a different template (home-print) is acted upon to render the result.


Page Association


The Page Association objects allows you to link two pages together. Most commonly, this link is of type child and is meant to depict a fixed structure like a navigation tree. However, other types are possible and there is no requirement to use Page Associations as a means to support only a single fixed tree.

Using associations, multiple trees are possible. The nature of the associations, when expanded beyond child, is very similar to that of classifiers, categories, or tags. In other words, Pages may be associated to other pages, but they may also be laterally associated to other elements. This allows for implementations of faceted navigation and tag clouds.


Storage location :/WEB-INF/classes/alfresco/site-data/page-associations
Properties

  • id  => the id of the object (optional)
  • title  => the title of the Page Association(optional)
  • description  => the description of the Page Association(optional)
  • source-id => the id of the parent element, often a page id
  • dest-id => the id of the linked element, often a page id
  • assoc-type => the type of the association

Sample Page Association



  <page-association>
    <title>Products</title>
    <source-id>page.home</source-id>
    <dest-id>page.products</dest-id>
    <assoc-type>child</assoc-type>
  </page-association>

Note: Links the Home page to the Products page using a child relationship. At present, child relationships are the only ones understood by the Surf platform.


Template Instance


This sample is from share's site-data\template-instances\search.xml.  It points to FreeMarker renderer classes/alfresco/templates/org/alfresco/search.ftl.  




<template-instance>
   <template-type>org/alfresco/search</template-type>
   <properties>
   </properties>
</template-instance>


The above sample works because if template-type is not known to Surf (i.e. not webscript, freemarker, etc), it assumes freemarker and looks for it at the specified URI.  A way to specify this more explicitly is:



<template-instance>
<template-type>freemarker</template-type>
<url>org/alfresco/search</url>
       <properties>
       </properties>
<template-instance>

Template Type


Template Renderer


Example below is from share's search.ftl.



<link rel='stylesheet' type='text/css' href='${url.context}/templates/wiki/wiki.css' />

     

  

     

        

           

     

  


     


Theme


Creating a New Template


Freemarker Example


JSP Example


Creating a New Component


Web Script Example


JSP Example


Java Bean Example


Advanced Surf Platform Configuration


DispatcherServlet can be customized by changing the way it creates pages, users, links, etc.   Of course, the Surf platform provides default implementations for all of these. In most cases, you will be able to use the default implementations. 

Modifying the mechanisms typically involves extending one or more of the following (look in the source code for examples on how to do so):


Request Context


Request Context Factory :An implementation of the RequestContextFactory interface - responsible for generating a RequestContext instance. RequestContext instances are created at the top of the request processing chain and are then made available to all rendering items downstream.

Page Mapper


Page Mapper :An implementation of the PageMapper interface. This is responsible for examining request parameters, headers, and attributes so as to populate the RequestContext instance with page state.

Users


User Factory :An implementation of the UserFactory interface. This is responsible for examining the request state and ensuring that a valid User object is loaded into the request context. The User object is then available to all rendering items downstream.

Link Builder


Link Builder :An implementation of the LinkBuilder interface. This is responsible for creating links that the aforementioned pieces are able to properly interpret.

File Systems


Formats


Model Types


Tag Libraries


Renderers


Content Loaders


Error Handlers


System Pages


Dispatcher Defaults


Application Defaults


Debug Settings


Advanced Remote Configuration

Attachments

    Outcomes