eXo Platform 3.5

- Prev
- Next

## Chapter 4. Developer references

## WCM Templates

### Content types

Overview

The templates are applied to a node type or a metadata mixin type. There are two types of templates:

- Dialogs are in the HTML form that allows creating node instances.

- Views: are in the HTML fragments which are used to display nodes.

From the ECM admin portlet, the Manage Template lists existing node types 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).

Document Type

1. The checkbox defines if the node type should be considered as the Document type or not. Content Explorer considers such nodes as user content and applies the following behavior:

- View template will be used to display the document type nodes.

- Document types nodes can be created by the 'Add Document' action.

- Non-document types are hidden (unless the 'Show non document types' option is checked).

Templates are written by using Groovy Templates that requires some experiences with JCR API and HTML notions.

#### Dialog

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.

##### Common parameters

These following parameters are common and can be used for all 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 mixin types you want to initialize when creating the content. | mixintype=mix:i18n mixintype=mix:votable,mix:commentable,mix:i18n
validate | String with comma `,` character |  | List of validators you want to apply to the input. Possible values are: name, email, number, empty, null, datetime, length OR validator classes. | validate=empty validate=empty,name validate=org.exoplatform.webui.form.validator.StringLengthValidator
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-valued component if true and must be used only with corresponding multi-valued 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:

- Text field

- Hidden field

- Text area field

- Rich text field

- Calendar field

- Upload field

- Radio field

- Select box field

- Checkbox field

- Mixin field

- Action field

### Note

The mixintype can be used only in the root node field (commonly known as the name field).

##### Text Field

- Additional parameters

See also: Common parameters

- Example

    <%

      String[] fieldTitle = ["jcrPath=/node/exo:title", "validate=empty"] ;

      uicomponent.addTextField("title", fieldTitle) ;

    %>

##### Hidden Field

- Additional parameters

See also: Common parameters

- Example

    String[] hiddenField5 = ["jcrPath=/node/jcr:content/dc:date", "visible=false"];

      uicomponent.addCalendarField("hiddenInput5", hiddenField5);

##### Text Area Field

- Additional parameters

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
rows | `Number` |  | The initial text area's number of rows. The value is `10` by default. | `rows=20`
cols | `Number` |  | The initial text area's number of cols. The value is `30` by default . | `cols=50`

See also: Common parameters

- Example

    <%

      String[] fieldDescription = ["jcrPath=/node/exo:description", "validate=empty"] ;

      uicomponent.addTextAreaField("description", fieldDescription) ;

    %>

##### Rich Text Field

- Additional 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';`
toolbar | `String` |  | The predefined toolbar for CKEditor. The value can be: `Default`, `Basic`, `CompleteWCM`, `BasicWCM`, `SuperBasicWCM` | `options=CompleteWCM`
width | `String` |  | The width of CKEditor. Its value can be the percent of pixel. | `options=width:'100%'`
height | `String` |  | The height of CKEditor. Its value can be the percent of pixel. | `options=height:'200px'`

See also: Common parameters

- Example

    <%

      String[] fieldSummary = ["jcrPath=/node/exo:summary", "options=toolbar:CompleteWCM,width:'100%',height:'200px'", "validate=empty"] ;

      uicomponent.addRichtextField("summary", fieldSummary) ;

    %>

##### Calendar Field

- Additional parameters

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
options | `String` |  | An option for the calendar field: Display time | `options=displaytime`

See also: Common parameters

- Example

    <%

      String[] fieldPublishedDate = ["jcrPath=/node/exo:publishedDate", "options=displaytime", "validate=datetime", "visible=true"] ;

      uicomponent.addCalendarField("publishedDate", fieldPublishedDate) ;

    %>

##### Upload Field

- Additional parameters

See also: Common parameters

- Example

When you create an upload form, there are two main ways to store an

- If you want to store as property, use the following code:

    <%

      String[] fieldMedia = ["jcrPath=/node/exo:image"] ;

      uicomponent.addUploadField("media", fieldMedia) ;

    %>

- If you want to store as node, use the following code:

    <%

      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) ;

        }

    %>

##### Radio Field

- Additional parameters

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
options | `String` with comma `,` characters |  | Some radio values | `options=radio1,radio2,radio3`

See also: Common parameters

- Example

    <%

      String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=radio1,radio2,radio3"];

      uicomponent.addRadioBoxField("isDeep", fieldDeep);

    %>

##### Select box Field

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
options | `String` with comma `,` characters |  | Some option values | `options=option1,option2,option3`

See also: Common parameters

- Example

    <%

      String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=checkbox1,checkbox2,checkbox3"];

      uicomponent.addCheckBoxField("isDeep", fieldDeep);

    %>

##### Checkbox Field

- Additional parameters

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
options | `String` with comma `,` characters |  | Some checkbox values | `options=checkbox1,checkbox2,checkbox3`

See also: Common parameters

- Example

    <%

      String[] fieldDeep = ["jcrPath=/node/exo:isDeep", "defaultValues=true", "options=checkbox1,checkbox2,checkbox3"];

      uicomponent.addCheckBoxField("isDeep", fieldDeep);

    %>

##### Mixin Field

- Additional parameters

See also: Common parameters

- Example

    <%

      String[] fieldId = ["jcrPath=/node", "editable=false", "visible=if-not-null"] ;

      uicomponent.addMixinField("id", fieldId) ;

    %>

##### Action Field

- Additional 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` needs the following parameters:

Parameter | Type | Required | Description | Example
--- | --- | --- | --- | ---
workspaceField | `String` |  | The field which enables you to select a workspace. | `workspaceField=targetWorkspace`

The component `org.exoplatform.ecm.webui.selector.UIPermissionSelector` does not need any special parameters.

See also: Common parameters

- Example

    <%

      String[] fieldPath = ["jcrPath=/node/exo:targetPath", "selectorClass=org.exoplatform.ecm.webui.tree.selectone.UIOneNodePathSelector", "workspaceField=targetWorkspace", "selectorIcon=SelectPath24x24Icon"] ;

      uicomponent.addActionField("targetPath", fieldPath)  ;

    %>

##### Interceptors

To add an interceptor to a dialog, you 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 interceptor: `prev` or `post`.

- Example

    <%

      uicomponent.addInterceptor("ecm-explorer/interceptor/PreNodeSaveInterceptor.groovy", "prev");

    %>

##### How to add a new ECM template with tabs

To avoid refreshing the first tab for every action execution, add a new private function to the template with tabs. In the template, you must insert a 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 must be done like the following:

    <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, simply add it to the style of UITabContent class.

    <div class="UITabContent" style="<%=getDisplayTab("mainWebcontent")%>">

#### View

    <%

      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")%>

### List of Contents

#### Content List Template

The Content List Template allows you to view the content list with various templates. eXo Platform supports the following content list templates:

Template | Description
--- | ---
BigHotNewsTemplateCLV.gtmpl | Display contents under one column with a content list. The illustration of each content is displayed above the content.
ContentListViewerDefault.gtmpl | Its function is similar to BigHotNewsTemplateCLV.gtmpl. The illustration of each content is bigger.
DocumentsTemplate.gtmpl | Display contents under a content list with a NodeType icon or the illustration on the left of the corresponding content.
EventsTemplateCLV.gtmpl | Its function is similar to BigHotNewsTemplateCLV.gtmpl, but the illustration of each content is smaller.
OneColumnCLVTemplate.gtmpl | Display contents under one column. The illustration of each content is displayed on its left.
TwoColumnsCLVTemplate.gtmpl | Display contents under two columns. The illustration of each content is displayed on its left.
UIContentListPresentationBigImage.gtmpl | Its function is similar to BigHotNewsTemplateCLV.gtmpl, but the illustration of each content is bigger than the image displayed with ContentListViewerDefault.gtmpl and the text font is different.
UIContentListPresentationDefault.gtmpl | Its function is similar to BigHotNewsTemplateCLV.gtmpl, but the illustration of each content is smaller and the text font is different.
UIContentListPresentationSmall.gtmpl | Display contents under one column with a content list. The images are displayed on the left of the corresponding content and smaller than the images of the other templates.

#### Category Navigation Template

The Category Navigation Template displays all contents under the categories.

Template | Description
--- | ---
CategoryList.gtmpl | Display categories as a navigation bar.
CategoryTree.gtmpl | Display categories as a tree.
TagsCloud.gtmpl | Display all tags of the contents.

## WCM Explorer

### CSS

- By using WCM, all the stylesheets of each site can be managed online easily. You do not need to access the file system to modify and wait until the server has been restarted. For the structure, each site has its own CSS folder which can contain one or more CSS files. These CSS files have the data, and the priority. If they have the same CSS definition, the higher priority will be applied. You can also disable some of them to make sure the disabled style will no longer be applied into the site.

- For example, a WCM demo package has two sites by default: ACME and Classic. The Classic site has a CSS folder which contains a CSS file called DefaultStylesheet. Most of the stylesheets of this site are defined within this stylesheet. Moreover, the ACME site has two CSS files called BlueStylesheet and GreenStylesheet. The blue one is enabled and the green one is disabled by default. All you need to test is to disable the blue one (by editing it and setting Available equals false) and enable the green one. Now, back to the homepage and see the magic.

### Note

Remember the cache and refresh the browser first if you do not see any changes. Normally, this is the main reason why the new style is not applied.

### CKEditor

Basically, if you want to add a rich text area to your dialogs, you can use the addRichtextField method. However, in case you want to add the rich text editor manually, you first need to use the addTextAreaField method and some additional Javascripts as shown below:

    <%

        String[] fieldDescription = ["jcrPath=/node/exo:description"] ;

        uicomponent.addTextAreaField("description", fieldDescription)

    %>

    <script>

      var instances = CKEDITOR.instances['description'];

      if (instances) instances.destroy(true);

      CKEDITOR.replace('description', {

        toolbar : 'CompleteWCM',

        uiColor : '#9AB8F3'

      });

    </script>

## Extensions

### REST Services

#### Overview

REST-style architectures consist of clients and servers. Clients initiate requests to servers; servers process requests and return appropriate responses. Requests and responses are built around the transfer of "representations" of "resources". A resource can be essentially any coherent and meaningful concept that may be addressed. A representation of a resource is typically a document that captures the current or intended state of a resource.

At any particular time, a client can either be in transition between application states or "at rest". A client in a REST state is able to interact with its users, but creates no load and consumes no per-client storage on the set of servers or on the network.

The client begins sending requests when it is ready to make the transition to a new state. While one or more requests are outstanding, the client is considered to be in transition. The representation of each application state contains links that may be used the next time, the client chooses to initiate a new state transition.

REST is initially described in the context of HTTP, but is not limited to that protocol. RESTful architectures can be based on other Application Layer protocols if they already provide a rich and uniform vocabulary for applications based on the transfer of meaningful representational state. RESTful applications maximize the use of the pre-existing, well-defined interface and other built-in capabilities provided by the chosen network protocol, and minimize the addition of new application-specific features on its top.

#### Restful Web Service

##### HTTP Methods

Here is the convention you should follow:

Method | Definition
--- | ---
GET | Get a Resource. Its state should not be modified.
POST | Create a Resource (or anything that does not fit elsewhere).
PUT | Update a Resource.
DELETE | Delete a Resource.

##### Formats

The followings are formats which need to be supported for all your APIs:

- JSON: This format makes developers easy to parse in a lot of languages, such as JavaScript, Python or Ruby.

- XML: Most of Java developers like using this format.

- ATOM: This is a standard format which can be used by many applications.

##### Data Format

The default format is JSON.

The response format can be specified by a parameter in the request: "format". You need to specify the format requested.

##### REST configuration

First, you need to register the REST service class to the configuration file in the package named conf.portal .

    <configuration xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">

      <component>

        <type>org.exoplatform.services.ecm.publication.REST.presentation.document.publication.PublicationGetDocumentRESTService</type>

      </component>

    </configuration>

##### Create a REST service

You can start creating GetEditedDocumentRESTService that implements from the ResourceContainer interface as follows:

    @Path("/presentation/document/edit/")

    public class GetEditedDocumentRESTService implements ResourceContainer {

        @Path("/{repository}/")

            @GET

            public Response getLastEditedDoc(@PathParam("repository") String repository,

               @QueryParam("showItems") String showItems) throws Exception {

               ........

            }

    }

Parameters | Definition
--- | ---
@Path("/presentation/document/edit/") | Specify the URI path which a resource or class method will serve requests for.
@PathParam("repository") | Bind the value repository of a URI parameter or a path segment containing the template parameter to a resource method parameter, resource class field, or resource class bean property.
@QueryParam("showItems") | Bind the value showItems of a HTTP query parameter to a resource method parameter, resource class field, or resource class bean property.

### UI Extensions

This part describes how to create a sample UI extension.

#### Overview

In WCM 2.2.0, it is possible to extend the Content Explorer and the ECM Administration with the UI Extension Framework. Indeed, you can add your own action buttons to the Content Explorer and/or add your own managers to the ECM Administration.

#### How to add your own tab in ECM Administration

##### Add your own UIAction

To add your own UIAction, do as follows:

1. Create a pom.xml file with the following content:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

      <modelVersion>4.0.0</modelVersion>

      <parent>

        <groupId>org.exoplatform.ecms</groupId>

        <artifactId>exo-ecms-examples-uiextension-framework</artifactId>

        <version>2.2.0-SNAPSHOT</version>

      </parent>

      <artifactId>exo-ecms-examples-uiextension-framework-manage-wcm-cache</artifactId>

      <name>eXo WCM Cache Examples </name>

      <description>eXo WCM Cache Examples </description>

      <dependencies>

        <dependency>

          <groupId>org.exoplatform.kernel</groupId>

          <artifactId>exo.kernel.container</artifactId>

          <version>2.3.0-GA</version>

          <scope>compile</scope>

        </dependency>

        <dependency>

          <groupId>org.exoplatform.commons</groupId>

          <artifactId>exo.platform.commons.webui.ext</artifactId>

          <version>1.1.1-GA</version>

          <scope>provided</scope>

        </dependency>

        <dependency>

          <groupId>org.exoplatform.ecms</groupId>

          <artifactId>exo-ecms-core-webui</artifactId>

          <version>2.3.0-GA</version>

          <scope>provided</scope>

        </dependency>

        <dependency>

          <groupId>org.exoplatform.ecms</groupId>

          <artifactId>exo-ecms-core-webui-administration</artifactId>

          <version>2.3.0-GA</version>

          <scope>provided</scope>

        </dependency>

      </dependencies>

      <build>

        <resources>

          <resource>

            <directory>src/main/java</directory>

            <includes>

              <include>**/*.xml</include>

            </includes>

          </resource>

          <resource>

            <directory>src/main/resources</directory>

            <includes>

              <include>**/*.properties</include>

              <include>**/*.xml</include>

              <include>**/*.jar</include>

              <include>**/*.pom</include>

              <include>**/*.conf</include>

              <include>**/*.gtmpl</include>

              <include>**/*.gif</include>

              <include>**/*.jpg</include>

              <include>**/*.png</include>

            </includes>

          </resource>

        </resources>

      </build>

    </project>

2. Create the src/main/java directory and start launching mvn eclipse:eclipse. Then, you can launch your eclipse and import this new project.

3. Create a new class called org.exoplatform.wcm.component.cache.UIWCMCacheComponent that extends org.exoplatform.ecm.webui.component.admin.manager.UIAbstractManagerComponent.

##### Add your own ActionListener

With the Webui framework, you will be notified if any given action is triggered. You just need to call your own action listener ($ACTIONNAME) ActionListener. For example, to create your own action listener for CacheView, do as follows:

1. Call CacheViewActionListener.

2. Add a static inner class called CacheViewActionListener that extends org.exoplatform.ecm.webui.component.admin.listener.UIECMAdminControlPanelActionListener .

You will see the expected code below:

    public class CacheViewComponent extends UIAbstractManagerComponent {

      public static class CacheViewActionListener extends UIECMAdminControlPanelActionListener<UIWCMCacheComponent> {

        public void processEvent(Event<UIWCMCacheComponent> event) throws Exception {

        UIECMAdminPortlet portlet = event.getSource().getAncestorOfType(UIECMAdminPortlet.class);

           UIECMAdminWorkingArea uiWorkingArea = portlet.getChild(UIECMAdminWorkingArea.class);

           uiWorkingArea.setChild(UIWCMCachePanel.class) ;

           event.getRequestContext().addUIComponentToUpdateByAjax(uiWorkingArea);

        }

      }

    }

3. Create the src/main/java directory and launch mvn eclipse:eclipse. You can then launch your eclipse and import this new project.

4. Create a new configuration file called conf/portal/configuration.xml to register your action (see 6.2.2.3) with the org.exoplatform.webui.ext.UIExtensionManager service.

##### Register your UI Action

To register your UI Action, do as follows:

1. Create the code:

    <configuration xmlns="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.exoplaform.org/xml/ns/kernel_1_1.xsd http://www.exoplaform.org/xml/ns/kernel_1_1.xsd">

      <external-component-plugins>

        <target-component>org.exoplatform.webui.ext.UIExtensionManager</target-component>

        <component-plugin>

          <name>Add.Actions</name>

          <set-method>registerUIExtensionPlugin</set-method>

          <type>org.exoplatform.webui.ext.UIExtensionPlugin</type>

          <init-params>

            <object-param>

              <name>CacheView</name>

              <object type="org.exoplatform.webui.ext.UIExtension">

                <field name="type">

                  <string>org.exoplatform.ecm.dms.UIECMAdminControlPanel</string>

                </field>

                <field name="name">

                  <string>CacheView</string>

                </field>

                <field name="category">

                  <string>GlobalAdministration</string>

                </field>

                <field name="component">

                  <string>org.exoplatform.wcm.component.cache.UIWCMCacheComponent</string>

                </field>

              </object>

            </object-param>

            <object-param>

              <name>UIWCMCacheManager</name>

              <object type="org.exoplatform.webui.ext.UIExtension">

                <field name="type">

                  <string>org.exoplatform.ecm.dms.UIECMAdminControlPanel</string>

                </field>

                <field name="name">

                  <string>UIWCMCacheManager</string>

                </field>

                <field name="category">

                  <string>GlobalAdministration</string>

                </field>

                <field name="component">

                  <string>org.exoplatform.wcm.manager.cache.UIWCMCacheManagerComponent</string>

                </field>

                <field name="extendedFilters">

                   <collection type="java.util.ArrayList">

                      <value>

                        <object type="org.exoplatform.webui.ext.filter.impl.UserACLFilter">

                           <field name="permissions">

                              <collection item-type="java.lang.String" type="java.util.ArrayList">

                                 <value>

                                    <string>*:/platform/administrators</string>

                                  </value>

                              </collection>

                           </field>

                        </object>

                      </value>

                   </collection>

                </field>

              </object>

            </object-param>

          </init-params>

        </component-plugin>

      </external-component-plugins>

    </configuration>

### Note

With this configuration, only the users with the *:/platform/administrators membership have the right to access the CacheView item.

2. Launch mvn clean install.

3. Copy the resource bundle.

### Note

All resources can be located in the src/main/resource package because the resources (*.xml, images, conf file) and the code are separated. This is very useful in a hierarchical structure.

Create ExamplePortlet_en.xml with the following content and add it to the src/main/resource package:

    <bundle>

      <!-- ################################################################################ # org.exoplatform.wcm.component.cache.UIWCMCacheForm

        # ################################################################################ -->

      <UIWCMCacheForm>

        <action>

          <Cancel>Cancel</Cancel>

          <Save>Save</Save>

          <Clear>Clear the cache</Clear>

        </action>

        <label>

          <maxsize>Max size :</maxsize>

          <livetime>Live time in sec :</livetime>

          <isCacheEnable>Cache enabled(should always be on production enviroment)</isCacheEnable>

          <hit>Hit count :</hit>

          <currentSize>Current size</currentSize>

          <miss>Miss count :</miss>

        </label>

      </UIWCMCacheForm>

      <!-- ################################################################################ # org.exoplatform.wcm.manager.cache.UIWCMCacheManagerForm

        # ################################################################################ -->

      <UIWCMCacheManagerForm>

        <action>

          <Cancel>Cancel</Cancel>

          <Save>Save</Save>

          <Clear>Clear the cache</Clear>

        </action>

        <label>

          <cacheModify>Cache to modify :</cacheModify>

          <maxsize>Max size :</maxsize>

          <livetime>Live time in sec :</livetime>

          <isCacheEnable>Cache enabled(should always be on production enviroment)</isCacheEnable>

          <hit>Hit count :</hit>

          <currentSize>Current size</currentSize>

          <miss>Miss count :</miss>

        </label>

      </UIWCMCacheManagerForm>

      <UIECMAdminControlPanel>

        <tab>

          <label>

            <GlobalAdministration>Global Administration</GlobalAdministration>

          </label>

        </tab>

        <label>

          <UIWCMCache>WCM Cache</UIWCMCache>

          <UIWCMCachePanel>WCM Cache Administration</UIWCMCachePanel>

          <UIWCMCacheManager>Managing Caches</UIWCMCacheManager>

          <UIWCMCacheManagerPanel>WCM Cache Management</UIWCMCacheManagerPanel>

        </label>

      </UIECMAdminControlPanel>

    </bundle>

You must add the following content to configuration.xml- to register the resource bundle.

### Note

By being added this configuration, the resource bundle has been completely separated from the original system. This is clearly useful for you to get an independent plugin.

    <external-component-plugins>

      <!-- The full qualified name of the ResourceBundleService -->

      <target-component>org.exoplatform.services.resources.ResourceBundleService</target-component>

      <component-plugin>

        <!-- The name of the plugin -->

        <name>ResourceBundle Plugin</name>

        <!-- The name of the method to call on the ResourceBundleService in order to register the ResourceBundles -->

        <set-method>addResourceBundle</set-method>

        <!-- The full qualified name of the BaseResourceBundlePlugin -->

        <type>org.exoplatform.services.resources.impl.BaseResourceBundlePlugin</type>

        <init-params>

          <values-param>

            <name>init.resources</name>

            <description>Store the following resources into the db for the first launch </description>

            <value>locale.portlet.cache.ExamplePortlet</value>

          </values-param>

          <values-param>

            <name>portal.resource.names</name>

            <description>The properties files of the portal , those file will be merged

              into one ResoruceBundle properties </description>

            <value>locale.portlet.cache.ExamplePortlet</value>

          </values-param>

        </init-params>

      </component-plugin>

    </external-component-plugins>

##### Run your own UI extension sample

Do as follows:

1. Run Tomcat.

2. Sign in as root.

3. Go to the ECM Administration.

You will see that a new extension has been already added to ECM Administrator:

### Authoring Extension

Publication add-ons for WCM 2.2.0

#### Extended Publication Plugin

##### States

This extended publication has new states and new profiles that are enabled in WCM 2.2.0.

- Profiles

  - Author: This profile can edit a content and mark this content as redacted.

  - Approver: This profile approves a pending content (marked by the Author).

  - Publisher: This profile publishes contents or marks them as "Ready for publication" in multi-server mode.

  - Archiver: An administrative profile which moves contents to an archive storage.

- States

  - enrolled: It is a pure technical state, generally used for content creation.

  - draft (Author): Content is in editing phase.

  - pending (Author): The author validates the content.

  - approved (Approver): A content is approved by the manager.

  - inreview (Manager): This state can be used when a second approval state is needed (for i18 translation for example).

  - staged (Publisher): A content is ready for publication (multi-server mode).

  - published (Publisher or Automatic): A content is published and visible in the Live mode.

  - unpublished (Publisher or Automatic): A content is not visible in the Live mode.

  - obsolete: A content can still be published but it is not in an editing lifecycle anymore.

  - archived (Automatic): A content is archived and ready to be moved in the archive workspace if enabled.

##### Start/End publication dates

In most cases, you do not want to publish a content directly, but at a defined date and you can also want to unpublish automatically the content after that. New properties are added to the new publication plugin, that allows you to manage this:

- publication:startPublishedDate

- publication:endPublishedDate

The WCM 2.2.0 rendering engine does not know anything about publication dates, so another service needs to manage that. When the publisher sets start/end publication dates, he can "stage" the content. The content will go automatically to "published" state when the start date arrives and to "unpublished" state after end date. A cron job checks every hour (or less) all contents which need to be published (start date in the past + "staged" state) or unpublished (end date in the past + "published" state).

Thus, the publication dates are not mandatory and a content can go to:

- Staged: in multi-server mode, the publisher can only put the content to the "staged" state and wait for auto-publication.

- Published: in single-server mode, the publisher can directly publish a content (with or without publication dates).

##### New Publication Mixin

    <nodeType hasOrderableChildNodes="false" isMixin="true" name="publication:authoringPublication" primaryItemName="">

      <supertypes>

        <supertype>publication:stateAndVersionBasedPublication</supertype>

      </supertypes>

      <propertyDefinitions>

        <propertyDefinition autoCreated="false" mandatory="true" multiple="false" name="publication:startPublishedDate" onParentVersion="IGNORE" protected="false" requiredType="Date">

          <valueConstraints/>

        </propertyDefinition>

        <propertyDefinition autoCreated="false" mandatory="true" multiple="false" name="publication:endPublishedDate" onParentVersion="IGNORE" protected="false" requiredType="Date">

          <valueConstraints/>

        </propertyDefinition>

      </propertyDefinitions>

    </nodeType>

###### Publication plugin UI

Note that some labels containing special or non-ASCII characters could not be well displayed in the publication UI. You can extend the width of the current UI State button by adding:

    .UIPublicationPanel .StatusTable .ActiveStatus {
      width: 75px !important;
    }

Also, for the publication date inputs, UIPublicationPanel should not initialize the dates to any default value. The publishing and unpublish CRON jobs will do this:

- A staged document with null publication start date is published instantly.

- A document with null publication end date is published forever.

See the export section for more information about the CRON jobs.

#### Publication Manager

The Publication Manager manages lifecycles and contexts in the WCM platform. It allows to manages different lifecycles based on different publication plugin in the platform.

    public interface PublicationManager {

        public List<Lifecycle> getLifecycles();

        public List<Context> getContexts();

        public Context getContext(String name);

        public Lifecycle getLifecycle(String name);

        public List<Lifecycle> getLifecyclesFromUser(String remoteUser, String state);

    }

In which:

- getLifecycles: returns a list of lifecycles (see below), with lifecycle name, publication plugin involved and possible states.

- getContexts: returns a list of context, with name, related Lifecycle and other properties (see below).

- getContext: returns a context by its name.

- getLifecycle: returns a lifecycle by its name.

- getLifecycleFromUser: returns a list of lifecycles in which the user has rights (based on membership property).

##### Lifecycle

A lifecycle is defined by a simple vertical workflow with steps (states) and profiles (membership). Each lifecycle is related to a Publication plugin (compliant with the JBPM or Bonita business processes).

For example: Two lifecycles with/without states

    <external-component-plugins>

      <target-component>org.exoplatform.services.wcm.publication.PublicationManager</target-component>

      <component-plugin>

        <name>AddLifecycle</name>

        <set-method>addLifecycle</set-method>

        <type>org.exoplatform.services.wcm.publication.lifecycles.StatesLifecyclePlugin</type>

        <init-params>

          <object-param>

            <name>lifecyles</name>

            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig">

              <field name="lifecycles">

                <collection type="java.util.ArrayList">

                  <value>

                    <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$Lifecycle">

                      <field name="name">

                        <string>lifecycle1</string>

                      </field>

                      <field name="publicationPlugin">

                        <string>States and versions based publication</string>

                      </field>

                    </object>

                  </value>

                  <value>

                    <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$Lifecycle">

                      <field name="name">

                        <string>lifecycle2</string>

                      </field>

                      <field name="publicationPlugin">

                        <string>Authoring publication</string>

                      </field>

                      <field name="states">

                        <collection type="java.util.ArrayList">

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>draft</string>

                              </field>

                              <field name="memberships">

                                <collection type="java.util.ArrayList">

                                  <value>

                                    <string>author:/CA/communicationDG</string>

                                  </value>

                                  <value>

                                    <string>author:/CA/alerteSanitaire</string>

                                  </value>

                                  <value>

                                    <string>author:/CA/alerteInformatique</string>

                                  </value>

                                  <value>

                                    <string>author:/CA/informations</string>

                                  </value>

                                </collection>

                              </field>

                            </object>

                          </value>

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>pending</string>

                              </field>

                              <field name="membership">

                                <string>author:/platform/web-contributors</string>

                              </field>

                            </object>

                          </value>

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>approved</string>

                              </field>

                              <field name="membership">

                                <string>manager:/platform/web-contributors</string>

                              </field>

                            </object>

                          </value>

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>staged</string>

                              </field>

                              <field name="membership">

                                <string>publisher:/platform/web-contributors</string>

                              </field>

                            </object>

                          </value>

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>published</string>

                              </field>

                              <field name="membership">

                                <string>automatic</string>

                              </field>

                            </object>

                          </value>

                        </collection>

                      </field>

                    </object>

                  </value>

                  <value>

                    <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$Lifecycle">

                      <field name="name">

                        <string>lifecycle3</string>

                      </field>

                      <field name="publicationPlugin">

                        <string>Authoring publication</string>

                      </field>

                      <field name="states">

                        <collection type="java.util.ArrayList">

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>draft</string>

                              </field>

                              <field name="membership">

                                <string>author:/platform/web-contributors</string>

                              </field>

                            </object>

                          </value>

                          <value>

                            <object type="org.exoplatform.services.wcm.publication.lifecycles.impl.LifecyclesConfig$State">

                              <field name="state">

                                <string>published</string>

                              </field>

                              <field name="memberships">

                                <collection type="java.util.ArrayList">

                                  <value>

                                    <string>publisher:/CA/communicationDG</string>

                                  </value>

                                  <value>

                                    <string>publisher:/CA/alerteSanitaire</string>

                                  </value>

                                  <value>

                                    <string>publisher:/CA/alerteInformatique</string>

                                  </value>

                                  <value>

                                    <string>publisher:/CA/informations</string>

                                  </value>

                                </collection>

                              </field>

                            </object>

                          </value>

                        </collection>

                      </field>

                    </object>

                  </value>

                </collection>

              </field>

            </object>

          </object-param>

        </init-params>

      </component-plugin>

    </external-component-plugins>

In the last example, there are three lifecycles:

- Lifecycle 1: based on States and versions based publication.

  - This allows to be backward compliant with older WCM releases. If all your site contents are using an existing plugin, you can create a lifecycle for it and it will work.

  - For new instances, you should use the new plugin with dynamic states capabilities.

- Lifecycle 2: based on new Authoring publication.

  - Visibility: Define only the "visible" steps. In this example, there is no step for 'enrolled'. Even if this step exists, it will not be displayed in the UI.

  - Automatic: Set a step as "automatic". In this mode, the step will be visible in the UI but it will be managed by the system (a cron job for example).

- Lifecycle 3: Simulates the States and versions based publication plugin. Note that this simple lifecycle will work in a single server configuration.

###### Listen to a lifecycle

When a state is changed, you can broadcast an event to add features. The event could look like this:

    listenerService.broadcast(AuthoringPlugin.POST_UPDATE_STATE_EVENT, null, node);

Listener declaration could look like this:

    <external-component-plugins>

      <target-component>org.exoplatform.services.listener.ListenerService</target-component>

      <component-plugin>

        <name>PublicationService.event.postUpdateState</name>

        <set-method>addListener</set-method>

        <type>org.exoplatform.services.wcm.publication.listener.post.PostUpdateStateEventListener</type>

        <description>this listener will be called every time a content changes its current state</description>

      </component-plugin>

    </external-component-plugins>

##### Context

A context is defined by simple rules. In WCM 2.2.0, you can select to enroll the content in a specific lifecycle (for example, publication plugin) based on context parameters. There are three parameters used to define contexts:

- Remote User: The current user who can create/edit the content.

- Current sitename: The Site from where the content is created (not the storage but the navigation).

- Node: The node which you want to enroll.

From these parameters, you can easily connect and define contexts based on:

- Membership: Does the current user have this membership?

- Site: On this particular site, you want to enroll contents in a specific lifecycle.

- Path: You can enroll contents in the lifecycles based on their path (from the Node).

- Type of content: You can enroll contents in the lifecycles based on their nodetype (from the Node).

Because each site has a content storage (categories + physical storage), you can select the right lifecycle for the right storage/site. To avoid conflicts on contexts, you can set a priority (The less is the best).

For example, Different Contexts

    <external-component-plugins>

      <target-component>org.exoplatform.services.wcm.publication.PublicationManager</target-component>

      <component-plugin>

        <name>AddContext</name>

        <set-method>addContext</set-method>

        <type>org.exoplatform.services.wcm.publication.context.ContextPlugin</type>

        <init-params>

          <object-param>

            <name>contexts</name>

            <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig">

              <field name="contexts">

                <collection type="java.util.ArrayList">

                  <value>

                    <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig$Context">

                      <field name="name">

                        <string>contextdefault</string>

                      </field>

                      <field name="priority">

                        <string>200</string>

                      </field>

                      <field name="lifecycle">

                        <string>lifecycle1</string>

                      </field>

                    </object>

                    <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig$Context">

                      <field name="name">

                        <string>context1</string>

                      </field>

                      <field name="priority">

                        <string>100</string>

                      </field>

                      <field name="lifecycle">

                        <string>lifecycle1</string>

                      </field>

                      <field name="membership">

                        <string>*:/platform/web-contributors</string>

                      </field>

                      <field name="site">

                        <string>acme</string>

                      </field>

                      <field name="path">

                        <string>repository:collaboration:/sites content/live/acme/categories</string>

                      </field>

                    </object>

                    <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig$Context">

                      <field name="name">

                        <string>context2</string>

                      </field>

                      <field name="priority">

                        <string>100</string>

                      </field>

                      <field name="lifecycle">

                        <string>lifecycle1</string>

                      </field>

                      <field name="site">

                        <string>classic</string>

                      </field>

                    </object>

                    <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig$Context">

                      <field name="name">

                        <string>context3</string>

                      </field>

                      <field name="priority">

                        <string>80</string>

                      </field>

                      <field name="lifecycle">

                        <string>lifecycle3</string>

                      </field>

                      <field name="membership">

                        <string>manager:/company/finances</string>

                      </field>

                      <field name="path">

                        <string>repository:collaboration:/documents/company/finances</string>

                      </field>

                    </object>

                    <object type="org.exoplatform.services.wcm.publication.context.impl.ContextConfig$Context">

                      <field name="name">

                        <string>context4</string>

                      </field>

                      <field name="priority">

                        <string>50</string>

                      </field>

                      <field name="lifecycle">

                        <string>lifecycle4</string>

                      </field>

                      <field name="memberships">

                        <collection type="java.util.ArrayList">

                          <value>

                            <string>manager:/CA/communicationDG</string>

                          </value>

                          <value>

                            <string>manager:/CA/alerteSanitaire</string>

                          </value>

                          <value>

                            <string>manager:/CA/alerteInformatique</string>

                          </value>

                          <value>

                            <string>manager:/CA/informations</string>

                          </value>

                        </collection>

                      </field>

                      <field name="path">

                        <string>repository:collaboration:/documents/company/finances</string>

                      </field>

                      <field name="nodetype">

                        <string>exo:article</string>

                      </field>

                    </object>

                  </value>

                </collection>

              </field>

            </object>

          </object-param>

        </init-params>

      </component-plugin>

    </external-component-plugins>

The logic is very simple. When creating a content, it should be attached a lifecycle with the lifecyle priority:

- context4 is the most important (priority=50): you will enroll the content in the lifecycle 'lifecycle4' if:

  - The content creator has the 'manager:/company/finances' membership.

  - The content is stored in 'repository:collaboration:/documents/company/finances' or any subfolders.

  - The content is a 'exo:article'.

- If not, you will continue with context3.

The logic is very simple. When you create a content, go lifecycle by lifecycle starting with the better priority:

- context4 is the most important (priority=50): you will enroll the content in the lifecycle 'lifecycle4' if:

  - the content creator has the 'manager:/company/finances' membership.

  - the content is stored in 'repository:collaboration:/documents/company/finances' or any subfolders.

  - the content is a 'exo:article'.

- if not, you will continue with context3.

### Note

The contexts will be used only when the content is created and when you want to enroll it in a lifecycle for the first time. Once you have the corresponding lifecycle, you will set the lifecycle inside the content (see New authoring Mixin) and the context service will not be called again for this content.

##### New Authoring Mixin

    <nodeType hasOrderableChildNodes="false" isMixin="true" name="publication:authoring" primaryItemName="">

      <propertyDefinitions>

        <propertyDefinition autoCreated="false" mandatory="false" multiple="false" name="publication:lastUser" onParentVersion="IGNORE" protected="false" requiredType="String">

          <valueConstraints/>

        </propertyDefinition>

        <propertyDefinition autoCreated="false" mandatory="false" multiple="false" name="publication:lifecycle" onParentVersion="IGNORE" protected="false" requiredType="String">

          <valueConstraints/>

        </propertyDefinition>

      </propertyDefinitions>

    </nodeType>

When adding the content in a lifecycle, set the publication:lifecycle property with the corresponding lifecycle.

### Note

A content can be in one lifecycle only.

Each time you change from one state to another, set the user who changed the state in publication:lastUser.

###### Querying based on publication status

By adding this mixin to contents, you can access contents by simple queries based on the current user profile. For example:

- All your draft contents:

  - query: select * from nt:base where publication:currentState='draft' and publication:lastUser='benjamin';

- All the contents you have to approve.

  - call: PublicationManager.getLifecycles('benjamin', 'approved') => returns lifecycles where you can go to the 'approved' state.

  - query: select * from nt:base where publication:currentState='pending' and (publication:lifecycle='lifecycle1' or publication:lifecycle='lifecycle3');

- All the content that will be published tomorrow.

  - query: select * from nt:base where publication:currentState='staged' and publication:startPublishedDate>'xxxx';

## Public REST APIs

### ThumbnailRESTService

Service name | Service URL | Location | Description
--- | --- | --- | ---
ThumbnailRESTService | {portalname}/{restcontextname}/thumbnailImage/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-services | Return a responding data as a thumbsnail image.

### Note

- {portalname}: The name of the portal.

- {restcontextname}: The context name of rest webapplication which is deployed to the "{portalname}" portal.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getThumbnailImage | {portalname}/{restcontextname}/thumbnailImage/medium/{repoName}/{workspaceName}/{nodePath}/ | repoName workspaceName nodePath | String String String | Return an image with the medium size (64x64).
getLargeImage | {portalname}/{restcontextname}/thumbnailImage/large/{repoName}/{workspaceName}/{nodePath}/ | repoName workspaceName nodePath | String String String | Return an image with the large size (300x300).
getSmallImage | {portalname}/{restcontextname}/thumbnailImage/small/{repoName}/{workspaceName}/{nodePath}/ | repoName workspaceName nodePath | String String String | Return an image with the small size (32x32).
getCustomImage | {portalname}/{restcontextname}/thumbnailImage/custom/{size}/{repoName}/{workspaceName}/{nodePath}/ | size repoName workspaceName nodePath | String String String String | Return an image with the custom size.
getOriginImage | {portalname}/{restcontextname}/thumbnailImage/origin/{repoName}/{workspaceName}/{nodePath}/ | repoName workspaceName nodePath | String String String | Return an image with the original size.

### RssConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
RssConnector | {portalname}/{restcontextname}/feed/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Generate an RSS feed.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
generate | {portalname}/{restcontextname}/feed/rss/ | repository workspace server siteName title desc folderPath orderBy orderType lang detailPage detailParam recursive | String String String String String String String String String String String String String | Generate an RSS feed.

### FCKCoreRESTConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
FCKCoreRESTConnector | {portalname}/{restcontextname}//fckconnector/jcr/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Get a list of files and folders, and create a folder and uploads files.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getFoldersAndFiles | {portalname}/{restcontextname}/fckconnector/jcr/getFoldersAndFiles/{repositoryName}/{workspaceName}/{currentFolder}/{command}/{type}/ | repositoryName workspaceName currentFolder command type | String String String String String | Return the folders and the files in the current folder.
createFolder | {portalname}/{restcontextname}/fckconnector/jcr/createFolder/{repositoryName}/{workspaceName}/{currentFolder}/{newFolderName}/{language}/ | repositoryName workspaceName currentFolder newFolderName language | String String String String String | Create a folder under the current folder.
uploadFile | {portalname}/{restcontextname}/fckconnector/jcr/uploadFile/upload/ | servletRequest | HttpServletRequest | Uploads a file with the HttpServletRequest.
processUpload | {portalname}/{restcontextname}/fckconnector/jcr/uploadFile/control/{repositoryName}/{workspaceName}/{currentFolder}/{action}/{language}/{fileName}/{uploadId}/ | repositoryName workspaceName currentFolder action language fileName uploadId | String String String String String String String | Control the process of uploading a file, such as aborting, deleting or progressing the file.

### ResourceBundleConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
ResourceBundleConnector | {portalname}/{restcontextname}/bundle/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Get the bundle basing on the key and the locale.

exo-ecms-core-connector

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getBundle | {portalname}/{restcontextname}/bundle/getBundle/{key}/{locale}/ | key locale | String String | Get the bundle basing on the key and the locale.

### VoteConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
VoteConnector | {portalname}/{restcontextname}/contents/vote/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Return and set a vote value of a given node in the sent parameter.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
postVote | {portalname}/{restcontextname}/contents/vote/postVote/{repositoryName}/{workspaceName}/{jcrPath}/{vote}/{lang}/ | repositoryName workspaceName jcrPath vote lang | String String String String String String | Set a vote value for a given content.
getVote | {portalname}/{restcontextname}/contents/vote/getVote/{repositoryName}/{workspaceName}/{jcrPath}/ | repositoryName workspaceName jcrPath | String String String | Return a vote value for a given content.

### DriverConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
DriverConnector | {portalname}/{restcontextname}/wcmDriver/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Return a drive list, a folder list and a document list in a specified location for a given user. Also, it processes the file uploading action.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getDrivers | {portalname}/{restcontextname}/wcmDriver/getDrivers/ | lang | String | Return a list of drives for the current user.
getFoldersAndFiles | {portalname}/{restcontextname}/wcmDriver/getFoldersAndFiles/ | driverName currentFolder currentPortal repositoryName workspaceName filterBy | String String String String String String | Return all folders and files in a given location.
uploadFile | {portalname}/{restcontextname}/wcmDriver/uploadFile/upload/ | uploadId | String | Uploads a file.
processUpload | {portalname}/{restcontextname}/wcmDriver/uploadFile/control/ | repositoryName workspaceName driverName currentFolder currentPortal userId jcrPath action language fileName uploadId | String String String String String String String String String String String | Control the process of uploading a file, such as aborting, deleting or processing the file.

### GadgetConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
GadgetConnector | {portalname}/{restcontextname}/wcmGadget/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Instantiate a new gadget connector.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getFoldersAndFiles | {portalname}/{restcontextname}/wcmGadget/getFoldersAndFiles/{currentFolder}/{lang}/{host}/ | currentFolder lang host | String String String | Get the folders and files.

### PortalLinkConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
PortalLinkConnector | {portalname}/{restcontextname}/portalLinks/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-connector | Return a page URI for a given location.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getPageURI | {portalname}/{restcontextname}/portalLinks/getFoldersAndFiles/ | currentFolder | String String String | Get the page URI.

### GetEditedDocumentRESTService

Service name | Service URL | Location | Description
--- | --- | --- | ---
GetEditedDocumentRESTService | {portalname}/{restcontextname}/presentation/document/edit/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-publication | Return the latest edited documents.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getLastEditedDoc | {portalname}/{restcontextname}/presentation/document/edit/{repository}/ | repository | String | Return the latest edited documents.

### PublicationGetDocumentRESTService

Service name | Service URL | Location | Description
--- | --- | --- | ---
PublicationGetDocumentRESTService | {portalname}/{restcontextname}/publication/presentation/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-publication | Return a list of published documents.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getPublishDocument | {portalname}/{restcontextname}/publication/presentation/{repository}/{workspace}/{state}/ | repository workspace state showItems | String String String String | Return a list of published document by the default plugin.
getPublishedListDocument | {portalname}/{restcontextname}/publication/presentation/{repository}/{workspace}/{publicationPluginName}/{state}/ | repository workspace publicationPluginName state showItems | String String String String String String | Return a list of published documents by a specific plugin.

### FavoriteRESTService

Service name | Service URL | Location | Description
--- | --- | --- | ---
FavoriteRESTService | {portalname}/{restcontextname}/favorite/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-services | Return a list of favourite documents of a given user.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
getFavoriteByUser | {portalname}/{restcontextname}/favorite/all/{repoName}/{workspaceName}/{userName} | repoName workspaceName userName showItems | String String String String | Return a list of favourite documents of a given user.

### RESTImagesRendererService

Service name | Service URL | Location | Description
--- | --- | --- | ---
RESTImagesRendererService | {portalname}/{restcontextname}/images/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-core-services | Get the image binary data of a given image node.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
serveImage | {portalname}/{restcontextname}/images/{repositoryName}/{workspaceName}/{nodeIdentifier}/ | repositoryName workspaceName nodeIdentifier param | String String String String | Get the image binary data of a given image node.

### LifecycleConnector

Service name | Service URL | Location | Description
--- | --- | --- | ---
LifecycleConnector | {portalname}/{restcontextname}/authoring/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-ext-authoring-services | Return a list of contents in a given state range of the publication lifecycle.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
byState | {portalname}/{restcontextname}/authoring/bystate/ | fromstate user lang workspace json | String String String String String | Return a list of contents from the given state to the last state.
toState | {portalname}/{restcontextname}/authoring/toState/ | fromstate tostate user lang workspace json | String String String String String String | Return a list of contents from the begining state to the last state.
byDate | {portalname}/{restcontextname}/authoring/byDate/ | fromstate date lang workspace json | String String String String String String | Return a list of contents from the given begining state and published before the given date.

### CopyContentFile

Service name | Service URL | Location | Description
--- | --- | --- | ---
CopyContentFile | {portalname}/{restcontextname}/copyfile/ | Maven groupId: org.exoplatform.ecms ArtifactId: exo-ecms-ext-authoring-services | Copy a file.

- APIs usage:

Name | Service URL endpoint | Parameters | Expected Values | Description
--- | --- | --- | --- | ---
copyFile | {portalname}/{restcontextname}/copyfile/copy/ | param - the file information | String | Copy a file.

### PDFViewerRESTService

## Public Java APIs

### TaxonomyService

Taxonomy service is used to work with taxonomies. In this service, there are many functions which enable you to add, find, or delete taxonomies from a node.

Method | Return | Prototype | Description
--- | --- | --- | ---
getTaxonomyTree | `Node` | `getTaxonomyTree(String repository, String taxonomyName, boolean system) throws RepositoryException;` | Return the root node of the given taxonomy tree. @param repository: The name of repository. @param taxonomyName: The name of the taxonomy. @param system: Indicates whether the nodes must be retrieved using a session system or user session. @throws RepositoryException: if the taxonomy tree could not be found.
getTaxonomyTree | `Node` | `getTaxonomyTree(String repository, String taxonomyName) throws RepositoryException;` | Return the root node of the given taxonomy tree with the user session. @param repository: The name of repository. @param taxonomyName: The name of the taxonomy. @throws RepositoryException: if the taxonomy tree could not be found.
getAllTaxonomyTrees | `List<Node>` | `getAllTaxonomyTrees(String repository, boolean system) throws RepositoryException;` | Return the list of all the root nodes of the taxonomy tree available. @param repository: The name of repository. @param system: Indicates whether the nodes must be retrieved using a session system or user session. @throws RepositoryException: if the taxonomy trees could not be found .
getAllTaxonomyTrees | `List<Node>` | `getAllTaxonomyTrees(String repository) throws RepositoryException;` | Return the list of all the root nodes of the taxonomy tree available with the user session. @param repository: The name of repository. @throws RepositoryException: if the taxonomies could not be found.
hasTaxonomyTree | `boolean` | `hasTaxonomyTree(String repository, String taxonomyName) throws RepositoryException;` | Check if a taxonomy tree with the given name has already been defined. @param repository: The name of repository. @param taxonomyName: The name of the taxonomy. @throws RepositoryException: if the taxonomy name could not be checked.
addTaxonomyTree | `void` | `addTaxonomyTree(Node taxonomyTree) throws RepositoryException, TaxonomyAlreadyExistsException;` | Define a node as a new taxonomy tree. @param taxonomyTree: The taxonomy tree to define. @throws TaxonomyAlreadyExistsException: if a taxonomy with the same name has already been defined. @throws RepositoryException: if the taxonomy tree could not be defined.
updateTaxonomyTree | `void` | `updateTaxonomyTree(String taxonomyName, Node taxonomyTree) throws RepositoryException;` | Re-define a node as a taxonomy tree. @param taxonomyName: The name of the taxonomy to update. @param taxonomyTree: The taxonomy tree to define. @throws RepositoryException: if the taxonomy tree could not be updated.
removeTaxonomyTree | `void` | `removeTaxonomyTree(String taxonomyName) throws RepositoryException;` | Remove the taxonomy tree definition. @param taxonomyName: The name of the taxonomy to remove. @throws RepositoryException: if the taxonomy tree could not be removed.
addTaxonomyNode | `void` | `addTaxonomyNode(String repository, String workspace, String parentPath, String taxoNodeName, String creator) throws RepositoryException, TaxonomyNodeAlreadyExistsException;` | Add a new taxonomy node at the given location. @param repository: The name of the repository. @param workspace: The name of the workspace @param parentPath: The place where the taxonomy node will be added. @param taxoNodeName: The name of taxonomy node. @param creator: The name of the user creating this node. @throws TaxonomyNodeAlreadyExistsException: if a taxonomy node with the same name has already been added. @throws RepositoryException: if the taxonomy node could not be added.
removeTaxonomyNode | `void` | `removeTaxonomyNode(String repository, String workspace, String absPath) throws RepositoryException;` | Remove the taxonomy node located at the given absolute path. @param repository: The name of the repository @param workspace: The name of the workspace. @param absPath: The absolute path of the taxonomy node to remove. @throws RepositoryException: if the taxonomy node could not be removed.
moveTaxonomyNode | `void` | `moveTaxonomyNode(String repository, String workspace, String srcPath, String destPath, String type) throws RepositoryException;` | Copy or cut the taxonomy node from source path to destination path. The parameter type indicates if the node must be cut or copied. @param repository: The name of the repository. @param workspace: The name of the workspace. @param srcPath: The source path of this taxonomy. @param destPath: The destination path of the taxonomy. @param type: If type is equal to cut, the process will be cut. If type is equal to copy, the process will be copied. @throws RepositoryException: if the taxonomy node could not be moved.
hasCategories | `boolean` | `hasCategories(Node node, String taxonomyName) throws RepositoryException;` | Return true if the given node has categories in the given taxonomy. @param node: The node to check. @param taxonomyName: The name of the taxonomy. @throws RepositoryException: if categories cannot be checked.
hasCategories | `boolean` | `hasCategories(Node node, String taxonomyName, boolean system) throws RepositoryException;` | Return true if the given node has categories in the given taxonomy. @param node: The node to check. @param taxonomyName: The name of the taxonomy. @param system: check system provider or not. @throws RepositoryException: if categories cannot be checked.
getCategories | `List<Node>` | `getCategories(Node node, String taxonomyName) throws RepositoryException;` | Return all the paths of the categories (relative to the root node of the given taxonomy) which have been associated to the given node for the given taxonomy. @param node: The node for which we seek the categories. @param taxonomyName: The name of the taxonomy. @throws RepositoryException: if the categories cannot be retrieved.
getCategories | `List<Node>` | `getCategories(Node node, String taxonomyName, boolean system) throws RepositoryException;` | Return all the paths of the categories(relative to the root node of the given taxonomy) which have been associated to the given node for the given taxonomy. @param node: The node for which we seek the categories. @param taxonomyName: The name of the taxonomy. @param system. @throws RepositoryException: if the categories cannot be retrieved.
getAllCategories | `List<Node>` | `getAllCategories(Node node) throws RepositoryException;` | Return all the paths of the categories which have been associated to the given node. @param node: The node for which we seek the categories @throws RepositoryException.
getAllCategories | `List<Node>` | `getAllCategories(Node node, boolean system) throws RepositoryException;` | Return all the paths of the categories which have been associated to the given node. @param node: The node for which we seek the categories @param system: check system provider or not . @throws RepositoryException.
removeCategory | `void` | `removeCategory(Node node, String taxonomyName, String categoryPath) throws RepositoryException;` | Remove a category to the given node. @param node: The node from which we remove the category. @param taxonomyName: The name of the taxonomy. @param categoryPath: The path of the category relative to the root node of the given taxonomy. @throws RepositoryException: if the category cannot be removed.
removeCategory | `void` | `removeCategory(Node node, String taxonomyName, String categoryPath, boolean system) throws RepositoryException;` | Remove a category to the given node. @param node: The node from which we remove the category. @param taxonomyName: The name of the taxonomy. @param categoryPath: The path of the category relative to the root node of the given taxonomy. @param system: check system provider or not. @throws RepositoryException: if the category cannot be removed.
addCategories | `void` | `addCategories(Node node, String taxonomyName, String[] categoryPaths) throws RepositoryException;` | Add several categories to the given node. @param node: The node to which we add the categories. @param taxonomyName: The name of the taxonomy. @param categoryPaths: An array of category paths relative to the given taxonomy. @throws RepositoryException: if the categories cannot be added.
addCategories | `void` | `addCategories(Node node, String taxonomyName, String[] categoryPaths, boolean system) throws RepositoryException;` | Add several categories to the given node. @param node: The node to which we add the categories. @param taxonomyName: The name of the taxonomy. @param categoryPaths: An array of category paths relative to the given taxonomy. @param system: check system provider or not. @throws RepositoryException: if the categories cannot be added.
addCategory | `void` | `addCategory(Node node, String taxonomyName, String categoryPath) throws RepositoryException;` | Add a new category path to the given node. @param node: the node to which we add the category. @param taxonomyName: The name of the taxonomy. @param categoryPath: The path of the category relative to the given taxonomy. @throws RepositoryException: if the category cannot be added.
addCategory | `void` | `addCategory(Node node, String taxonomyName, String categoryPath, boolean system) throws RepositoryException;` | Add a new category path to the given node. @param node: the node to which we add the category. @param taxonomyName: The name of the taxonomy. @param categoryPath: The path of the category relative to the given taxonomy. @param system: check system provider or not. @throws RepositoryException: if the category cannot be added.
getTaxonomyTreeDefaultUserPermission | `Map<String, String[]>` | `getTaxonomyTreeDefaultUserPermission();` | Get the default permission for the user in taxonomy tree.
addTaxonomyPlugin | `void` | `addTaxonomyPlugin(ComponentPlugin plugin);` | Add a new taxonomy plugin to the service. @param plugin: The plugin to adds
init | `void` | `init(String repository) throws Exception;` | Initialize all taxonomy plugins that have been already configured in .xml files. @param repository: The name of repository. @see TaxonomyPlugin. @throws Exception.
getCategoryNameLength | `String` | `getCategoryNameLength();` | Get the limited length of the category name.

### LinkManager

Supply API to work with the linked node or the link included in a node.

Package org.exoplatform.services.cms.link.LinkManager

Method | Return | Prototype | Description
--- | --- | --- | ---
createLink | `Node` | `createLink(Node parent, String linkType, Node target)` `throws RepositoryException;` | Creates a new link that is added to the parent node and returns the link. @param parent: The parent node of the link. @param linkType: The primary node type of the link must be a sub-type of exo:symlink, the default value is "exo:symlink" @param target The target of the link. @throws RepositoryException: if the link cannot be created for any reason.
createLink | `Node` | `createLink(Node parent, Node target)` `throws RepositoryException;` | Creates a new node of type exo:symlink, then adds it to the parent node and returns the link node. @param parent: The parent node of the link to create. @param target: The target of the link. @throws RepositoryException: if the link cannot be created for any reason.
createLink | `Node` | `createLink(Node parent, String linkType, Node target, String linkName)` `throws RepositoryException;` | Creates a new link that is added to the parent node and returns the link. @param parent: The parent node of the link. @param linkType: The primary node type of the link must be a sub-type of exo:symlink, the default value is exo:symlink. @param target: The target of the link. @param linkName: The name of the link. @return @throws RepositoryException: if the link cannot be created for any reason.
updateLink | `Node` | `updateLink(Node link, Node target)` `throws RepositoryException;` | Updates the target node of the given link. @param link: The link node to update. @param target: The new target of the link. @throws RepositoryException: if the link cannot be updated for any reason.
getTarget | `Node` | `getTarget(Node link, boolean system) throws ItemNotFoundException,` `RepositoryException;` | Gets the target node of the given link. @param link: The node of type exo:symlink. @param system: Indicates whether the target node must be retrieved using a session system or user session in case we cannot use the same session as the node link because the target and the link are not in the same workspace. @throws ItemNotFoundException: if the target node cannot be found. @throws RepositoryException: if an unexpected error occurs while retrieving the target node.
getTarget | `Node` | `getTarget(Node link)` `throws ItemNotFoundException, RepositoryException;` | Gets the target node of the given link using the user. @param link: The node of type exo:symlink. @throws ItemNotFoundException: if the target node cannot be found. @throws RepositoryException: if an unexpected error occurs while retrieving the target node.
isTargetReachable | `boolean` | `isTargetReachable(Node link)` `throws RepositoryException;` | Checks if the target node of the given link can be reached using the user session. @param link: The node of type exo:symlink. @throws RepositoryException: if an unexpected error occurs .
isTargetReachable | `boolean` | `isTargetReachable(Node link, boolean system)` `throws RepositoryException;` | Checks if the target node of the given link can be reached using the user session. @param link: The node of type exo:symlink. @param system @throws RepositoryException if an unexpected error occurs.
isLink | `boolean` | `isLink(Item item)` `throws RepositoryException;` | Indicates whether the given item is a link. @param item: the item to test. @return <code>true</code>: if the node is a link, <code>false</code> otherwise. @throws RepositoryException: if an unexpected error occurs.
getTargetPrimaryNodeType | `String` | `getTargetPrimaryNodeType(Node link)` `throws RepositoryException;` | Gives the primary node type of the target. @param link: The node of type exo:symlink. @return: the primary node type of the target @throws RepositoryException: if an unexpected error occurs.
getAllLinks | `List<Node>` | `getAllLinks(Node targetNode, String linkType, String repoName)` `{}throws Exception;` | Gives all links of the given node. @param targetNode: The target node to get links. @param linkType: The type of link to get. @param repoName: Name of the repository. @return: the list of link of the target node with given type. @throw Exception

### PublicationManager

PublicationService is to manage the publication.

Method | Return | Prototype | Description
--- | --- | --- | ---
addLifecycle | `void` | `addLifecycle(ComponentPlugin plugin);` | Add plugins context for the publication service.
getLifecycle | `Lifecycle` | `Lifecycle getLifecycle(String name) ;` | Get a specific lifecycle with the given name. @param name: The name of the wanted lifecycle.
getLifecycles | `List<Lifecycle>` | `List<Lifecycle> getLifecycles();` | Get all the lifecycles which were added to service instances.
getContext | `Context` | `Context getContext(String name) ;` | Get a specific context with the given names.
getContexts | `List<Context>` | `List<Context> getContexts();` | Get all the contexts which were added to service instances.
getContents | `List<Node>` | `List<Node> getContents(String fromstate, String tostate, String date, String user, String lang , String workspace) throws Exception;` | Get all the nodes. @param fromstate/tostate: the current range state of node. @param user: The last user of node. @param lang: the node's language. @param workspace: the Workspace of the node's location.
getLifecyclesFromUser | `List<Lyfecycle>` | `List<Lyfecycle> getLifecyclesFromUser(String remoteUser, String state);` | Get all the Lifecycle of a specific user. @param remoteUser: the current user of publication service. @param state: The current state of the node.

### WCMComposer

This class is used to get contents inside the WCM product. You should not access contents directly from the JCR on the front side.

In general, this service stands between publication and cache.

Package org.exoplatform.services.wcm.publication.WCMComposer

Method | Return | Prototype | Description
--- | --- | --- | ---
getContent | `Node` | `getContent(String repository, String workspace, String nodeIdentifier, HashMap<String, String> filters, SessionProvider sessionProvider)` `throws Exception ;` | Return contents at the specified path based on filters. @param repository: the repository @param workspace: the workspace @param path: the path @param filters: the filters @param sessionProvider: the session provider @return a JCR node @throws Exception: the exception
getContents | `List<Node>` | `getContents(String repository, String workspace, String path, HashMap<String, String> filters, SessionProvider sessionProvider)` `throws Exception ;` | Return contents at the specified path based on filters. @param repository: the repository @param workspace: the workspace @param path: the path @param filters: the filters @param sessionProvider: the session provider @return: a JCR node @throws Exception: the exception
updateContent | `boolean` | `updateContent(String repository, String workspace, String nodeIdentifier, HashMap<String, String> filters)` `throws Exception;` | Update content. @param repository: the repository @param workspace: the workspace @param path: the path @param filters: the filters @return true, if successful.
getAllowedStates | `List<String>` | `getAllowedStates(String mode)` `throws Exception ;` | Return allowed states for a specified mode. @param mode: the mode @return a JCR node. @throws Exception: the exception
cleanTemplates | `void` | `cleanTemplates()` `throws Exception ;` | Initialize the templates hashmap. @throws Exception: the exception
isCached | `boolean` | `isCached()` `throws Exception;` | Check isCache or not. @return: the state of caches @throws Exception: the exception
updateTemplatesSQLFilter | `String` | `updateTemplatesSQLFilter()` `throws Exception;` | Update all document nodetypes and write a query cause. @return: A part of the query allow search all document node and taxonomy link also. Return null if there is any exception. @throws Exception: the exception

### NewFolksonomy

Package org.exoplatform.services.cms.folksonomy.NewFolksonomyService;

Method | Return | Prototype | Description
--- | --- | --- | ---
addPrivateTag | `void` | `addPrivateTag(String[] tagsName, Node documentNode, String repository, String workspace, String userName) throws Exception ;` | Add a private tag to a document. A folksonomy link will be created in a tag node. @param tagNames: Array of tag name as the children of tree. @param documentNode: Tags this node by creating a folksonomy link to the node in the tag. @param repository: Repository name @param workspace: Workspace name @param userName: User name @throws Exception
addGroupsTag | `void` | `addGroupsTag(String[] tagsName, Node documentNode,String repository, String workspace, String[] roles) throws Exception ;` | Add a group tag to a document. A folksonomy link will be created in a tag node. @param tagNames: Array of tag name as the children of tree. @param documentNode: Tags this node by creating a folksonomy link to the node in tag. @param repository: Repository name @param workspace: Workspace name @param roles: User roles @throws Exception
addPublicTag | `void` | `addPublicTag(String treePath, String[] tagsName, Node documentNode, String repository, String workspace) throws Exception ;` | Add a public tag to a document. A folksonomy link will be created in a tag node. @param treePath: Path of folksonomy tree @param tagNames: Array of tag name as the children of tree. @param documentNode: Tags this node by creating a folksonomy link to the node in the tag. @param repository: Repository name @param workspace: Workspace name @throws Exception
addSiteTag | `void` | `addSiteTag(String siteName, String[] tagsName, Node node, String repository, String workspace) throws Exception ;` | Add a site tag to a document. A folksonomy link will be created in a tag node. @param siteName: Portal name @param treePath: Path of folksonomy tree @param tagNames: Array of tag name as the children of tree. @param documentNode: Tags this node by creating a folksonomy link to the node in tag. @param repository: The repository name @param workspace: Workspace name @throws Exception
getAllPrivateTags | `List<Node>` | `getAllPrivateTags(String userName, String repository, String workspace) throws Exception ;` | Get all private tags. @param userName: User name @param repository: The repository name @param workspace: Workspace name @return List<Node>
getAllPublicTags | `List<Node>` | `getAllPublicTags(String treePath, String repository, String workspace) throws Exception ;` | Get all public tags. @param treePath: Folksonomy tree path @param repository: The repository name @param workspace: Workspace name @return List<Node> @throws Exception
getAllGroupTags | `List<Node>` | `getAllGroupTags(String[] roles, String repository, String workspace) throws Exception ;` | Get all tags by groups. @param roles: Roles of user @param repository: Repository name @param workspace: Workspace name @return List<Node> @throws Exception
getAllGroupTags | `List<Node>` | `getAllGroupTags(String role, String repository, String workspace) throws Exception ;` | Get all tags by group. @param role: Role of user @param repository: Repository name @param workspace: Workspace name @return List<Node> @throws Exception
getAllSiteTags | `List<Node>` | `getAllSiteTags(String siteName, String repository, String workspace) throws Exception ;` | Get all tags of Site. @param siteName: Portal name @param treePath: Folksonomy tree path @param repository: Repository name @param workspace: Workspace name @return List<Node> @throws Exception
getAllDocumentsByTag | `List<Node>` | `getAllDocumentsByTag(String tagPath, String repository, String workspace, SessionProvider sessionProvider) throws Exception ;` | Get all documents which are stored in a tag. @param treeName: The name of folksonomy tree @param tagName: The name of a tag @param repository: The repository name @return: a list of documents in atag @throws Exception
getTagStyle | `String` | `getTagStyle(String tagPath, String repository, String workspace) throws Exception ;` | Get HTMLSTYLEPROP property in styleName node in repository. @param tagPath: Tag path @param workspace: The workspace name @param repository: The repository name @return: The value of property of the styleName node @throws Exception
addTagStyle | `void` | `addTagStyle(String styleName, String tagRange, String htmlStyle, String repository, String workspace) throws Exception ;` | Update the properties TAGRATEPROP and HTMLSTYLEPROP, following the values tagRate, htmlStyle for node in tagPath in repository. @param styleName: Style name @param tagRate: The range of tag numbers @param htmlStyle: Tag style @param repository: The repository name @param workspace: The workspace name @throws Exception
updateTagStyle | `void` | `updateTagStyle(String styleName, String tagRange, String htmlStyle, String repository, String workspace) throws Exception ;` | Update the properties TAGRATEPROP and HTMLSTYLEPROP, following the value tagRate, htmlStyle for node in tagPath in repository. @param styleName: Style name @param tagRate: The range of tag numbers @param htmlStyle: Tag style @param repository: The repository name @param workspace: The workspace name @throws Exception
getAllTagStyle | `List<Node>` | `getAllTagStyle(String repository, String workspace) throws Exception ;` | Get all tag style bases of a folksonomy tree. @param repository: The repository name @param workspace: Workspace name @return List<Node> List tag styles @throws Exception
init | `void` | `init(String repository) throws Exception ;` | Initialize all TagStylePlugin with session in repository name. @param repository: The repository name
removeTagOfDocument | `void` | `removeTagOfDocument(String tagPath, Node document, String repository, String workspace) throws Exception;` | Remove a tag of a given document. @param treeName: The name of a folksonomy tree @param tagName: The name of a tag @param document: The document which is added a link to tagName. @param repository: The repository name @return @throws Exception
removeTag | `void` | `removeTag(String tagPath, String repository, String workspace) throws Exception;` | Remove tag. @param tagPath: The path of the tag @param repository: The repository name @param workspace: The workspace name
modifyTagName | `Node` | `modifyTagName(String tagPath, String newTagName, String repository, String workspace) throws Exception;` | Modify the tag name. @param tagPath: The name of the tag @param newTagName: New tag name @param repository: The repository name @param workspace: The workspace name @return @throws Exception
getLinkedTagsOfDocument | `List<Node>` | `getLinkedTagsOfDocument(Node documentNode, String repository, String workspace) throws Exception;` | Get all tags linked to a given document. @param documentNode: Document node @param repository: The repository name @param workspace: Workspace name @return @throws Exception
getLinkedTagsOfDocumentByScope | `List<Node>` | `getLinkedTagsOfDocumentByScope(int scope, String value, Node documentNode, String repository, String workspace) throws Exception;` | Get all tags linked to a given document by scope. @param documentNode: Document node @param repository: The repository name @param workspace: The workspace name @return @throws Exception
removeTagsOfNodeRecursively | `void` | `removeTagsOfNodeRecursively(Node node, String repository, String workspace, String username, String groups) throws Exception;` | Remove all tags linked to the child nodes of a given node. @param node @param repository @param workspace @throws Exception
addTagPermission | `void` | `addTagPermission(String usersOrGroups);` | Add given users or groups to tagPermissionList. @param usersOrGroups
removeTagPermission | `void` | `removeTagPermission(String usersOrGroups);` | Remove given users or groups from tagPermissionList. @param usersOrGroups
getTagPermissionList | `List<String>` | `getTagPermissionList();` | Return tagPermissionList.
canEditTag | `boolean` | `canEditTag(int scope, List<String> memberships);` | Set the permission to edit a tag for a user. @param scope: Scope @param memberships: Memberships @return: true if it is possible.
getAllTagNames | `List<String>` | `getAllTagNames(String repository, String workspace, int scope, String value) throws Exception;` | Get all tag names which start within a given scope. @param repository: Repository @param workspace: Workspace @param scope: scope of tags @param value: value, according to scope, can be understood differently. @return true if it is possible.

### ApplicationTemplateManager

This class is used to manage dynamic groovy templates for WCM-based products.

Package org.exoplatform.services.cms.views.ApplicationTemplateManager;

Method | Return | Prototype | Description
--- | --- | --- | ---
addPlugin | `void` | addPlugin(PortletTemplatePlugin portletTemplatePlugin) throws Exception | Add the plugin. portletTemplatePlugin: the portlet template plugin
getAllManagedPortletName | `List<String>` | getAllManagedPortletName(String repository) throws Exception | Retrieve all the portlet names that have dynamic groovy templates managed by service. repository: the repository @throws Exception the exception
getTemplatesByApplication | `List<Node>` | getTemplatesByApplication(String repository, String portletName, SessionProvider provider) throws Exception; | Retrieve the templates node by application. @param repository: the repository @param portletName: the portlet name @param provider: the provider @return the templates by application @throws Exception: the exception
getTemplatesByCategory | `List<Node>` | getTemplatesByCategory(String repository, String portletName, String category, SessionProvider sessionProvider) throws Exception; | Retrieve the templates node by category. @param repository: the repository @param portletName: the portlet name @param category: the category @param sessionProvider: the session provider @return the templates by category @throws Exception: the exception
getTemplateByName | `Node` | getTemplateByName(String repository, String portletName, String category, String templateName, SessionProvider sessionProvider) throws Exception; | Retrieve the template by name. @param repository: the repository @param portletName: the portlet name @param category: the category @param templateName: the template name @param sessionProvider: the session provider @return the template by name @throws Exception: the exception
getTemplateByPath | `Node` | getTemplateByPath(String repository, String templatePath, SessionProvider sessionProvider) throws Exception ; | Get the template by path. @param repository: the repository @param templatePath: the template path @param sessionProvider: the session provider @return the template by path @throws Exception: the exception
addTemplate | `void` | addTemplate(Node portletTemplateHome, PortletTemplateConfig config) throws Exception; | Add the template. @param portletTemplateHome: the portlet template home @param config: the config @throws Exception: the exception
removeTemplate | `void` | removeTemplate(String repository, String portletName, String catgory, String templateName, SessionProvider sessionProvider) throws Exception; | Remove the template. @param repository: the repository @param portletName: the portlet name @param catgory: the catgory @param templateName: the template name @param sessionProvider: the session provider @throws Exception: the exception

### NodeFinder

NodeFinder is used to find a node with a given path. If the path to the node contains sub-paths to exo:symlink nodes, find the real link node.

Method | Return | Prototype | Description
--- | --- | --- | ---
getNode | `Node` | getNode(Node ancestorNode, String relativePath) throws PathNotFoundException, RepositoryException; | Return the node at relPath related to the ancestor node. @param ancestorNode: The ancestor of the node to retrieve from which we start. @param relativePath: The relative path of the node to retrieve. @throws PathNotFoundException: If "no", the node exists at the specified path. @throws RepositoryException: if another error occurs.
getNode | `Node` | getNode(Node ancestorNode, String relativePath, boolean giveTarget) throws PathNotFoundException, RepositoryException; | Return the node at relPath related to the ancestor node. If the node is a link and giveTarget has been set to <code>true</code>, the target node will be returned @param ancestorNode: The ancestor of the node to retrieve from which we start. @param relativePath: The relative path of the node to retrieve. @param giveTarget: Indicates if the target must be returned in case the item is a link @throws PathNotFoundException: If no node exists at the specified path. @throws RepositoryException: if another error occurs.
getItem | `Item` | getItem(String repository, String workspace, String absPath) throws PathNotFoundException, RepositoryException; | Return the item at the specified absolute path. @param repository: The name of repository @param workspace: The name of workspace @param absPath: An absolute path @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItemSys | `Item` | getItemSys(String repository, String workspace, String absPath, boolean system) throws PathNotFoundException , RepositoryException; | Return the item at the specified absolute path. @param repository: The name of repository @param workspace: The name of workspace @param absPath: An absolute path. @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItem | `Item` | getItem(String repository, String workspace, String : absPath, boolean giveTarget) throws PathNotFoundException, RepositoryException; | Return the item at the specified absolute path. If the item is a link and giveTarget has been set to <code>true</code>, the target node will be returned. @param repository: The name of repository @param workspace: The name of workspace @param absPath: An absolute path @param giveTarget: Indicates if the target must be returned in case the item is a link @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItemGiveTargetSys | `Item` | getItemGiveTargetSys(String repository, String workspace, String absPath, boolean giveTarget, boolean system) throws PathNotFoundException, RepositoryException; | Return the item at the specified absolute path. If the item is a link and giveTarget has been set to <code>true</code>, the target node will be returned. @param repository: The name of repository @param workspace: The name of workspace @param absPath: An absolute path @param giveTarget: Indicates if the target must be returned in case the item is a link @param system: system provider @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItem | `Item` | getItem(Session session, String absPath) throws PathNotFoundException, RepositoryException; | Return the item at the specified absolute path. @param session: The session is used to get the item @param absPath: An absolute path @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItem | `Item` | getItem(Session session, String absPath, boolean giveTarget) throws PathNotFoundException, RepositoryException; | Return the item at the specified absolute path. If the item is a link and giveTarget has been set to <code>true</code>, the target node will be returned @param session: The session is used to get the item. @param absPath: An absolute path @param giveTarget: Indicates if the target must be returned in case the item is a link @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
getItemTarget | `Item` | `getItemTarget(Session session, String absPath, boolean giveTarget, boolean system) throws PathNotFoundException, RepositoryException;` | Return the item at the specified absolute path. If the item is a link and giveTarget has been set to <code>true</code>, the target node will be returned @param session: The session is used to get the item. @param absPath: An absolute path @param giveTarget: Indicates if the target must be returned in case the item is a link. @param system: system provider @throws PathNotFoundException: if the specified path cannot be found. @throws RepositoryException: if another error occurs.
itemExists | `boolean` | itemExists(Session session, String absPath) throws RepositoryException; | Return <code>true</code> if an item exists at absPath; otherwise returns <code>false</code> Also returns <code>false</code> if the specified absPath is malformed. @param session: The session is used to get the item. @param absPath: An absolute path @return <code>true</code> if an item exists at absPath; otherwise returns <code>false</code>. @throws RepositoryException: if an error occurs.

### JodConverter

JodConverter is used to convert documents into different office formats.

Package org.exoplatform.services.cms.jodconverter.JodConverterService

Method | Return | Prototype | Description
--- | --- | --- | ---
convert | `void` | convert(InputStream input, String formatInput, OutputStream out, String formatOutput) throws Exception; | Convert InputStream in the formatInput format to OutputStream with the formatOutput format. @param input @param formatInput @param out @param formatOutput @throws Exception

### SiteSearchService

SiteSearchService is used in the Search portlet that allows users to find all information matching with your given keyword.

Method | Return | Prototype | Description
--- | --- | --- | ---
addExcludeIncludeDataTypePlugin | `void` | addExcludeIncludeDataTypePlugin(ExcludeIncludeDataTypePlugin plugin) | Filter mimetypes data in the search results. @param plugin: The plugin.
searchSiteContents | `AbstractPageList<ResultNode>` | searchSiteContents(SessionProvider sessionProvider, QueryCriteria queryCriteria, int pageSize, boolean isSearchContent) throws Exception; | Find all child nodes whose contents match with the given keyword. These nodes will be put in the list of search results. @param queryCriteria: The query criteria for SiteSearchService. Based on search criteria, SiteSearchService can easily create the query statement to search. @param sessionProvider: The session provider. @param pageSize: The number of search results on a page.

### SEOService

SEOService supplies APIs to manage SEO data of a page or a content. This service includes some major functions which enables you to add, store, get or remove the metadata of a page or a content.

Method | Return | Prototype | Description
--- | --- | --- | ---
storePageMetadata | `void` | `storePageMetadata(PageMetadataModel metaModel, String portalName, boolean onContent) throws Exception` | Store the metadata of a page/content. @param metaModel: The metadata of a page/content stored. @param portalName: The name of portal. @param onContent: Indicate whether the current page is the content page or the portal page.
getMetadata | `PageMetadataModel` | `PageMetadataModel (ArrayList<String> params, String pageReference) throws Exception` | Return the metadata of a portal page or a content page. @param params: The parameters list of a content page. @param pageReference: The reference of the page.
getPageMetadata | `PageMetadataModel` | `getPageMetadata(String pageReference) throws Exception` | Return the metadata of a portal page. @param pageReference: The reference of the page.
getContentMetadata | `PageMetadataModel` | `getContentMetadata(ArrayList<String> params) throws Exception` | Return the metadata of a content page. @param params: The parameters list of a content page.
removePageMetadata | `void` | `removePageMetadata(PageMetadataModel metaModel, String portalName, boolean onContent) throws Exception` | Remove the metadata of a page. @param metaModel: The metadata of a page/content stored. @param portalName: The name of portal. @param onContent: Indicate whether the current page is the content page or the portal page.
getContentNode | `Node` | `getContentNode(String contentPath) throws Exception` | Return the content node by the content path. @param contentPath: The content path.
getHash | `String` | `getHash(String uri) throws Exception` | Create a key from the page reference or the UUID of the node. @param uri: The page reference of the UUID of a node.
getSitemap | `String` | `getSitemap(String portalName) throws Exception` | Return a sitemap's content of a specific portal. @param portalName: The portal name.
getRobots | `String` | `getRobots(String portalName) throws Exception` | Return Robots' content of a specific portal. @param portalName: The portal name.
getRobotsIndexOptions | `List<String>` | `getRobotsIndexOptions() throws Exception` | Return a list of options (INDEX and NOINDEX) for robots to index.
getRobotsFollowOptions | `List<String>` | `getRobotsFollowOptions() throws Exception` | Return a list of options (FOLLOW and NOFOLLOW) for robots to follow.
getFrequencyOptions | `List<String>` | `getFrequencyOptions() throws Exception` | Return a list of options for frequency.

## FAQ

### How to deploy a workflow?

The addPlugin() function of WorkflowServiceContainer service is used to register a Business Process when a workflow is implemented. Thus, if you want to use a workflow, you are required to configure the workflow service to invoke the addPlugin() function by adding the external-component-plugins element to the configuration file.

You have to set values for the name and location of the workflow which you want to use. There are TWO ways to configure the location of the workflow.

#### Deploy a workflow inside a .war file

You can use "war:(FOLDER_PATH)" to configure which .jar files contain your workflow processes inside the .war file.

    <external-component-plugins>

      <target-component>org.exoplatform.services.workflow.WorkflowServiceContainer</target-component>

      <component-plugin>

        <name>deploy.predefined.processes</name>

        <set-method>addPlugin</set-method>

        <type>org.exoplatform.services.workflow.PredefinedProcessesPlugin</type>

        <init-params>

          <object-param>

            <name>predefined.processes</name>

            <description>load of default business processes</description>

            <object type="org.exoplatform.services.workflow.ProcessesConfig">

              <field name="processLocation">

                <string>war:/conf/bp</string>

              </field>

              <field name="predefinedProcess">

                <collection type="java.util.HashSet">

                  <value>

                    <string>/exo-ecms-ext-workflow-bp-jbpm-content-2.1.1.jar</string>

                  </value>

                  <value>

                    <string>/exo-ecms-ext-workflow-bp-jbpm-payraise-2.1.1.jar</string>

                  </value>

                  <value>

                    <string>/exo-ecms-ext-workflow-bp-jbpm-holiday-2.1.1.jar</string>

                  </value>

                </collection>

              </field>

            </object>

          </object-param>

        </init-params>

      </component-plugin>

    </external-component-plugins>

#### Deploy a workflow inside a .jar file

You can use "classpath:" to configure which .jar files contain your workflow processes inside the .jar file.

    <external-component-plugins>

      <target-component>org.exoplatform.services.workflow.WorkflowServiceContainer</target-component>

      <component-plugin>

        <name>deploy.predefined.processes</name>

        <set-method>addPlugin</set-method>

        <type>org.exoplatform.services.workflow.PredefinedProcessesPlugin</type>

        <init-params>

          <object-param>

            <name>predefined.processes</name>

            <description>load of default business processes</description>

            <object type="org.exoplatform.services.workflow.ProcessesConfig">

              <field name="processLocation">

                <string>classpath:</string>

              </field>

              <field name="predefinedProcess">

                <collection type="java.util.HashSet">

                  <value>

                    <string>/exo-ecms-ext-workflow-bp-jbpm-content-myworkflow.jar</string>

                  </value>

                </collection>

              </field>

            </object>

          </object-param>

        </init-params>

      </component-plugin>

    </external-component-plugins>

The notification message is displayed when you deploy a workflow on Jboss. If you use "classpath:" to register, you must put your workflow in the .jar files inside the gatein.ear/lib folder (instead of the lib folder) to make it work.

- Prev
- Up
- Home
- Next