Customizing Documentum D2

I have been working on customization of D2 for the last 1.5 years and I think that I am in a good position to share some knowledge I managed to gather. I am going to start a series of blog posts explaining some less obvious tricks that I find useful.

So, lets start with customizing D2 menus…

There are two ways of doing it, one way involves using D2-Config, you can simply click on “Go to…/D2 Menu” and then configure order of menu items, change their conditions etc.
This is fine, but this is not always the best way of doing it. For example, what if you would like to add more advanced conditions which are not available in vanilla D2? Or what if you would like to dynamically create menu items? This simply can’t be done by using just the D2-Config. In more advanced projects it is often better to have the menus customized via XML in a D2 plugin than in D2-Config, this also allows better control of changes (as all files are in VCS some sort).

Okay, enough introduction, lets see some example. Lets assume that we would like to add a static D2 menu that will open some dialog.
In order to achieve this goal it is good to understand how D2 plugins work. At the moment lets only focus on a typical plugin folder structure:


The menu layout XML file is stored in src/main/resources/xml/menu, so lets create a file MenuContextDelta.xml there with following content:

<?xml version="1.0" encoding="utf-8"?>
    <insert position-after="menuContextEdit">
        <menuitem id="menuContextSampleStatic">

The name of this file is important, it is a ‘delta’ file containing differences that merged with the base MenuContext.xml (that is stored in D2FS4DCTM-WEB-4.5.jar) will produce the final MenuContext.xml.

What the XML code does is pretty simple, we define a new menu item, that will be inserted after menuContextEdit menu item (that is ‘Edit’) in the Context menu (this is implied by name of the MenuContextDelta.xml file). When clicked, the new menu item will show dialog named ‘SampleDialog’.

Now, what if we would like to have a dynamic menu item? Lets say the requirement is to list available custom actions e.g “Publish to system A”, “Publish to system B” etc. when the menu is selected.

In order to implement it we need two files: first one adds the main menu item that contains reference to the second file (please note src=”PublishSubmenu”), second one points to the Java class that will generate available submenu options based on the current document selection (as available publishing systems depend on the selected document):

File: MenuContextDelta.xml

<?xml version="1.0" encoding="utf-8"?>
    <insert position-after="menuContextEdit">
        <menuitem id="menuContextSampleSubmenu" src="PublishSubmenu">

File: PublishSubmenu.xml

<?xml version="1.0" encoding="utf-8"?>
    <dynamic-menuitem id="submenuPublish" class="">

And finally the Java class that will create submenu items:


import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.documentum.fc.client.IDfSysObject;
import com.emc.d2fs.dctm.ui.dynamicactions.actions.ShowDialog;
import com.emc.d2fs.utils.AttributeUtils;

 * Created by kbryd on 11/01/2015.
public class PublishMenu extends SimpleDynamicMenu {

  public XmlNode getXmlMenuItem(D2fsContext context) throws Exception {
    XmlNode result = new XmlNode();
    IDfSysObject sysObject = (IDfSysObject)context.getFirstObject();
    AvailablePublishingSystemsModel model = PublishingUtils.getSystems(context.getSession(), sysObject);
    List<String> configNames = model.getSystemsAsList();

    for(int i = 0; i < configNames.size(); i++) {
      String configName = configNames.get(i);
      String label = configName;
      XmlNode node = result.appendChildNode("menuitem");
      node.setAttribute("id", "genid_" + i);
      node.setAttribute("label", label);

      Map<String, Object> attributes = new HashMap();
      attributes.put("DIALOG_NAME", "ConfirmPublishDialog");
          "target_system" + AttributeUtils.SEPARATOR_VALUE + "label" + AttributeUtils.SEPARATOR_VALUE
              + "oam_id");
      attributes.put("target_system", configName);
      node.setAttribute("action", new ShowDialog().getAction(context, attributes));
    return result;

There is one small interesting thing going on there…I pass the target_system name to the dialog so it can be displayed as part of the confirmation message:

      Map<String, Object> attributes = new HashMap();
      attributes.put("DIALOG_NAME", "ConfirmPublishDialog");
          "target_system" + AttributeUtils.SEPARATOR_VALUE + "label" + AttributeUtils.SEPARATOR_VALUE
              + "oam_id");
      attributes.put("target_system", configName);
      node.setAttribute("action", new ShowDialog().getAction(context, attributes));

Merely adding the value to the attributes Map is not enough to pass the value to the dialog. It is also important to add that attribute name to the DIALOG_LIST_PARAM value. Then in the dialog buildDialog method you can access the parameter value like this:

  public XmlNode buildDialog(D2fsContext context, List<Attribute> attributes) throws Exception {
    XmlNode configDialog = XmlUtil.loadFromURL(context.getXmlDialogFile()).getRootXmlNode();

    DialogProcessor dialogProcessor = new DialogProcessor(context, configDialog);
    Map<String, String> defaultValues = new HashMap<>();
    defaultValues.put("target_system", context.getParameterParser().getStringParameter("target_system"));

    XmlNode dialogNode = dialogProcessor.getDialog();
    return dialogNode;

Nice thing about default values in dialogs is that the values can be automatically used in *.properties files.

Lets have a look at a ConfirmPublishDialog layout XML:

<?xml version="1.0" encoding="utf-8"?>
<dialog id="ConfirmPublishDialog" width="410" height="200" resizable="true" buttons_right="false">
        <comment id="confirmMessage" html_content="true" condition_visible="true"/>
        <button id="buttonOk" type="submit" action="validDialog()" />
        <button id="buttonCancel" type="reset" action="cancelDialog()" />

The comment element has id ‘confirmMessage’. This id also points to the resource in in src/main/resources/strings/dialog/ConfirmPublishDialog.

And the promised trick is that you can use $value constructs there like this:

confirmMessage=Please confirm that you want to publish selected document to $value(target_system)

This saves some additional effort with passing the value down to the view.

I hope this was useful!

3 thoughts on “Customizing Documentum D2

  1. Dear Karol Bryd,

    I would like to request if it is possible to have a link to the full project because I think there is a missing class “AvailablePublishingSystemsModel” .


    • Hello Karol. Nice example! I’d like to create e custom D2 plugin and I found that your guide could be very usefull. I’m waiting the working example in order to start with the creation of plugins. Did you use eclipse? What kind of eclipse project did you create?
      According to you plugins could be a viable alternative to D2 Widgets?
      The plugin could be deployed as war under Tomcat?

      Thanks in advance

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.