Documentation Center

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.

Element nameA .. element configured as ..is rendered as ..
mapsheetA mapsheet element, which is typically used for map elements and their specializations, configured as
<mapsheet xpath="self::mymap">
  <label>Map</label>
</mapsheet>

Note that the DITA map element is shown as a separate sheet of paper, but the topicref elements are not rendered in the sheet. They are only rendered in the Outline pane.

sheetA sheet element, which is typically used for topic elements and their specializations, configured as
<sheet xpath="self::mytopic">
  <label>Topic</label>
</sheet>

Note that the topic element is shown as a separate sheet of paper that also shows the sub-elements of the topic element, if those elements are configured properly.

sheetbodyA sheetbody element, which is typically used for body elements or their specializations, configured as
<sheetbody xpath="self::mybody">
  <label>Body</label>
</sheetbody>

Note that a sheetbody does not have any visual representation. As it is most of the time only used for grouping elements together, there is no need to show it. If you do want to show it, you can configure the body element as block.

titleA title element, which is typically used for title elements on any level, configured as
<title xpath="self::mytitle[parent::mytopic]" 
    fontvariation="document-title">
  <label>Title</label>
  <placeholdertext>Type the title</placeholdertext>
</title>

Note that the text "Inside the box" is shown as a title, in a bigger font.

blockA block element, which is typically used for paragraph-like elements, configured as
<block xpath="self::mycontext" 
    type="cannotbesplit-and-candirectlycontaintext">
  <label>Context</label>
  <placeholdertext>Type the context</placeholdertext>
</block>
Choose the correct value for the type attribute based on:
  • whether or not you want users to be able to split the current element and create the same element by pressing Enter.
  • whether the element itself can contain text or not.

In this example, we set the type in the above configuration to cannotbesplit-and-candirectlycontaintext because our schema only allows one mycontext element and the element can directly contain text, not only sub-elements.

.

Note that depending on the type attribute value you use on the block element, you might get a label before or on top of the text, and potentially a border around it.

inlineAn inline element, which is typically used for phrase elements (ph) or their specializations, configured as
<inline xpath="self::mytm" enddelimiter="™">
  <label>Trademark</label>
</inline>

Note that the sentence just continues around the TM symbol, which is configured as inline

highlightingA highlighting element, which is typically used for inline highlighting elements, configured as
<highlighting xpath="self::myb" bold="yes">
  <label>Bold text</label>
</highlighting>
listA list element, which is typically used for list elements and their items, configured as
<list xpath="self::myul">
  <label>Buletted list</label>
  <items xpath="self::myli" type="bullet" 
      elementname="myli">
    <label>Item</label>
  </items>
</list>
imageAn image element, which is typically used for image elements or their specializations, configured as
<image xpath="self::myimage">
  <label>Image</label>
  <description>Image</description>
</image>
blockgenericiconA blockgenericicon element, which is typically used to show a placeholder on its own line to give the user an indication that there is XML contents there without showing the entire contents, configured as
<blockgenericicon xpath="self::myobject" 
     icon="external-link">
  <label>Object</label>
</blockgenericicon>
inlinegenericiconA inlinegenericicon element, which is typically used to show an inline placeholder to give the user an indication that there is XML content there without showing the entire contents, configured as
<inlinegenericicon xpath="self::mydata" 
     icon="properties">
  <label>Data</label>
</inlinegenericicon>
Is rendered the same as the blockgenericicon, but can appear in line with the text.
definitiontableA definitiontable element, which is typically used for definitiontable elements or their specializations, configured as
<definitiontable xpath="self::mydl" borders="yes">
  <label>Definition Table</label>
  <rows elementname="mydlentry">
    <label>Row</label>
    <term elementname="mydt">
      <label>Term</label>
      <placeholdertext>Type the term
      </placeholdertext>
    </term>
    <definitions elementname="mydd">
      <label>Definitions</label>
      <placeholdertext>Type the definitions
      </placeholdertext>
    </definitions>
  </rows>
</definitiontable>
readonlynarrowtableA readonlynarrowtable element, which is typically used to represent a very basic table of which the structure and element contents cannot be changed, configured as
<readonlynarrowtable xpath="self::specialtable" 
   borders="yes" headerbackgroundcolor="grey" 
   rowbackgroundcolor="white">
    <label>Special Table</label>
    <header elementname="header">
        <label>Header</label>
        <cell elementname="col1">
            <label>Column1</label>
            <placeholdertext>Please fill in a label 
            for this column</placeholdertext>
        </cell>
        <cell elementname="col2">
            <label>Column2</label>
            <placeholdertext>Please fill in a label 
            for this column</placeholdertext>
        </cell>
        <cell elementname="col3">
            <label>Column3</label>
            <placeholdertext>Please fill in a label 
            for this column</placeholdertext>
        </cell>
    </header>    
    <rows elementname="row">
        <label>Row</label>
        <cell elementname="col1">
            <label>Column1</label>
            <placeholdertext>Please fill in a value 
            for this column</placeholdertext>
        </cell>
        <cell elementname="col2">
            <label>Column2</label>
            <placeholdertext>Please fill in a value 
            for this column</placeholdertext>
        </cell>
        <cell elementname="col3">
            <label>Column3</label>
            <placeholdertext>Please fill in a value 
            for this column</placeholdertext>
        </cell>
    </rows>
</readonlynarrowtable>
structureviewitemA structureviewitem element can be used to show specializations of topicref elements in the Outline view. A configuration looks like the following:
<structureviewitem xpath="self::mymap" 
icon="folder-open-o" priority="3"/>

Note that the DITA map and topics are shown in the Outline view. For topic elements or their specialization of topic you probably don't need any configuration, but for maps elements, you might.

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.

Element nameA .. element configured as ..is rendered as ..
menuconfiguration

extramenu

Any extramenu element in the menuconfiguration will be shown as an extra menu. It should have a label and optional description (which can be used to provide a tooltip), also can contain any number of menuitemref, menuseparator, and menuexpandgroup elements.

You can use the xpath attribute value to limit when the extra menu is available.

The configuration
<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>
will render an extra Custom API Reference menu if you are in an API Reference document.
Note that
  • The API Reference menu is also still visible as it belongs to the OOB menu configuration and currently there is no way to adapt anything in the OOB menu configuration.
  • The vertical separator is present between the Add Function Name and Advanced buttons as well, but it is hardly visible now that the pull-down menu is open.
menuitemrefA menuitemref element, always has a ref attribute value that should refer to a menuitem with the same id attribute value which is defined in one of the behavior elements.
The configuration
<menuitemref ref="add-functionname"
 icon="code"/>
will show a button or menu item with the label of the referenced menuitem.
See extramenu example
menuseparatorA menuseparator element, configured as
<menuseparator/>
is rendered as a vertical line between buttons or a horizontal line between menu items.
See extramenu example
menuexpandgroupA menuexpandgroup element groups a number of menuitemref or menuseparator elements in a drop-down button or expandable menu (if the menuexpandgroup is nested inside another menuexpandgroup)
<menuexpandgroup>
  <label>Advanced</label>
  <description>Choose one of the advanced elements</description>
  <menuitemref ref="add-paramlist"/>
  <menuseparator/>
  <menuitemref ref="add-remarks"/>
 </menuexpandgroup>
See extramenu example

Tips on configuration order, priority and clearsamexpathbehavior in the BehaviorConfig.xml

Multiple configuration elements (let's call them rules) might apply to the same XML element in your document. The behavior you will see in Collective Spaces depends on the rule or rules that are taken into account. Which rule takes precedence depends on its XPath expression, the value of its 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 having xpath="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 specific xpath still takes precedence over a configured rule with a less specific XPath.
  • A configuration rule that has a higher priority attribute value will take precedence over a lower priority rule, even when its XPath is less specific. Use a priority value 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 use priority values lower than 0, to let the out-of-the-box configuration always take precedence over your rules. Note that the priority attribute 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 priority attribute, 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 clearsamexpathbehavior to yes on 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 SDL 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.
ConfigurationDescription
No compiled schema yetWhen you didn't configure your schema on the server, or did not compile it using the IshDeploy Set-ISHFontoSchemaExperience command, the apiref2 XML document is rendered as follows:
No configuration yetWhen you don't have any configuration in BehaviorConfig.xml for api2ref yet, 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>
The apiref2 XML document is rendered as:

Note that the XML document is not rendered in the sheet view at all.

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>
the api2ref XML document is rendered as:

Note that the api2ref document is now shown as a sheet, but since we don't have configuration for api2function and api2description yet, they are shown as Unconfigured Element, which is the fallback rule we defined in configuration for all elements that are not configured yet (neither in the out-of-the-box configuration, nor in the BehaviorConfig.xml).

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>
the api2ref XML document is rendered as:

Note that more elements are already shown properly, although we did not configure them. Since we have the regular apiref elements defined out of the box, and the elements purpose, paramlist, paramStringIn and others are defined in that schema as well, these elements are also rendered already.

Configuration with improved rendering and some menu's
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>
the api2ref XML document is rendered as:

When there are menuitem elements defined in the configuration, but no menuconfiguration element is defined, the menu items will all be shown alphabetically sorted in one Custom menu.

Note that the Custom menu is now visible, and that the Add Function Name, Add Parameter list and Add Remarks top menus are available. Also notice that there is an Add Function Name context menu.

In the configuration, use the clearsamexpathbehavior="yes" to override the out-of-the-box behavior completely.

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>
the api2ref XML document is rendered as:

The ref attribute value of the menuitemref element should match the id attribute value of a menuitem element which is defined in one of the behavior elements.

Note that the optional xpath="ancestor-or-self::apiref" makes sure the extra menu is only shown when the user is positioned in an API Reference document.

Sidebar configuration elements

To define your own extra custom sidebars using the sidebarconfiguration element, the examples below show how every element will be rendered.

Element nameA .. element configured as ..is rendered as ..
sidebarconfiguration

extrasidebar

Any extrasidebar element in the sidebarconfiguration will be shown as an extra sidebar. It should have a label and optional description (which can be used to provide a tooltip).

You can use such attributes:
  • url attribute to specify the application URL. This attribute is mandatory.
  • position attribute to specify the position of custom sidebar
  • icon attribute to specify the icon that will be visible next to the label
  • size attribute to specify the width of the sidebar while the tab is opened. You can choose from s, m(default), l.
The configuration
<sidebarconfiguration>
  <extrasidebar id="my-sidebar" url="https://domain.com" icon="globe" position="1" size="l">
    <label>My Sidebar</label>
    <description>Description of the sidebar</description>
  </extrasidebar>
</sidebarconfiguration>
Note that
  • Information visible inside of extra sidebar is rendered by a custom application specified in url attribute value

An application in the sidebar will get information about selected document and 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 can be sure that information comes from the right source, if you don't do that then you handle much more message events that can have data that aren't related to the sidebar configuration.

Use a 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,
  }
}