Overview
The templates are applied to a NodeType or a metadata MixinType. Two kinds of templates exist :
dialogs : are html forms that allow to create node instances.
views : are html fragments used to display nodes.
From the ECM admin portlet, Manage Template lists existing NodeTypes that have been associated to Dialog and/or View templates. These templates can be attached to permissions (in the usual membership:group_ form), so that a specific one is displayed according to the rights of the user (very useful in a content validation workflow activity).
DocumentType
checkbox allows to say if the NodeType should be considered as a DocumentType. File Explorer considers such nodes as user content and applies the following behavior :
View template will be used to display the DocumentType nodes
DocumentTypes nodes can created by the 'Add Document' action
non DocumentType are hidden (unless 'Show non document types' option is checked)
Templates are written using Groovy Templates and will require some experience with JCR API and HTML notions.
Dialogs are groovy templates that generate forms by mixing static HTML fragments and groovy calls to the components responsible for building the UI at runtime. The result is a simple but powerful syntax.
These following parameters are common and can be used for every input fields.
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| jcrPath | String |
| relative path inside the current node | jcrPath=/node/exo:title |
| mixintype | String with comma , character |
| List of the mixin types you want to initialize when creating the content |
|
| validate | String with comma , character |
| List of the validators you want to apply to the input. Possible values are : name, email, number, empty, null, datetime, length OR validator classes |
|
| editable | String |
| The input will be editable only if the value of this parameter is if-null and the value of this input is null or blank | editable=if-null |
| multiValues | Boolean |
| Show a multi values component if true. Must be used only with corresponding multi-values properties. The default value of this parameter is false | multiValues=true |
| visible | Boolean |
| The input is visible if this value is true | visible=true |
See also:
Note that mixintype can be used only in the root node field (commonly known as the name field)
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| rows | Number |
| The initial textarea's number of rows. The value is 10 by default | rows=20 |
| cols | Number |
| The initial textarea's number of cols. The value is 30 by default | cols=50 |
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| options | String with semicolon ; character |
| Some options for CKEditor field: toolbar, width and height | options=CompleteWCM;width:'100%';height:'200px'; |
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| toolbar | String |
| The pre-define toolbar for CKEditor. The value can be: Default, Basic, CompleteWCM, BasicWCM, SuperBasicWCM | options=CompleteWCM |
| width | String |
| The width of CKEditor. The value can be the percent of pixel | options=width:'100%' |
| height | String |
| The height of CKEditor. The value can be the percent of pixel | options=height:'200px' |
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| options | String |
| An option for calendar field: Display time | options=displaytime |
See also: Common parameters
See also: Common parameters
There are 2 main cases when creating an upload form: You want to store the image as a property OR as a node.
If you want to use property so you can do as follow:
<%
String[] fieldMedia = ["jcrPath=/node/exo:image"] ;
uicomponent.addUploadField("media", fieldMedia) ;
%>
If you want to use node so you can do as follow:
<%
String[] hiddenField1 = ["jcrPath=/node/exo:image", "nodetype=nt:resource", "visible=false"] ;
String[] hiddenField2 = ["jcrPath=/node/exo:image/jcr:encoding", "visible=false", "UTF-8"] ;
String[] hiddenField3 = ["jcrPath=/node/exo:image/jcr:lastModified", "visible=false"] ;
uicomponent.addHiddenField("hiddenInput1", hiddenField1) ;
uicomponent.addHiddenField("hiddenInput2", hiddenField2) ;
uicomponent.addHiddenField("hiddenInput3", hiddenField3) ;
String[] fieldMedia = ["jcrPath=/node/exo:image"] ;
uicomponent.addUploadField("media", fieldMedia) ;
%>
But, this code is not complete. If you want to display the upload field, the image must be blank, otherwise you can display the image and an action enables you to remove it. You can do as follows:
<%
def image = "image";
// If you're trying to edit the document
if(uicomponent.isEditing()) {
def curNode = uicomponent.getNode();
// If the image existed
if (curNode.hasNode("exo:image")) {
def imageNode = curNode.getNode("exo:image") ;
// If the image existed and available
if (imageNode.getProperty("jcr:data").getStream().available() > 0 && (uicomponent.findComponentById(image) == null)) {
def imgSrc = uicomponent.getImage(curNode, "exo:image");
def actionLink = uicomponent.event("RemoveData", "/exo:image");
%>
<div>
<img src="$imgSrc" width="100px" height="80px"/>
<a href="$actionLink">
<img src="/eXoResources/skin/DefaultSkin/background/Blank.gif" alt="" class="ActionIcon Remove16x16Icon"/>
</a>
</div>
<%
} else {
String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
uicomponent.addUploadField(image, fieldImage) ;
}
} else {
String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
uicomponent.addUploadField(image, fieldImage) ;
}
} else if(uicomponent.dataRemoved()) {
String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
uicomponent.addUploadField(image, fieldImage) ;
} else {
String[] fieldImage = ["jcrPath=/node/exo:image/jcr:data"] ;
uicomponent.addUploadField(image, fieldImage) ;
}
%>
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| options | String with comma , characters |
| Some radio values | options=radio1,radio2,radio3 |
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| options | String with comma , characters |
| Some option values | options=option1,option2,option3 |
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| options | String with comma , characters |
| Some checkbox values | options=checkbox1,checkbox2,checkbox3 |
See also: Common parameters
See also: Common parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| selectorClass | String |
| The component to display | selectorClass=org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector |
| selectorIcon | String |
| The action icon | selectorIcon=SelectPath24x24Icon |
Depending on the selectorClass, some other parameters can be added.
For example: The component org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector need these parameters
| Parameter | Type | Required | Description | Example |
|---|---|---|---|---|
| workspaceField | String |
| The field which allow to select a workspace | workspaceField=targetWorkspace |
The component org.exoplatform.ecm.webui.selector.UIPermissionSelector does not need any special parameters.
See also: Common parameters
To add an intercepter into a dialog, we can use this method
uicomponent.addInterceptor(String scriptPath, String type)
| Parameters | ||
|---|---|---|
| scriptPath | String | The relative path to the script file |
| type | String | The type of intercepter: prev or post |
To avoid refreshing the first tab for every action execution, we add a new private function to the template with tabs. In the template, we must insert new piece of code like the following:
private String getDisplayTab(String selectedTab) {
if ((uicomponent.getSelectedTab() == null && selectedTab.equals("mainWebcontent"))
|| selectedTab.equals(uicomponent.getSelectedTab())) {
return "display:block";
}
return "display:none";
}
private String getSelectedTab(String selectedTab) {
if (getDisplayTab(selectedTab).equals("display:block")) {
return "SelectedTab";
}
return "NormalTab";
}
Changing in every event of onclick is have to be done like this :
<div class="UITab NormalTabStyle">
<div class="<%=getSelectedTab("mainWebcontent")%>">
<div class="LeftTab">
<div class="RightTab">
<div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "mainWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.MainContent")%></div>
</div>
</div>
</div>
</div>
<div class="UITab NormalTabStyle">
<div class="<%=getSelectedTab("illustrationWebcontent")%>">
<div class="LeftTab">
<div class="RightTab">
<div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "illustrationWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.Illustration")%></div>
</div>
</div>
</div>
</div>
<div class="UITab NormalTabStyle">
<div class="<%= getSelectedTab("contentCSSWebcontent")%>">
<div class="LeftTab">
<div class="RightTab">
<div class="MiddleTab" onClick="<%=uicomponent.event("ChangeTab", "contentCSSWebcontent")%>"><%=_ctx.appRes("WebContent.dialog.label.Advanced")%></div>
</div>
</div>
</div>
</div>Finally, to display the selected tab, we will add it into the style of UITabContent class.
<div class="UITabContent" style="<%=getDisplayTab("mainWebcontent")%>">
<% def node = uicomponent.getNode() ; def originalNode = uicomponent.getOriginalNode() %>
<%=node.getName()%>
<%if(node.hasProperty("exo:title")) {%>
<%=node.getProperty("exo:title").getString()%>
<%}%>
<%
import java.text.SimpleDateFormat ;
SimpleDateFormat dateFormat = new SimpleDateFormat() ;
%>
...
<%if(node.hasProperty("exo:date")) {
dateFormat.applyPattern("MMMMM dd yyyy") ;
%>
<%=dateFormat.format(node.getProperty("exo:date").getDate().getTime())%>
<%}%>
<%=_ctx.appRes("Sample.view.label.node-name")%>