Collective Spaces - BehaviorConfig.xml - Examples & How To
Creating a custom configuration for Collective Spaces is an advanced configuration task. This article shows how the different behavior elements are rendered, and gives some pointers that can help you create this configuration.
Before doing any configuration in the BehaviorConfig.xml, first see how your content will show up using the out-of-the-box configuration which is always applied, if your custom DITA specialized XML Schema is compiled. You should only make changes to this file on a development or test environment, never on production. Preferably, use an XML editor to update this file as it will provide help on which elements you can use where, because the BehaviorConfig.xsd, which defines the structure of the XML, is referenced from the behaviorconfig element.
Rendering Behavior elements
To get a better understanding of the rendering behavior elements you can use in your configuration, the examples below show how every element is actually rendered.
mapsheetelement- Used for:
mapelements and their specializations sheetelement- Used for:
topicelements and their specializations sheetbodyelement- Used for:
bodyelements or their specializations titleelement- Used for:
titleelements on any level blockelement- Used for: paragraph-like elements
inlineelement- Used for: phrase elements (
ph) or their specializations highlightingelement- Used for: highlighting elements
listelement- Used for: list elements and their items
imageelement- Used for:
imageelements or their specializations blockgenericiconelement- Used for: showing a placeholder on its own line to give the user an indication that there is XML content there, without showing all the content
inlinegenericiconelement- Used for: showing an inline placeholder to give the user an indication that there is XML content there, without showing all the content
definitiontableelement- Used for:
definitiontableelements or their specializations readonlynarrowtableelement- Used for: representing a very basic table whose structure and element contents cannot be changed
structureviewitemelement- Used for: showing specializations of
topicrefelements in the Outline view
Menu configuration elements
To define your own extra custom menus using the menuconfiguration element, the examples below show how every element will be rendered.
When there are menuitem elements defined in the behavior elements, but no menuconfiguration element is defined, the menu items will all be shown alphabetically sorted in one Custom menu.
extramenuelement- Description:
menuitemrefelement- Description: This element always has a
refattribute value that should refer to amenuitemwith the sameidattribute value which is defined in one of the behavior elements. menuseparatorelement- Configured as:
<menuseparator/> menuexpandgroupelement- Description: groups a number of
menuitemreformenuseparatorelements in a drop-down button or expandable menu (if themenuexpandgroupis nested inside anothermenuexpandgroup)
Tips about precedence of configuration rules in BehaviorConfig.xml
priority attribute, and the order of the rules in the BehaviorConfig.xml configuration file. The following applies:
- The more specific the XPath expression value is, the more precedence it will take. For example a rule, having
xpath="self::p[parent::section][parent::body]"will take precedence over a rule havingxpath="self::p". - A configuration rule in theBehaviorConfig.xml will override the out-of-the-box rule that has the same
xpath. However, an out-of-the-box rule having a more specificxpathstill takes precedence over a configured rule with a less specific XPath. - A configuration rule that has a higher
priorityattribute value will take precedence over a lowerpriorityrule, even when its XPath is less specific. Use apriorityvalue higher than 2 to make sure that your configuration takes precedence over every out-of-the-box defined behavior having a more specific XPath expression. You can also usepriorityvalues lower than 0, to let the out-of-the-box configuration always take precedence over your rules. Note that thepriorityattribute is optional, so first look at the result without having this attribute set. - If there are multiple rules in the configuration file having the same XPath and without having a
priorityattribute, the last rule in the file takes precedence. - If multiple rules apply, by default the behavior is merged: For example if the out-of-the-box specifies that the element should be rendered bold, and your configured rule says it should be rendered as italic (without specifying anything for the bold property), the element would be rendered as bold+italic. To avoid merging, you can set the
clearsamexpathbehaviortoyeson the rule taking precedence, and then only the properties explicitly set on that rule will be taken into account.
You can use the location attribute in the schema element, if the scopetoschemas child element of the behaviorscopegroup element is set, to make sure certain configuration rules are only applied when a user opens an XML document that adheres to a certain DTD or XML Schema. Make sure to put the common rules on top of the configuration file and the schema-dependent ones at the bottom, as the last rule in the file "wins" (if xpath and priority are the same).
Building up a configuration
We will give an example here on how you can build up a configuration. We created a specialized api2ref DTD, that contains a copy of the RWS apiref DTD that is supplied out of the box. In this api2ref DTD, all elements having api in their name have been renamed to api2 (for example: api2ref, api2function, api2description) . When you define a menuitem, make sure to put elements that need to be inserted in the inserttemplate on one line, to avoid extra whitespace characters.
- Configuration: No compiled schema yet
-
If you didn't configure your schema on the server, or did not compile it using the
IshDeploy Set-ISHFontoSchemaExperiencecommand, theapiref2XML document is rendered as follows: - Configuration: no configuration yet
-
When you don't have any configuration in BehaviorConfig.xml for
api2refyet, the following default configuration is used:<?xml version="1.0" encoding="utf-8"?> <behaviorconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BehaviorConfig.xsd" version="1.0"> </behaviorconfig> - Configuration: first configuration with basic rendering
-
When using the following configuration:
<?xml version="1.0" encoding="utf-8"?> <behaviorconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BehaviorConfig.xsd" version="1.0"> <behaviorscopegroup name="Common for all DTDs/schemas"> <behaviorgroup> <blockgenericicon xpath="self::*" icon="sort-alpha-asc" tooltipquery="./string(node-name(.))" priority="-5"> <label>Unconfigured element</label> </blockgenericicon> </behaviorgroup> </behaviorscopegroup> <behaviorscopegroup name="Api2ref DTD/schema specific configuration"> <scopetoschemas> <schema location="dita-sdl/1.3/schema/api2ref/xsd/api2ref.xsd"/> </scopetoschemas> <behaviorgroup name="Api2ref behavior"> <sheet xpath="self::api2ref"> <label>API2 Reference</label> </sheet> </behaviorgroup> </behaviorscopegroup> </behaviorconfig> - Configuration: configuration with somewhat improved rendering
-
When using the following configuration:
<?xml version="1.0" encoding="utf-8"?> <behaviorconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BehaviorConfig.xsd" version="1.0"> <behaviorscopegroup name="Common for all DTDs/schemas"> <behaviorgroup> <blockgenericicon xpath="self::*" icon="sort-alpha-asc" tooltipquery="./string(node-name(.))" priority="-5"> <label>Unconfigured element</label> </blockgenericicon> </behaviorgroup> </behaviorscopegroup> <behaviorscopegroup name="Api2ref DTD/schema specific configuration"> <scopetoschemas> <schema location="dita-sdl/1.3/schema/api2ref/xsd/api2ref.xsd"/> </scopetoschemas> <behaviorgroup name="Api2ref behavior"> <sheet xpath="self::api2ref"> <label>API2 Reference</label> </sheet> <block xpath="self::api2function" type="cannotbesplit-and-candirectlycontaintext"> <label>Function</label> </block> <block xpath="self::classname" type="cannotbesplit-and-candirectlycontaintext"> <label>Class Name</label> </block> <block xpath="self::classversion" type="cannotbesplit-and-candirectlycontaintext"> <label>Class Version</label> </block> <block xpath="self::functionname" type="cannotbesplit-and-candirectlycontaintext"> <label>Function Name</label> </block> <block xpath="self::api2desc" type="cannotbesplit-and-cannotdirectlycontaintext"> <label>Description</label> </block> </behaviorgroup> </behaviorscopegroup> </behaviorconfig> - Configuration: configuration with improved rendering and some menus
-
When using the following configuration:
<?xml version="1.0" encoding="utf-8"?> <behaviorconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BehaviorConfig.xsd" version="1.0"> <behaviorscopegroup name="Common for all DTDs/schemas"> <behaviorgroup> <blockgenericicon xpath="self::*" icon="sort-alpha-asc" tooltipquery="./string(node-name(.))" priority="-5"> <label>Unconfigured element</label> </blockgenericicon> </behaviorgroup> </behaviorscopegroup> <behaviorscopegroup name="Api2ref DTD/schema specific configuration"> <scopetoschemas> <schema location="dita-sdl/1.3/schema/api2ref/xsd/api2ref.xsd"/> </scopetoschemas> <behaviorgroup name="Api2ref behavior"> <sheet xpath="self::api2ref"> <label>API2 Reference</label> </sheet> <block xpath="self::api2function" type="cannotbesplit-and-candirectlycontaintext"> <label>Function</label> <contextualmenuitems> <contextualmenuitem> <label>Add Function Name</label> <inserttemplate><functionname/></inserttemplate> </contextualmenuitem> </contextualmenuitems> </block> <block xpath="self::classname" type="cannotbesplit-and-candirectlycontaintext"> <label>Class Name</label> </block> <block xpath="self::classversion" type="cannotbesplit-and-candirectlycontaintext"> <label>Class Version</label> </block> <block xpath="self::functionname" type="cannotbesplit-and-candirectlycontaintext"> <label>Function Name</label> <placeholdertext>Fill in a function name here</placeholdertext> <menuitems> <menuitem id="add-functionname"> <label>Add Function Name</label> <inserttemplate><functionname/></inserttemplate> </menuitem> </menuitems> </block> <block xpath="self::paramlist" type="cannotbesplit-and-cannotdirectlycontaintext" clearsamexpathbehavior="yes"> <label>Parameter list</label> <contextualmenuitems> <contextualmenuitem> <label>Add input parameter</label> <inserttemplate><paramStringIn><paramName/><paramDesc/></paramStringIn></inserttemplate> </contextualmenuitem> <contextualmenuitem> <label>Add output parameter</label> <inserttemplate><paramStringOut><paramName/><paramDesc/></paramStringOut></inserttemplate> </contextualmenuitem> </contextualmenuitems> <menuitems> <menuitem id="add-paramlist"> <label>Add Parameter list</label> <inserttemplate><paramlist/></inserttemplate> </menuitem> </menuitems> </block> <block xpath="self::remarks" type="cannotbesplit-and-candirectlycontaintext" clearsamexpathbehavior="yes"> <label>Remarks</label> <menuitems> <menuitem id="add-remarks"> <label>Add Remarks</label> <inserttemplate><remarks/></inserttemplate> </menuitem> </menuitems> </block> <block xpath="self::api2desc" type="cannotbesplit-and-cannotdirectlycontaintext"> <label>Description</label> </block> </behaviorgroup> </behaviorscopegroup> </behaviorconfig> - Configuration; Configuration with menu structure
-
When using the previous configuration extended with a
menuconfiguration:<?xml version="1.0" encoding="utf-8"?> <behaviorconfig xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="BehaviorConfig.xsd" version="1.0"> <behaviorscopegroup name="Common for all DTDs/schemas"> ... </behaviorscopegroup> <behaviorscopegroup name="Api2ref DTD/schema specific configuration"> ... </behaviorscopegroup> <menuconfiguration> <extramenu xpath="ancestor-or-self::apiref"> <label>Custom Api Reference</label> <description>Menus to insert API reference elements</description> <menuitemref ref="add-functionname" icon="code"/> <menuseparator/> <menuexpandgroup> <label>Advanced</label> <description>Choose one of the advanced elements</description> <menuitemref ref="add-paramlist"/> <menuseparator/> <menuitemref ref="add-remarks"/> </menuexpandgroup> </extramenu> </menuconfiguration> </behaviorconfig>
Sidebar configuration elements
To define your extra custom sidebars, use the sidebarconfiguration element.
Any extrasidebar element in the sidebarconfiguration is shown as an extra sidebar. It should have a label and optional description, which can be used to provide a tooltip.
url- Specifies the application URL. This attribute is mandatory.
position- Specifies the position of the custom sidebar
icon- Specifies the icon that will be visible next to the label
size-
Specifies the width of the sidebar for the first time the tab is opened. Possible values are
s,m(default), orl. The sidebar can be resized by the user and thesizeattribute is ignored after that to keep the size as set by the user. ishcondition-
Used with
ClientName, this attributes assigns custom sidebars to their clients in Collective Spaces. The possible values forClientNameare:DraftSpace,ReviewSpaceorCollectiveSpaces.
<sidebarconfiguration>
<extrasidebar id="custom-sidebar-example" ishcondition="ClientName=DraftSpace" url="#!#installtool:BASEURL#!#/#!#installtool:INFOSHARECSWEBAPPNAME#!#/Api/Try/ExtraSidebar/" icon="globe" size="l">
<label>Custom Sidebar</label>
<description>Custom Sidebar Example</description>
</extrasidebar>
</sidebarconfiguration>
Rendered as follows:
- Information visible inside the extra sidebar is rendered by a custom application specified in the
urlattribute value. Here you can see how an example application provided by Tridion Docs is used. - Initial sidebar size can be configured, but users can resize the sidebar to their liking. After changing the size of the sidebar new size is kept for user in the browser.
An application in the sidebar will get information about the selected document and the publication. To use that data, the application needs to listen to message event, the example below shows how to do that.
const postMessageHandler = (event) => {
if (event && event.data) {
if (event.data.type !== 'sdl-extension-sidebar') {
return;
}
console.log(event.data.payload);
}
}
window.addEventListener('message', postMessageHandler);
You need to use type property from the event data and check if that equals to sdl-extension-sidebar. This way you make sure that information comes from the right source, if you do not do that then you handle much more message events that can have data that aren't related to the sidebar configuration.
payload property from the event data to get information about selected topic and publication. The payload object has the following structure:
{
document: {
language,
languageCardId,
logicalCardId,
logicalId,
objectType,
revisionId,
version,
versionCardId,
xml,
},
publication: {
language,
logicalId,
version,
}
}
In the out-of-the-box BehaviorConfig.xml we provide an example, based on the explanation above, that is commented out. If you uncomment this example, you can see an extra Custom Sidebar in Draft Space that uses an Tridion Docs API endpoint to show which JSON content gets sent from Draft Space. The API endpoint uses the ExtraSidebar.html in the Web\Author\ASP\ folder to show the information sent.
Conref configuration elements
conrefconfiguration element:
<conrefconfiguration>
<element name="mytopic" baseelement="topic"/>
<element name="mysection"/>
<element name="mypara"/>
<element name="myul"/>
</conrefconfiguration>
You only need to specify your specialized elements, the regular DITA elements are working out-of-the-box.
The optional baseelement attribute is rarely needed. Its value should be set to topic only if the configured XML element is specialized from the DITA topic element or any of its specializations.