Each document type is represented by a node type in the JCR. Therefore, to create a new document type, you have to add a new node type. There are two ways to do this: through XML configuration files, or through the administration portlet.
To learn how to use the administration portlet, refer to the Admin Guide, found here:
| (!) | need link to admin guide |
Otherwise, you can create a new document type by configuring the file /WEB-INF/conf/wcm-extension/wcm/nodetypes-configuration.xml in your extension.
| (!) | Comment from Philippe: this part should go in the JCR part in the architecture primer. |
<nodeType name="exo:newnodetype" isMixin="true" hasOrderableChildNodes="false" primaryItemName=""> <supertypes> <supertype>exo:article</supertype> </supertypes> <propertyDefinitions> <propertyDefinition name="text" requiredType="String" autoCreated="true" mandatory="true" onParentVersion="COPY" protected="false" multiple="false"> <valueConstraints/> </propertyDefinition> <propertyDefinition name="date" requiredType="Date" autoCreated="false" mandatory="true" onParentVersion="COPY" protected="false" multiple="false"> <valueConstraints/> </propertyDefinition> </propertyDefinitions> </nodeType>
By defining a supertype, you can reuse other node types and extend them with more properties (just like inheritance in Object Oriented Programming).
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 (which can be useful in a content validation workflow activity).
The 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.
By placing interceptors in your template, you will be able to execute a groovy script just before and just after the node-save. Pre node-save interceptors are mostly used to validate input values and their overall meaning while the post node-save interceptor can be used to do some manipulation or reference for the newly created node such as binding it with a forum discussion or wiki space.
To place interceptors, use the following fragment :
<% uicomponent.addInterceptor("ecm-explorer/interceptor/PreNodeSaveInterceptor.groovy", "prev");%>
Interceptor groovy scripts are managed in the 'Manage Script' section in the ECM admin portlet. They must implement the CmsScript interface. Pre node-save are passed input values within the context :
public class PreNodeSaveInterceptor implements CmsScript {
public PreNodeSaveInterceptor() {
}
public void execute(Object context) {
Map inputValues = (Map) context;
Set keys = inputValues.keySet();
for(String key : keys) {
JcrInputProperty prop = (JcrInputProperty) inputValues.get(key);
println(" --> "+prop.getJcrPath());
}
}
public void setParams(String[] params) {}
}
Whereas post node-save one are passed the path of the saved node in the context:
<% uicomponent.addInterceptor("ecm-explorer/interceptor/PostNodeSaveInterceptor.groovy", "post");%>
public class PostNodeSaveInterceptor implements CmsScript {
public PostNodeSaveInterceptor() {
}
public void execute(Object context) {
String path = (String) context;
println("Post node save interceptor, created node: "+path);
}
public void setParams(String[] params) {}
In the next code sample, each argument is composed of a set of keys and values. The order of the arguments are not important and only the key matters. That example builds a field which has the id "hiddenInput4", which will generate a date which will not be visible. In other words the value of the field will be automatically set to the current date value and no visible field will be printed on the form.
String[] hiddenField4 = ["jcrPath=/node/jcrcontent/jcr:lastModified", "visible=false"];
uicomponent.addCalendarField("hiddenInput4", hiddenField4);
Once the form is saved, that date value will be saved in under the relative JCR path ./exo:image/jcr:lastModified
In many cases, when creating a Node instance out of a form, one must still tell the CMS service about the structure of that node. In other words, the template creator must tell what nodetype is a child of the newly created node or if that current node has any mixin type attributed.
By defining these arguments, the node and its children are created with the correct nodetype and mixintype.
See the following example :
String[] hiddenField = ["jcrPath=/node/jcrcontent", "nodetype=nt:resource", "mixintype=exo:rss-enable", "visible=false"] ;
uicomponent.addHiddenField("hiddenInput", hiddenField) ;
In the previous sample, the value was automatically created and set according to the current date. However, it is also possible to set a default value for a field.
Furthermore, as no widget is specified then a text widget is used. The widget will still not be visible.
String[] hiddenField = ["jcrPath=/node/jcrcontent/jcr:mimeType", "image/jpeg"] ;
uicomponent.addHiddenField("hiddenInput", hiddenField) ;
It is possible to create widgets that are non editable (and then only used to print some information). Furthermore, it is possible to tell that a widget should be visible only if its value is not null, in other words when the form is used to edit an already existing node.
String nameArgs[] = ["jcrPath=/node", "mixintype=mix:votable", "visible=if-not-null"];
uicomponent.addMixinField("name", nameArgs )
The "What You See Is What You Get" widget is one of the most powerful one. It prints an advanced javascript text editor with many functionalities including the ability to dynamically upload images or flash assets into a JCR workspace and then to reference them from the created HTML text.
String[] fieldSummary = ["jcrPath=/node/exo:summary", "options=basic"] ;
uicomponent.addWYSIWYGField("summary", fieldSummary) ;
The "options" argument is used to tell the component which toolbar should be used.
By default there are two options for the toolbar:
basic: a minimal set of icons is printed
default: a large set of icons is printed, no options argument is needed in that case
There is also a simple textarea widget:
String [] descriptionArgs = ["jcrPath=/node/exo:title", "validate=empty"];
uicomponent.addTextAreaField("description", descriptionArgs) ;
We also provide a selectbox widget with a simple default mechanism where we can print all the available static options, separated with comma, in the "options" argument of the directive. The argument with no key (here "text/html") is the selected option of the list.
String[] mimetype = ["jcrPath=/node/jcrcontent/jcr:mimeType", "text/html", "options=text/html,text/plain"] ;
uicomponent.addSelectBoxField("mimetype", mimetype) ;
As usual, the value will be stored at the relative path defined by the jcrPath directive argument.
For more example on how to create WCM templates, take a look at the reference guide.
A taxonomy is a particular classification arranged in a hierarchical structure. Taxonomy trees in eXo Platform will help organize your content into categories.
When you create a new taxonomy tree, you add a preconfigured exo:action (exo:scriptAction or exo:businessProcessAction) to the root node of the taxonomy tree. This action is triggered when a new document is added anywhere in the taxonomy tree. The default action moves the document to the physical storage location and replaces the document in the taxonomy tree by a symlink of type exo:taxonomyLink that points to it. The physical storage location is defined by a workspace name, a path and the current date and time. As with adding document types, taxonomy trees can be managed either through the Administration portlet, or by adding XML files.
To configure taxonomy trees by adding configuration files in the /webapp/WEB-INF/conf/acme-portal/wcm/taxonomy/ directory, create a new file called $taxonomyName-taxonomies-configuration.xml. For example, if the name of your taxonomy tree is acme, the file should be named acme-taxonomies-configuration.xml.
You can view the file here: $PLFHOME/samples/acme-website/webapp/src/main/webapp/WEB-INF/conf/acme-portal/wcm/taxonomy/acme-taxonomies-configuration.xml
As you can see, the value-params allow you to define the repository, workspace, name of the tree and its JCR path. You can then configure permissions for each group of users in the portal, as well as the triggered action when a new document is added to the taxonomy tree. Finally, you can describe the structure and names of the categories inside your taxonomy tree.