Manage Templates

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 usefull in a content validation workflow activity).

A 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 behaviour :

  • 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.

The Dialog Syntax

Dialogs are groovy templates that generate forms by mixing static HTML fragments and groovy calls to the components responsible of building the UI at runtime. The result is a simple but powerfull syntax.

Interceptors

By placing interceptors in your template, you will be apple to execute a groovy script juste before and just after 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", "post");\%\>

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:

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) {}

Hidden fields

In the next code sample, each argument is composed of a set of key and values. The order of the argument is not important and only the key matters. That example builds a field which has the id "hiddenInput4", which will generate a date (as the widget is a calendar) but which is not 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.

TODO

Once the form is saved, that date value will be saved in under the relative JCR path ./exo:image/jcr:lastModified

Non value field, nodetype or mixintype creation

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 thet current node has any mixin type attributed.

The following syntax allow the admin to tell all that information to the service so that it can instanciate correctly the newly created Node and its children with the correct nodetype and mixintypes.

TODO

Hidden field with default value

In the first sample the widget was a calendar one and the value was automatically created and set according to the current date. in that new example we show that it is also possible to set a default value for a field.

Furthermore, as no widget is specified then a text widget is used. Here too the widget is not visible.

TODO

Non editable and visible if not null fields

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.

TODO

WYSIWYG widget

The "What You See Is What You Get" widget is one of the most powefull one. It prints an advanced javascript text editor with many functionnalities including the ability to dynamically upload images or flash assets into a JCR workspace and then to reference them from the created HTML text.

The syntax is once again quite simple especially when later you see the result of that single line of code.

TODO

Tthe "options" argument is used to tell to the component which toolbar should be used (a toolbar is a set of buttons that the editor will render).

By default there are three options:

  • input-only: no toolbar is printed
  • basic: a minimal set of icons is printed
  • default: a large set of icons is printed, no options argument is needed in that case
Note that there also exist a simple textarea widget:

TODO

A calendar widget with time

We already introduced the calendar widget, that widget can be extended with the use of the options=displaytime argument to print some time.

TODO

Upload widget

The dialog syntax also provides an upload widget which allows the user to upload a document withing the generated form. Once again the syntax is very simple and the result impressive.

TODO

Simple selectbox widget

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 "image/gif") is the selected option of the list.

TODO

As usual, the value will be stored at the relative path defined by the jcrPath directive argument.

Advanced dynamic select box

In many cases, the previous solution with static options is not good enough and one would like to have the select list filled dynamically. That is what we provide thanks to the introduction of a Groovy script as shown in the next code fragment.

#jsfDialogFormField("inputName=destWorkspace" "jcrPath=/node/exo:destWorkspace" "widget=selectbox" "production" "script=ecm-explorer/widget/FillSelectBoxWithWorkspaces.groovy")

The script itself implements the CmsScript interface and the cast is done to get the select box object as shown in the script code which fill the select list with the existing JCR workspaces.

import java.util.List ;
import java.util.ArrayList ;

import org.exoplatform.services.jcr.RepositoryService;
import org.exoplatform.services.jcr.core.ManageableRepository;

import org.exoplatform.faces.core.component.UISelectBox;
import org.exoplatform.faces.core.component.model.SelectItem;
import org.exoplatform.services.cms.scripts.CmsScript;

public class FillSelectBoxWithWorkspaces implements CmsScript {

  private RepositoryService repositoryService_;

  public FillSelectBoxWithWorkspaces(RepositoryService repositoryService) {
    repositoryService_ = repositoryService;
  }

  public void execute(Object context) {
    UISelectBox selectBox = (UISelectBox) context;

    ManageableRepository jcrRepository = repositoryService_.getRepository();
    List options = new ArrayList();
    String[] workspaceNames = jcrRepository.getWorkspaceNames();
    for(i in 0..<workspaceNames.length) {
      String name = workspaceNames[i];
      options.add(new SelectItem(name, name));
    }
    selectBox.setOptions(options);
  }

  public void setParams(String[] params) {}

Finally note that it is also possible to provide a parameter to the script by using the argument "scriptParams"

Widget with selector

One of the most advanced functionality of that syntax is the ability to plug your own component that will be used to help the user choose the value of the field.

In the generated form you will simple see an icon (it is configurable thanks to the selectorLabel argument, if its starts with a @ symbol then the value of the label will be taken from the portlet properties file) like:

The syntax is a bit more complex but not that much.

TODO

The selectorAction value is in itself not that important, it just must be unique among all the validators of the form.

You can plug your own component using the selectorClass argument. It just must follow eXo UIComponent mechanism and implements the interface Selector:

package org.exoplatform.faces.core;

import org.exoplatform.faces.core.component.UIExoComponent;

public interface Selector extends UIExoComponent{
  public void setHandler(SelectorHandler handler);
  public void setParameters(String[] args);
  public String[] getParameters();
  public String getInputValue();
}

where the SelectorHandler is of the form:

package org.exoplatform.faces.core;

public interface SelectorHandler {
  public void cancel(Selector selector) ;
  public void select(Selector selector) throws Exception ;
}

Selector that takes parameters

A Selector component can get parameters (they are passed thanks to the setParameter() method of the Selector interface). The argument used to give a parameter is the selectorParams one. If it starts with # then it means the value will be the value of another filed. In that case, the text after the # is the inputName of another component. That can be used as in the next code fragment to tell to the JcrBrowser selector component which workspace to use.

Multivalue widget

A widget can be a multi value one if you add the argument "multivalue=true" to the directive.

Manage template service

Template service allow create dialogs and views template for each node type registered. Each node type may have many dialogs and views template. The template will be used when create or view nodes.

<component>
    <key>org.exoplatform.services.cms.templates.TemplateService</key>
    <type>org.exoplatform.services.cms.templates.impl.TemplateServiceImpl</type>
    ..............
  </component>

As usual one can register a plugin inside the service. This plugin init default dialogs and views template of any node type as nt:file, exo:article, exo:workflowAction, exo:sendMailAction,...

<component-plugins>
        <component-plugin>
          <name>addTemplates</name>
          <set-method>addTemplates</set-method>
          <type>org.exoplatform.services.cms.templates.impl.TemplatePlugin</type>
          .........
        </component-plugin>
      </component-plugins>

With init parameters as:

TODO
 
Navigation

Creator: Administrator on 2007/05/23 04:30
Copyright (c) 2000-2009. Allright reserved - eXo platform SAS
1.6.13286