Méthode Swing DWP editor can be extended in multiple parts by adding custom buttons and executing custom actions, or configuring custom templates to render DWP linked objects.

Location of the DWP Editor extensions.

DWP Editor extensions consist in a Javascript (*.js) file loaded with Swing.

In general, all the extensions of Méthode Swing are places under

{SWING-APP}/plugins

So, all the Javascript described in the following sections should be placed under

{SWING-APP}/app/plugins/{EXTENSION-FOLDER}/{EXTENSION-NAME}.js

Do not use the word libs as an extension folder. The libs folder is reserved for loading external libs. See the proper documentation to obtain further info on the topic.

DEBUG MODE: by default, all plugins are aggregated into a single plugins.js file at the Tomcat startup. When creating a plugin, it may be frustrating to restart the Tomcat Server every time a change is made.

To avoid this, set the configuration property debugEnabled to true.

Then, that extension will be loaded on every refresh of the page.

Namespaces of the DWP editor extensions

DWP Editor extensions are available under the following namespace:

eidosmedia.webclient.actions.dwpeditor

Configure actions

Throughout this document, the example will focus on the development of a simple custom command, named custom.EditDwplink, which will edit a dwp link custom properties.

To add an action, then, it is necessary to follow the steps described below:

1. Add a custom command

The editor extensions follow the same approach of Swing commands.

See the Command configuration paragraph for further details.

Example

eidosmedia.webclient.commands.add({
    name: 'change.dwpLink',
    isActive: function( ctx ) {
        return true;
    },
    isEnabled: function( ctx ) {
        return true;
    },
    action: function( ctx, params, callbacks ) {
       if (callbacks && callbacks.success) {
          callbacks.success( /*...*/ );
       }
   }
});

The details of the implementation of the isEnabled and isActive method will be explained later.

2. Associated the commands to item toolbar

As a second step, the newly created command must be associated to the item toolbar. To add a button to the item toolbar, the following namespace must be used

eidosmedia.webclient.actions.dwpeditor

The method to be used is addButton(settings). See the following example:

/**
 * We now register a new action in the item toolbar using
 * the proper namespace. In this case we call the addButton
 * method, we define a label and an icon for the button and more important
 * we tell the button which command has to trigger using the
 * action property
 */
eidosmedia.webclient.actions.dwpeditor.addButton({
    action: "change.dwpLink",
    label: "Chane Dwp Link",
    icon: 'icon-globe'
});

The addButton method requires a single Javascript object ( settings ) as a parameter. This objects need to have the following properties:

  • action: the name of the previously registered command

  • label: the label associated with the command

  • icon: the icon associated with the command. See Icons supported by Swing for a comprehensive list of icons available in Swing.

Implementation of the DWP editor extensions

The editor extensions are powerful because they make use of an editor-related version of the context object. See Context Object for the editor extensions for further details.

As of any command implementation, it is possible to specify the isActive, isEnabled and action methods.

  • isActive method is called in different points according to the editor part it refers to.

    • For the toolbar the method is called after the story is loaded to determine whether a custom action is available.

    • For the components the method is called when a new component is created ( or an existing one is loaded from the story )

  • isEnabled method is called in different points according to the editor part it refers to.

    • For the toolbar the method is called whenever the user changes the current selection or cursor position.

  • the action is called when the user clicks on the corresponding action button.

All the methods are called with the same Context Object ( ctx ), which is enhanced for the editor and allows to access the active object ( activeObject ). See Context Object for the editor extensions for further details.

Context Object for the editor extensions

Basic structure of the Context Object

The Context object is made of a specific list of properties, and a number of publicly available methods.

{
    application: {
        getId: function()
    },
    area: {
        getType: function(),
        getName: function(),
        getContext: function()
    },
    component: {
        getType: function()
    },
    activeObject: {
        // Methods of the single object.
    },
    activeObjects: [{activeObject}] // An array of activeObject
    selection: [ ] // Array of objects. See below.
}
Table 1. Parameters list
Parameter Value type Description Values

application.getId()

String

Returns the application Id.

"swing", …​

area.getType()

String

Returns the area type.

"main" (for the main views), "editor"

area.getName()

String

Returns the area name.

"explorer", "dashboard", "myarea", "liveblogmanagement" (for "main" areas). "story" (for editors).

area.getContext()

String

Returns the area context.

"story-editor", "report-editor", "dwp-editor", "topic@editor", "topic@search", "topic@binder", "topicplan@editor", "topicplan@search", "topicplan@binder", "topicitem", "upload", "diagram-workflow", "search", "planning-calendar"

component.getType()

String

Returns the component type.

"toolbar", "grid", "objectpanel"…​

activeObject

Object

Returns an object with a set of methods. Refer to : Methods of the single object for the list of methods.

activeObjects

Array

Returns an array of activeObject(s). In bulk selection mode all selected items are returned here as array. In single selection mode array length is 1. Each activeObject is coupled with one selected item. Methods of the single object operate to that item.

selection

Array of Object

Returns an array with the currently selected items. Each item has the same set of methods available. Refer to : Methods of the single object for the list of methods.

Each context has a different value for these properties.

Methods available in the Context Object

Further details on the methods available in the Context Object can be found in the Context Object Methods reference.

In the Editor context, activeDocument and selection are NOT available.

The Dwp Editor Context Object activeObject contains a subset of methods to access the current dwp link information. These methods are described in the Dwp Editor API paragraph.

Dwp Editor API

Returns dwp link information.

It can be called as

ctx.activeObject.getLink();
Table 2. Method information

Method

getLink

Parameter

None

Returns

{JSON Object} Dwp link information

Example
var info = ctx.activeObject.getLink();

// info is now:
{
    "name": "230-Short updates.dwc",
    "id": "1.0.36956807",
    "type": "EOM::WebContainer",
    "modified": {
        "type": "DATE",
        "format": "YYYYMMDDHHmmss",
        "value": "20160323133940"
    },
    "last_modifier": "Dario",
    "locked": {
        "type": "DATE",
        "format": "YYYYMMDDHHmmss",
        "value": "20160323133940"
    },
    "locker": "",
    "webType": "dwc-4stories-230",
    "styleSheet": "List",
    "templates": [
        "Grid",
        "List",
        "230-4rows1col"
    ],
    "status_info": {
        "name": "",
        "identifier": "",
        "comment": ""
    },
    "system_attributes": {
        "workfolder": "/Globe/Politics",
        "template": "",
        "templateName": "/SysConfig/Globe/Web/DwcTemplates/public/230/230-4rows1col.dwc",
        "summary": "",
        "wordCount": "",
        "sugCategory": "",
        "channel": "Globe-Web",
        "storyType": "",
        "productInfo": {
            "name": "Globe-Web",
            "issueDate": "20111005"
        },
        "priority": ""
    },
    "system_attributes_xml": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\r\n<props><productInfo><name>Globe-Web</name>\r\n<issueDate>20111005</issueDate>\r\n</productInfo>\r\n<workFolder>/Globe/Politics</workFolder>\r\n<templateName>/SysConfig/Globe/Web/DwcTemplates/public/230/230-4rows1col.dwc</templateName>\r\n</props>\r\n",
    "channel": "Globe-Web",
    "pstate": {
        "uuid": "f8c9bd50-ee54-11e0-b51c-542d5e32b6d1",
        "suid": "",
        "loid": "1.0.36956807",
        "retention_time": 0,
        "ucount": 44
    },
    "position": 1
}
getTemplates

Returns the list of dwp link available templates.

It can be called as

ctx.activeObject.getTemplates();
Table 3. Method information

Method

getTemplates

Parameter

None

Returns

{JSON Array} List of dwp link available templates

Example
var templates = ctx.activeObject.getTemplates();

// templates is now:
[{
	"value":"Grid",
	"selected":false
},{
	"value":"List",
	"selected":true
}, {
	"value":"230-4rows1col"
	,"selected": false
}]
getCustomProperties

Returns the list of dwp link custom properties.

It can be called as

ctx.activeObject.getCustomProperties();
Table 4. Method information

Method

getCustomProperties

Parameter

None

Returns

{JSON Array} List of dwp link custom properties

Example
var properties = ctx.activeObject.getCustomProperties();

// properties is now:
[{
	"key": "customTitle",
	"value": "Alternate title"
}, {
	"key": "customDisplayLink",
	"value": "yes"
}, {
	"key": "customMaxResults",
	"value": "10"
}, {
	"key": "customTitleColor",
	"value": "gray"
}]
setCustomProperties

Set the list of dwp link custom properties.

It can be called as

ctx.activeObject.setCustomProperties(properties);
Table 5. Method information

Method

setCustomProperties

Parameter

{JSON Array} List of dwp link custom properties

Returns

None

Example
var properties = [{
	"key": "customTitle",
	"value": "Alternate title"
}, {
	"key": "customDisplayLink",
	"value": "yes"
}, {
	"key": "customMaxResults",
	"value": "10"
}, {
	"key": "customTitleColor",
	"value": "gray"
}];

ctx.activeObject.setCustomProperties(properties);

Custom DWP linked item templates

Méthode Swing DWP editor uses HTML templates to render linked objects. It is possible to configure custom templates to be used based on linked item type.

DWP Linked Item
Figure 1. DWP Linked Item

Editor configuration

In DWP editor configuration (see DWP editor configuration) can be specified which HTML template should be used to render a specific item linked type.

<WebClientConfiguration>
    ...
    <editor>
        ...
        <webpage>
            ...
            <linkedItemTemplates>
                <linkedItemTemplate>
                    <type>EOM::CompoundStory</type>
                    <template>dwp-story-template.html</template>
                </linkedItemTemplate>
                <linkedItemTemplate>
                    <type>EOM::WebContainer</type>
                    <template>dwp-dwc-template.html</template>
                </linkedItemTemplate>
            </linkedItemTemplates>
        </webpage>
    </editor>
<WebClientConfiguration>

Configured template files will be retrieved from

{SWING-APP}/config/templates/dwp/{TEMPLATE-NAME}

and can be configured outside {SWING-APP}, see the paragraph How to configure DWP linked item templates in external folder.

Templating system

Underscore.JS templating system is used to define templates.

The template is rendered with a main object item, which contains all the information about the item.

// item:
{
    name: 'ART-stories_block.dwc',
    id: '1.0.895409210',
    databaseId: '41',
    type: 'EOM::WebContainer',
    modified: 1524043188,
    last_modifier: 'john.doe',
    locked: 1542709437,
    // empty string if the item is not locked, username of the locker otherwise
    locker: '',
    webType: 'dwc-element-4row3cols',
    styleSheet: null,
    // stylesheet configured for the zone and applied as default
    defaultStylesheet: 'first',
    // selected template
    template: 'stories_block',
    // available templates
    templates: [
        {
            name: 'stories_block',
            path:
                '/SysConfig/Globe/WebV2/DwcTemplates/public/1060/stories_block.dwc'
        },
        {
            name: 'one_story_2_heads',
            path:
                '/SysConfig/Globe/WebV2/DwcTemplates/public/1060/one_story_2_heads.dwc'
        }
    ],
    status_info: {
        name: '',
        identifier: ''
    },
    // thumbnail preview if available, null otherwise
    preview: null,
    channel: 'Globe-Web',
    owner: 'john.doe',
    creator: 'john.doe',
    created: 1500474152,
    size: 243,
    path: '/Globe/WebV2/Web Components/Art/ART-stories_block(1).dwc',
    issueDate: '20150903',
    system_attributes_xml: 'system attributes XML string',
    system_attributes_json: {
        // system attributes as json object
    },
    usage_ticket: 'usage ticket XML string',
    usage_ticket_json: {
        // usage ticket as json object
    },
    attributes: 'attributes XML string',
    attributes_json: {
        // attributes as json object
    },
    virtual_attributes: 'virtual attributes XML string',
    virtual_attributes_json: {
        // attributes as json object
    },
    summary: '',
    dwc: {
        struct: {
            // dwc container structure as json object, see next section
        },
        links: {
            // dwc linked items, see next section
        }
    },
    // Icon class for type
    iconType: 'emui-icon-dwp',
    // Display label for type
    labelType: 'Web Container'
}

DWC

If a linked item is also a container, e.g. a DWC, the object passed to the template will also have a dwc field, containing information about container structure and linked items.

{
    // ...
    dwc: {
        struct: {
            type: 'container',
            path: 'root',
            pageTemplate: 'stories_block',
            depth: 0,
            slots: 12,
            rowspan: 1,
            id: '41$1.0.895409210',
            channel: 'Globe-Web',
            webType: 'dwc-element-4row3cols',
            rows: [
                {
                    dimension: 1,
                    boxesCount: 3,
                    boxes: [
                        {
                            type: 'zone',
                            path: 'root[r0]-zone0',
                            depth: 1,
                            slots: 5,
                            rowspan: 1,
                            sequence: 1,
                            maxItems: 4,
                            styleSheet: '2col-photo-homepage',
                            name: 'box',
                            zoneIndex: 1
                        }
                        // ...
                    ]
                }
            ],
            dimension: 1
        },
        links: {
            box: [
                {
                    depth: 0,
                    slots: 0,
                    rowspan: 0,
                    sequence: 1,
                    maxItems: 1,
                    styleSheet: '1col-photo-tight-homepage',
                    links: [
                        {
                            id: '1.0.740572086',
                            name: 'Story 1',
                            databaseId: '41',
                            channel: 'Globe-Web',
                            webType: 'story',
                            position: 1,
                            type: 'EOM::CompoundStory',
                            modified: 1522759672,
                            last_modifier: 'john.doe',
                            locked: 1524465039,
                            locker: '',
                            status_info: {
                                name: 'NewsFlow/Editing',
                                identifier: 'RGB(255,0,0)'
                            },
                            system_attributes_json: {
                                // system attributes as json object
                            }
                        }
                    ],
                    zoneIndex: 0
                }
                // ...
            ]
        }
    }
}

Following, a very simple example of a custom template for DWC objects:

<%
    function writeLink(link) {
        %>
            <div><%=link.name%></div>
        <%
        // ...
    }

    function writeRow(row) {
        %>
        <div>DWC row</div>
        <ul>
            <%
                _.each(row.boxes, function(box) {
                    if (box.type === 'zone' || box.type === 'container') {
                        %><li>
                            <div>BOX</div>
                            <%
                                var seqObj = _.findWhere(
                                    item.dwc.links[box.name],
                                    { sequence: parseInt(box.sequence) }
                                );
                                _.each(seqObj && seqObj.links, writeLink);
                            %>
                        </li><%
                    }
                });
            %>
            </ul>
        <%
    }
%>
<div>
    <h1>DWC</h1>
    <p>Name <%=item.name%></p>
    <%
        _.each(item.dwc.struct.rows, writeRow);
    %>
</div>

How to configure DWP linked item templates in external folder

Custom DWP linked item templates may be made available to Swing application by defining one or more nested components in Swing web context in server.xml. (for further details on Tomcat 9.x Resources configuration, please refer to Resources configuration).

<Context docBase="com.eidosmedia.webclient.web-app"
    path="/swing" reloadable="false">
    <Resources className="org.apache.catalina.webresources.StandardRoot">
        <PreResources
            className="org.apache.catalina.webresources.DirResourceSet"
            base="/methode/meth01/extension/dwp-templates" readOnly="true"
            webAppMount="/config/templates/dwp" />
    </Resources>
</Context>