This blog article will add these new pages into the share extension project structure discussed in the previous blog article 'Extending Share 1 - Creating a share extension project' that provides a clean way to isolate our changes from the existing share code. The new page will be able to be added to existing or new sites by using the 'Customize Site' feature of the site dashboard and selecting the new page.
Step 1 - Setting up the project
We will start with creating a project structure similar to that referenced in the previous blog article 'Extending Share 1 - Creating a share extension project' and the latest Alfresco SDK.
1. Create a new project (i.e. 'someco-share-extension') with the following source directories :
- source/java - contains java code to be packaged in someco-share-ext.jar
- config/alfresco/web-extension - contains 'web-framework-config-custom.xml'
- config/alfresco/web-extension/site-data - contains custom model objects like pages, template-instances, and components
- config/alfresco/web-extension/site-webscripts containing folder /com/someco to contain webscripts in a unique namespace
- config/alfresco/templates - contains custom templates containing folder /com/someco to contain templates in unique namespace
- source/web - contains web assets and delivered to the war, used for javascript and css as included by html templates
- lib - contains required library elements (includes junit.jar for testing
- test - contains java test code and configuration
2. Create the 'web-framework-config-custom.xml' file in the to contain a reference to our new page so that it can be included by customizing a site.
3. Copy the ant build.xml file from the source in the previous 'Extending Share' blog article into the root of the project. This build script has some handy tasks. Some of which were derived from the great works by Jeff Potts and his great new book Alfresco Developers Guide from Packt Publishing. Make sure to change the project name in the build.xml file as appropriate (i.e. 'someco-share-extension').
- The 'deploy' tasks will call the 'package' task and copy the created jar to the APP_TOMCAT_HOME/WEB-INF/lib directory (should be configured to point to the expanded share war file directory in tomcat), and copy the contents of the 'source/web' and 'config/alfresco/*' folders to the APP_TOMCAT_HOME/WEB-INF/classes/alfresco directory.
- The 'package' task will call the 'compile' taks and create a jar (someco-share-ext.jar) including our java code in the source/java folder, web scripts in the 'config/someco/site-webscripts' and templates in the 'config/someco/templates' folders.
4. Create (or copy) the build.properties file to the project root directory containing the following:
#directory names
dir.name.assemble=assemble
dir.name.bin=bin
dir.name.build=build
dir.name.classes=classes
dir.name.config=config
dir.name.source=source
dir.name.devenv=devenv
dir.name.dist=dist
dir.name.distro=distro
dir.name.docs=docs
dir.name.generated=generated
dir.name.java=java
dir.name.lib=lib
dir.name.test.results=
dir.name.test.results=test-results
dir.name.test.resources=test-resources
dir.name.web=web
file.name.jar=someco-share-ext.jar
dir.junit.lib=lib
Now we are ready to start creating our custom configuration. You can adjust these to make the ant build work with your own project structure.Step 2 - Creating the page and template instance
To start out, we will create a new page called 'Content Grid' that is intended to display a list of content in a way similar to Document Library but as a grid showing meta-data and a content extract in columns. This extension follows the model object structure as outlined in the Alfresco Surf Platform - Developers Guide page, and analyzed in the 'Learning Surf 2 - Examining Slingshot configuration' blog article.
The custom model objects we create will be added to the 'config/alfresco/web-extension' source directory. The contents of this directory will be copied into the Share war directory using the ant deploy task in the Ant build file.
1. Create 'contentgrid.xml' file in the 'pages' folder of the 'source/alfresco/web-extension/site-data' source directory, with the following content:
<?xml version='1.0' encoding='UTF-8'?>
<page>
<title>Content Grid</title>
<description>Document library with Tree view</description>
<template-instance>contentgrid</template-instance>
<authentication>user</authentication>
</page>
This defines a page with the title 'Content Grid'. It refers to a template instance called 'contentgrid' defined next.2. Create the 'contentgrid.xml' template instance in the 'template-instances' folder of the 'config/alfresco/web-extension/site-data' source folder with the following contents:
<?xml version='1.0' encoding='UTF-8'?>
<template-instance>
<template-type>org/alfresco/simple-contentgrid</template-type>
<properties>
<hasBreadcrumb>true</hasBreadcrumb>
<hasTreeview>true</hasTreeview>
<hasPackager>true</hasPackager>
</properties>
</template-instance>
This file tells Surf to use the template found from path org/alfresco/contentgrid path of the config/alfresco/templates folder.Step 3 - Creating the template type
The template we will create first will be a simple test template with no functionality, to test our configuration and deployment. This template is a gutted out version of the documentlibrary.ftl found in the config/alfresco/templates source folder in the org/alfresco package. It includes a standard set of included global regions with a simple body announcing that the template has rendered.
1. Create 'simple-contentgrid.ftl' freemarker template in the org/alfresco path of the 'config/alfresco/templates' source folder with the following contents:
<#import "/org/alfresco/import/alfresco-template.ftl" as template />
<@template.header>
<link rel="stylesheet" type="text/css" href="${url.context}/templates/documentlibrary/documentlibrary.css" />
<script type="text/javascript">//<![CDATA[
(function()
{
// If no location.hash exists, convert a location.search to a location.hash and replace the page
var loc = window.location;
if (loc.hash === "" && loc.search !== "")
{
var url = loc.protocol + "//" + loc.host + loc.pathname + "#" + loc.search.substring(1);
window.location.replace(url);
}
})();
//]]></script>
<script type="text/javascript" src="${url.context}/templates/documentlibrary/documentlibrary.js"></script>
<script type="text/javascript" src="${url.context}/modules/documentlibrary/doclib-actions.js"></script>
</@>
<@template.body>
<div id="hd">
<@region id="header" scope="global" protected=true />
<@region id="title" scope="template" protected=true />
<@region id="navigation" scope="template" protected=true />
</div>
<div id="bd">
This is the Content Grid template
</div>
<p> </p>
<p> </p>
</@>
<@template.footer>
<div id="ft">
<@region id="footer" scope="global" protected=true />
</div>
</@>
2. Modify 'web-framework-config-custom.xml' file in the 'config/alfresco/web-extensions' folder to add a reference to the new page we just created to allow this page to be added when customizing the site. It should read:
<alfresco-config>
<config evaluator="string-compare" condition="SitePages" replace="true">
<pages>
<page id="calendar">calendar</page>
<page id="wiki-page">wiki-page?title=Main_Page</page>
<page id="documentlibrary">documentlibrary</page>
<page id="contentgrid">contentgrid</page>
<page id="discussions-topiclist">discussions-topiclist</page>
<page id="blog-postlist">blog-postlist</page>
</pages>
</config>
</alfresco-config>
When Share is started, the new page will not be configured to display with any sites. The new page can be added to existing sites by using the 'customize site' feature. If you wish this new page to be automatically added to new sites, add it to the 'presets.xml' file.3. Run the ant deploy task to copy the configuration components to the deployed share war (APP_TOMCAT_HOME/webapps/share)
4. Start alfresco and share by starting tomcat
5. Login to share
6. Create the new site (or select it if already created)
7. Select the 'Customize Site' button and click 'Add Page' and select the 'Content Grid' page. The 'Content Grid' page should be added to the navigation bar.
8. Press this option to see the page we just created with the simple-contentgrid.ftl template. The message 'This is the Content Grid template' should be displayed.
Step 4 - Mapping the page components
Now we can advance to a more interesting page template. The previous simple-contentgrid.ftl only demonstrated that we could add a page and it would render, now we will create a page template that will be similar to the Document Library template, but display our custom grid view UI.
1. create contentgrid.ftl in the /org/alfresco directory of the /config/alfresco/templates source folder, with containing the following:
<#import "/org/alfresco/import/alfresco-template.ftl" as template />
<@template.header>
<link rel="stylesheet" type="text/css" href="${url.context}/templates/documentlibrary/documentlibrary.css" />
<script type="text/javascript">//<![CDATA[
(function()
{
// If no location.hash exists, convert a location.search to a location.hash and replace the page
var loc = window.location;
if (loc.hash === "" && loc.search !== "")
{
var url = loc.protocol + "//" + loc.host + loc.pathname + "#" + loc.search.substring(1);
window.location.replace(url);
}
})();
//]]></script>
<script type="text/javascript" src="${url.context}/templates/documentlibrary/documentlibrary.js"></script>
<script type="text/javascript" src="${url.context}/modules/documentlibrary/doclib-actions.js"></script>
</@>
<@template.body>
<div id="hd">
<@region id="header" scope="global" protected=true />
<@region id="title" scope="template" protected=true />
<@region id="navigation" scope="template" protected=true />
</div>
<div id="bd">
<div class="yui-t1" id="divDocLibraryWrapper">
<div id="yui-main">
<div class="yui-b" id="divDocLibraryDocs">
<@region id="toolbar" scope="template" protected=true />
<@region id="gridview" scope="template" protected=true />
</div>
</div>
<div class="yui-b" id="divDocLibraryFilters">
<@region id="filter" scope="template" protected=true />
<@region id="tree" scope="template" protected=true />
<@region id="tags" scope="template" protected=true />
</div>
</div>
</div>
<p> </p>
<p> </p>
</@>
<@template.footer>
<div id="ft">
<@region id="footer" scope="global" protected=true />
</div>
</@>
This template contains several regions, some global and some template specific. The template specific regions must have component configuraton xml files to indicate what ui webscript will be used to render in that region. The components follow a naming convention:
- a scope (global or template in our example)
- a region-id refering to the region of the template
- a source-id refering to the template
- a url refering to the ui web script to render in this region
Region | Scope | Component |
header | global | global.header.xml exists |
title | template | template.title.contentgrid.xml copied from template.title.documentlibrary.xml |
navigation | template | template.navigation.contentgrid.xml copied from template.navigation.documentlibrary.xml |
toolbar | template | template.toolbar.contentgrid.xml copied from template.toolbar.documentlibrary.xml |
gridview | template | template.gridview.contentgrid.xml created new |
filter | template | template.filter.contentgrid.xml copied from template.filter.documentlibrary.xml |
tree | template | template.tree.contentgrid.xml copied from template.tree.documentlibrary.xml |
tags | template | template.tags.contentgrid.xml copied from template.tags.documentlibrary.xml |
footer | global | global.footer.xml exists |
<?xml version='1.0' encoding='UTF-8'?>
<component>
<scope>template</scope>
<region-id>gridview</region-id>
<source-id>contentgrid</source-id>
<url>/someco/components/contentgrid/gridview</url>
</component>
Create a temporary ui webscript to render a simple message. In the alfresco/site-webscripts source folder, create folders com/orbitz/components/contentgrid to contain our ui webscripts supporting the content grid. Create the following three files:
gridview.get.desc.xml
<webscript>
<shortname>gridview</shortname>
<description>A simple grid view to view content in a grid layout</description>
<url>/orbitz/components/contentgrid/gridview</url>
</webscript>
gridview.get.html.ftl
This is the grid view!
gridview.get.properties
## Titles
title=New Content
header=New Content Details
## Labels
label.name=Name
label.title=Title
label.description=Description
label.content=Content
The last file 'gridview.get.properties' isn't needed yet, but we should have it around when we need it.
Next, modify the contentgrid.xml file in the config/alfresco/site-data/template directory to reference this 'contentgrid.ftl' template.
Finally, create a content template: . Restart the Share app and navigate to the site where this page is configured, and view the page. It should render similar to the document library page.
Now we can test our new contentgrid template with our temporary ui webscript displayed. Deploy (ant deploy) and restart Share. Navigate to our site and display the 'content grid' page.
Step 5 - Creating a new page component using ui web scripts
The next blog articles will add the desired functionality to share as time allows. We will create a new UI web script that calls a data webscript that serves the metadata and content extract from the document library to display in a grid form.