Let's take the same example as mentioned previously, of the Cignex website. We will create web forms for the blogs and news sections. Also, we will associate these web forms with the rendition templates. Finally, we will create content using web forms and preview it.
The process to define and create web forms in Alfresco is as follows:
To create a web form you are required to create an XML Schema Definition (XSD) file with an extension as .xsd
. XSD specifies how to formally describe the elements in an XML document. Before creating an XSD file you will need to decide what all user interface components you want to display in a web form. To create a schema for a web form, you analyze its structure defining each structural element as you encounter it. As mentioned previously, we will create web forms for the news and blogs sections. Consider that some of the elements that are required in creating an XSD file for news are: Brief Title, News Page Headline, News Page Sub Headline, News Page Content, News Article Graphic, Image Caption, Image Title, and News Date. Now that you have decided the elements, you will learn how to create an XSD file for simple user interface controls. You will know more about advanced controls in the short while.
To create an XSD file we have to start with the standard XML declaration followed by the xs:schema
element that defines a schema:
<?xml version="1.0" encoding="ISO-8859-1" ?> <xs:schema xmlns:xs=http://www.w3.org/2001/XMLSchema xmlns:trn="http://www.alfrescobook.com/webforms" xmlns:alf=http://www.alfresco.org targetNamespace="http://www.alfrescobook.com/webforms" elementFormDefault="qualified" > </xs:schema>
In the previous schema, we use the standard namespace (xs
), and the URI associated with this namespace is the schema language definition, which has the standard value of http://www.w3.org/2001/XMLSchema. It is important to specify a namespace (xlmns:trn
) for your web forms to eliminate collisions. You can have the same namespace for a specific development project. We will use this element while generating renditions. The alf
namespace is added to enable label, alert, and appearance elements while writing an XSD.
Now we can define elements inside a complex element. First we have to define a root element. Let's define news
as a root element. This element has an attribute and it contains other elements, therefore we consider it as a complex type. The child elements of the news
element are surrounded by an xs:sequence
element that defines an ordered sequence of sub-elements. The syntax for defining a complex element is:
<xs:element name="news"> <xs:complexType> <xs:sequence> ... </xs:sequence> </xs:complexType> </xs:element>
We can also define a few simple elements inside the complex element. Simple elements are those elements that do not contain any attribute. Each element is defined with a name and type. Let's define a few simple elements such as shortTitle, contentHeader, contentSubHeader, contentText
, and so on.
The syntax for defining a simple element is:
<xs:element name="shortTitle" type="xs:normalizedString"/>
Here shortTitle
is the name of the element and normalizedString
is the data type of the element. Following is an example of simple elements defining inside complex elements.
<xs:element name="news"> <xs:complexType> <xs:sequence> <xs:element name="shortTitle" type="xs:normalizedString "/> <xs:element name="contentHeader" type="xs:normalizedString "/> <xs:element name="contentSubHeader" type="xs:string"/> <xs:element name="contentText" type="xs:string"/> </xs:sequence> </xs:complexType> </xs:element>
An XML schema has a lot of built-in data types. Each of these data types has a default widget rendering within the generated XForm in Alfresco.
The following table shows the associated widgets with the most commonly used XSD data types:
XSD Data Type |
User Interface Widgets |
---|---|
|
Textbox |
|
WYSIWYG editor, Text area |
|
Calendar control |
|
Time picker |
|
Asset picker |
|
Checkbox |
|
Slider control |
|
Radio button, Drop down |
Now we will learn a few attributes that can be applied to an element in order to make it mandatory, optional, default value, or fixed value.
An attribute may have a default or fixed value. A default value is automatically assigned to the element and you can specify any other value. A fixed value is also automatically assigned to the element, but you cannot specify another value. This can be considered as a read-only value. Following is the code snippet for defining default value.
<xs:element name="contentHeader" type="xs:normalizedString"
default="News Full Headline">
We can define the number of possible occurrences for an element with the maxOccurs
and minOccurs
attributes. maxOccurs
specifies the maximum number of occurrences for an element and minOccurs
specifies the minimum number. The default value for both maxOccurs
and minOccurs
is 1
, which means the field is mandatory.
To set the element as optional, you have to set the value of minOccurs
to 0 as follows:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="0" maxOccurs="1">
The element can appear multiple times by setting the maxOccurs
attribute of the element to "unbounded", which means that there can be as many occurrences of the element as the content contributor wishes. We can also fix the occurrences of the element by specifying any number.
There are some advanced schemas attributes provided that will enhance the capabilities provided within a form. For instance, you may want to display images in the web form. You may also think of validation in the web forms that will validate your content. For this, you are required to customize some of the widgets in web forms.
Alfresco uses the xs:anyURI
data type to overcome limitations such as inter-document relationships. Although XML standards do exist for defining relationships (XPointer and XLink), both are stagnant (no updates since 2001) and neither has achieved widespread adoption:
<xs:element name="contentGraphic" type="xs:anyURI" />
This results in an "asset picker" widget, which will allow the content contributor to browse and select content from the web project. The following code snippet provides the ability to specify an image picker to get the images from any folder in the web project:
<xs:element name="contentGraphic" type="xs:anyURI" minOccurs="0" maxOccurs="1" <xs:annotation> <xs:appinfo> <alf:label>News Article Graphic</alf:label> <alf:appearance>image_file_picker</alf:appearance> </xs:appinfo> </xs:annotation> </xs:element>
On implementation of this code snippet, a Select button (shown in the following screenshot) will be displayed for each of the images:
We also have a few other preconfigured appearance options defined in the web-client-config-wcm.xml
file, which is placed under<install-alfresco>/tomcat/webapps/alfresco/WEB-INF/classes/alfresco/
.
Here are some examples of preconfigured appearances from the web-client-config-wcm.xml
file:
Appearance |
Description |
---|---|
|
Picks files from a specific folder |
|
Searches files from a specific folder |
|
Uploads images |
|
Uploads HTML files |
|
Uploads folders |
|
Uploads any file |
If you want to upload HTML files, you have to put html_file_picker
inside the<alf:appearance>
tag. For files and folders you can have file_picker
and folder_picker
respectively.
Suppose you want to provide restrictions to file pickers and be relative to the root of the web project folder. Thus, the contents of the specified folder will be available for selecting in the file picker. This can be achieved by uncommenting the section in the code below (which is highlighted in bold) in the same web-client-config-wcm.xml
file:
<widget xforms-type="xf:upload" appearance="folder_restricted_file_picker" javascript-class-name="alfresco.xforms.FilePicker"> <param name="selectable_types">wcm:avmcontent,wcm:avmfolder</param> <param name="folder_restriction">/common/pages</param> </widget>
Define this widget in the XSD file, as follows:
<xs:element name="contentGraphic" type="xs:anyURI" minOccurs="0" maxOccurs="1"
<xs:annotation>
<xs:appinfo>
<alf:label>News Article Graphic</alf:label>
<alf:appearance>folder_restricted_file_picker</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
This customized file picker will search for only folders inside common/pages folder as shown in the following screenshot:
Another important feature, which will make search faster and time saving, is the reusability of search. You don't have to browse every time for the files.
The config_search_name
parameter must be set to the name of a configured search. The file picker contents will be restricted to the results of this named configured search. The configured search must be stored in the Public Saved Searches
folder.
The search is Lucene based and it will only query content of the Staging Sandbox. The public saved search is actually stored as an XML document in the Alfresco repository. Therefore, we can modify it with any Lucene query that is supported by Alfresco WCM search. The following code snippet will search for "training" as a text in all of the files of the web project submitted to the staging server:
<widget xforms-type="xf:upload" appearance="search_restricted_file_picker" javascript-class-name="alfresco.xforms.FilePicker"> <param name="config_search_name">training</param> </widget>
Define this widget in the XSD file, as follows:
<xs:element name="contentGraphic" type="xs:anyURI" minOccurs="0" maxOccurs="1"
<xs:annotation>
<xs:appinfo>
<alf:label>News Article Graphic</alf:label>
<alf:appearance>search_restricted_file_picker</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
The following screenshot shows how to save 'config_search_name' text in a public search folder so that this can used while searching in the web project:
The file picker will search all files having the word "training" within its name. The following screenshot shows the search result:
You can also customize file pickers. You have to define all customizations in web-client-config-wcm.xml
. Using the following code snippet you will have the option of selecting only JPEG files from the web project. The selectable_types
parameter must be set to restrict which types of content are selectable in the widget.
The filter_mimetypes
parameter can be used to filter selectable files by MIME types:
<widget xforms-type="xf:upload"
appearance="custom_image_file_picker"
javascript-class-name="alfresco.xforms.FilePicker">
<param name="selectable_types">wcm:avmcontent</param>
<param name="filter_mimetypes">image/jpeg</param>
</widget>
Define this widget in the XSD file, as follows:
<xs:element name="image" type="xs:anyURI" minOccurs="0" maxOccurs="1"
<xs:annotation>
<xs:appinfo>
<alf:appearance>custom_image_file_picker</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
Since we have customized file picker, in the following screenshot you will find only JPEG files:
With the previous code snippet, we have customized image_file_picker
. In this manner, you can customize other file pickers also.
You can also provide a label for an element specified in your XSD file. By default, the label created by the form processor for each element is simply the element's name. You could also get a tool tip for the label you have provided. Hence, the label becomes News Page Sub-Headline
instead of contentSubHeader
. Whenever you drag a mouse over the label you will get help for the label:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="0" maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<alf:label>News Page Sub-Headline</alf:label>
<alf:hint>Please enter the news page sub-headline if the news has a sub-headline.</alf:hint>
</xs:appinfo>
</xs:annotation>
</xs:element>
You can also localize the label or alert by specifying a message bundle key in the annotation:
<xs:element name="emailId" type="xs:string">
<xs:annotation>
<xs:appinfo>
<alf:label>${email}</alf:label>
</xs:appinfo>
</xs:annotation>
</xs:element>
This can be achieved by creating the following message bundle file. Create a property file with name strings.properties
in the Company Home | Data Dictionary | Web Forms | <form space name>| strings.properties with the following code:
email = Please enter a proper Email Id .
The property files can also be internationalized by having different versions for language or locale combination. The default configured property file locations from highest to lowest precedence are:
webclient.properties
placed in<install-alfresco>/tomcat/webapps/alfresco/WEB-INF /classes/alfresco/messages/
.You can provide validations to any of the fields. For instance, if you provide the correct order ID, the element will be highlighted in red. This indicates that the value of the element must be a string, it must be exactly six characters in a row, and those characters must be a number from 0 to 9:
<xs:element name="orderId"> <xs:simpleType> <xs:restriction base="xs:string"> <xs:pattern value="[0-9]{6}"/> </xs:restriction> </xs:simpleType> </xs:element>
You can customize the WYSIWYG editor easily. The WYSIWYG editor is the TinyMCE editor. When we define a simple element of type string, we can see Rich Text Editor with limited functionalities. We can also have many other features available with Rich Text Editor. See the following code for the advanced editor. With this we can have features such as alignment, font family, and font size:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<alf:label>News Page Sub-Headline</alf:label>
<alf:hint>Please enter the news article sub-headline if the article has a sub-headline.</alf:hint>
<alf:appearance>full</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
If you want more advanced features for the editor, such as table, you can use the following code in the XSD file:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="1" maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<alf:label>News Page Sub-Headline</alf:label>
<alf:hint>Please enter the news article sub-headline if the article has a sub-headline.</alf:hint>
<alf:appearance>custom</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
Suppose you want to customize these editors. You want to hide bold, italic feature and reduce the height of the editor. The customization code has to be placed in the<install-alfresco>/tomcat/webapps/alfresco/WEB-INF /classes/alfresco/web-client-config-wcm.xml
file.
Place the following code:
<widget xforms-type="xf:textarea" appearance="customnews" javascript-class-name="alfresco.xforms.RichTextEditor"> <param name="theme_advanced_buttons1">underline,separator, forecolor,backcolor, separator,link,unlink,image</param> <param name="height">100</param> </widget>
Place this code in the XSD file:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="1" maxOccurs="1"> <xs:annotation> <xs:appinfo> <alf:label>News Page Sub-Headline</alf:label> <alf:hint>Please enter the news page sub-headline if the news has a sub-headline.</alf:hint> <alf:appearance>customnews</alf:appearance> </xs:appinfo> </xs:annotation> </xs:element>
Another customization that will allow you to see the source code of the HTML and insert media files in the Rich Text Editor if required is as follows. Open the web-client-config-wcm.xml
file. Replace the code with the following highlighted code:
<widget xforms-type="xf:textarea" appearance="custom" javascript-class-name="alfresco.xforms.RichTextEditor"> <param name="theme_advanced_buttons1">bold,italic,underline, strikethrough,separator,fontselect, fontsizeselect,code</param> <param name="theme_advanced_buttons2">link,unlink,image, separator,justifyleft,justifycenter,justifyright, justifyfull,separator,bullist,numlist,separator, undo,redo,separator,forecolor,backcolor</param> <param name="height">600</param> <param name="mode">exact</param> <param name="force_p_newlines">true</param> <param name="apply_source_formatting">true</param> <param name="plugins">table,paste,media</param> <param name="theme_advanced_buttons3">tablecontrols,media</ param> </widget>
Place the following code in the XSD file:
<xs:element name="contentSubHeader" type="xs:string" minOccurs="1"
maxOccurs="1">
<xs:annotation>
<xs:appinfo>
<alf:label>News Page Sub-Headline</alf:label>
<alf:hint>Please enter the news pagesub-headline if the page has a sub-headline.</alf:hint>
<alf:appearance>custom</alf:appearance>
</xs:appinfo>
</xs:annotation>
</xs:element>
A drop-down list can be handled with the xs:enumeration
element within the xs:restriction
element that defines the type of enumeration. For example, all the values in the list should be string
, as follows:
<xs:element name="disclaimer" minOccurs="0" maxOccurs="1"> <xs:annotation> <xs:appinfo> <alf:label>Disclaimer</alf:label> <alf:appearance>minimal</alf:appearance> </xs:appinfo> </xs:annotation> <xs:simpleType> <xs:restriction base="xs:string"> <xs:enumeration value="news" /> <xs:enumeration value="blogs" /> </xs:restriction> </xs:simpleType> </xs:element>
Use of includes will enable you to reuse the common structure across multiple files. You can also call a web script in include schemaLocation
. Please note: for this, the virtual server should be running. We will see example of includes in the later sections.
<xs:include schemaLocation="/common/inc/contentType.xsd" /> <xs:include schemaLocation="/common/inc/contentType.jsp "/> <xs:include schemaLocation="webscript://path/to/my/webscript?storeid={storeid}" /> <xs:import namespace="imported_namespace" schemaLocation="webscript://path/with/the/{storeid}/embedded?ticket={ticket}" />
For more information about XSD, refer to the website http://www.w3.org/XML/Schema.
In order to create the XSD file, follow these steps:
<installed-alfresco>/extras
. Create folder wcm/forms
. news.xsd
in the above-specified path and populate it with the downloaded code from Packt's website. blogs.xsd
in the above-specified path and populate it with the downloaded code from Packt's website. training.xsd
in the above-specified path and populate it with the downloaded code from Packt's website.The XSD file is now ready to use. The next task is to create web forms. For this you first have to create a web project. This section uses the web project that you have already created as a part of your Cignex sample application in Chapter 3. As a part of the sample application, you will manage content in the Cignex web project. For more information about the web project and sample application, refer to Chapter 3.
You can create a web form using two ways:
The process to create web forms is as follows:
news.xsd
file created in the folder<installed-alfresco>/extras/wcm/forms
. After uploading, it will automatically fill up the values like Root element, Name, Title, and Output path pattern. You can change the output path pattern. This means the XML file will be created in the specified path. Take a look at the following screenshot and change the Output path pattern and Description as specified. Then click on Next. news.xsd
file. blogs.xsd
and training.xsd
files.Please provide the Output path pattern as common/inc/${name}.xml
for creating blogs and training web forms when the Web Form Details window is opened.
Do not proceed to the subsequent sections without first creating the web forms. The remaining sample solution is based on these web forms. Please specify the Output path pattern as shown in a previous screenshot for news, training, and the blogs web form.
The Alfresco Wiki website (http://wiki.alfresco.com/wiki/Forms_Developer_Guide and http://wiki.alfresco.com/wiki/Creating_XForms_Widgets) contains information about forms and widgets.