Introduction
The purpose of this post is to introduce the steps required to add a page to Share using some of the updates outlined in my previous post. Hopefully if you've had previous experience of adding pages to Share you'll see how this approach simplifies the process. As this series of posts continues the examples will get progressively more detailed - I just want to get the basic concepts nailed down first!As with the last post, this information refers to the latest code in HEAD SVN and will appear in future 4.2 Community and Enterprise releases.Create a New Page
To create a new page in Share using the new capabilities added by recent updates you can now do the following:
- Create a new WebScript (made up of the following files)
- “new-page.get.desc.xml” (WebScript descriptor)
- “new-page.get.js” (WebScript controller)
- “new-page.get.html.ftl” (WebScript template)
- Place these files in any path under “<tomcat-home>/webapps/share/WEB-INF/classes/alfresco/site-webscripts”
The WebScript Descriptor should contain the following:
<webscript>
<shortname>My New Page</shortname>
<url>/my-new-page</url>
</webscript>
The WebScript Controller should contain the following:
model.jsonModel = {
widgets: [{
name: 'alfresco/logo/Logo”
}]
};
The WebScript Template should contain the following:
<@processJsonModel group='share'/>
Now open the web browser of your choice and point it at http://<server>:<port>/share/page/dp/ws/my-new-page and you should see the following…Not the most exciting page in the world granted, but implemented with fairly minimal effort.Widget Creation Configuration
What if we don’t want to just display the Alfresco logo? What if we want to display a different logo? Fortunately the “alfresco/logo/Logo” widget declares a number of different CSS rules that allow us to easily change the logo that is rendered. Update the JavaScript controller to be the following:model.jsonModel = {
widgets: [{
name: 'alfresco/logo/Logo',
config: {
logoClasses: 'surf-logo-large'
}
}]
};
If you make the changes to the source files in the deployed web application you can apply these changes simply by refreshing the WebScripts by clicking the “Refresh Web Scripts” button on the Web Scripts home page (http://<server>:<port>/share/service/index)When you refresh the page you should now see:What we've done is simply add some instantiation arguments to the “alfresco/logo/Logo” widget to override the default “logoClasses” attribute with a different CSS class that a selector was defined in the CSS resource associated with it. In the JSON model the “name” attribute refers to the name of the widget that you want to instantiate (technically it refers to the Module Identifier or “MID”) and “config” attribute is an object passed during instantiation of that widget.A Simple Menu Bar
Let’s build something a bit more interesting; replace the contents of the JavaScript controller with the following:model.jsonModel = {
widgets: [{
name: 'alfresco/menus/AlfMenuBar',
config: {
widgets: [{
name: 'alfresco/menus/AlfMenuBarItem',
config: {
label: 'One'
}
},{
name: 'alfresco/menus/AlfMenuBarItem',
config: {
label: 'Two'
}
}]
}
}
]};
This now creates a basic menu bar with two menu items (don’t worry for the moment that these menu items don’t do anything yet, we’ll get onto that in a future post!).The key thing to note here is the use of the “widgets” attribute in the “config” object of the “alfresco/menus/AlfMenuBar”. Where one widget can be the parent to child widgets it is always possible for the model for those children to be defined in an array assigned to the “widgets” attribute. This repeating pattern is one of the many ways in which Surf is able to establish all the dependencies to load onto the page.Adding a Drop Down Menu
Let’s make the menu bar a bit more detailed, update the model to be the following:
model.jsonModel = {
widgets: [{
name: 'alfresco/menus/AlfMenuBar',
config: {
widgets: [{
name: 'alfresco/menus/AlfMenuBarPopup',
config: {
label: 'One',
widgets: [{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Popup item 1'
}
},{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Popup item 2'
}
}]
}
},{
name: 'alfresco/menus/AlfMenuBarItem',
config: {
label: 'Two'
}
}]
}
}
]};
The result should be:Adding Cascading Menus and Icons
We've now converted the first menu item to be popup menu containing two more menu items (note again the repeating config/widgets/config/widgets pattern). Let’s now add some icons to the menu items, do some grouping and add a cascading menu… try this model in your JavaScript controller:model.jsonModel = {
widgets: [{
name: 'alfresco/menus/AlfMenuBar',
config: {
widgets: [
{
name: 'alfresco/menus/AlfMenuBarPopup',
config: {
label: 'One',
widgets: [
{
name: 'alfresco/menus/AlfMenuGroup',
config: {
label: 'Group 1',
widgets: [{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Popup item 1',
iconClass: 'alf-edit-icon'
}
},{
name: 'alfresco/menus/AlfCascadingMenu',
config: {
label: 'Popup item 2',
iconClass: 'alf-cog-icon',
widgets: [
{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Cascaded menu item 1',
iconClass: 'alf-leave-icon'
}
},{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Cascaded menu item 2',
iconClass: 'alf-help-icon'
}
}]
}
}]
}
},{
name: 'alfresco/menus/AlfMenuGroup',
config: {
label: 'Group 2',
iconClass: 'alf-logout-icon',
widgets: [{
name: 'alfresco/menus/AlfMenuItem',
config: {
label: 'Popup item 3',
iconClass: 'alf-profile-icon'
}
}]
}
}]
}
},{
name: 'alfresco/menus/AlfMenuBarItem',
config: {
label: 'Two'
}
}]
}
}
]};
Once the WebScripts are refreshed and the page is reloaded you should see:Summary and Next Steps
Without writing a single line of (traditional) HTML, JavaScript or CSS it has been possible to construct a page containing a reasonably detailed menu bar. OK, so at the moment this menu bar doesn't actually do anything but we’re just getting started. The purpose of this post is simply to explain a new way of adding a page to Share and how to start building a JSON model for the contents of that page. In future posts I’ll be explaining how…
- To create your own widget to include in a model
- The various localization options for your pages and widgets
- To define events in your model and introducing some of the out-of-the-box event handling services
- The model is converted into dependencies and how to configure the dependency analysis
- To wrap existing JavaScript widgets to work in the model
If you've previously done any JavaScript controller extensibility it should be fairly obvious how the existing mechanisms can be used to easily add, change and remove things from a default model. One of the main advantages of the new header bar in Share is not that you can easily change it without copying and pasting all of the XML that defined it.The 'Hybrid Page'
The final thing I’d like to quickly point out is the availability of the “hybrid” view of page. By simply changing the URL to be http://<server>:<port>/share/page/hdp/ws/my-new-page (note the additional “h”) you will get the page content rendered between the standard Share header and footer.