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.

mapsheet element
Used for: map elements and their specializations
Configured as:
<mapsheet xpath="self::mymap">
  <label>Map</label>
</mapsheet>
Rendered as:
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.
sheet element
Used for: topic elements and their specializations
Configured as:
<sheet xpath="self::mytopic">
  <label>Topic</label>
  <defaulttextcontainer elementname="mybody" />
</sheet>
Rendered as:
Note that the mytopic 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.
sheetbody element
Used for: body elements or their specializations
Configured as:
<sheetbody xpath="self::mybody">
  <label>Body</label>
  <defaulttextcontainer elementname="myp" />
</sheetbody>
Rendered as:
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.
title element
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>
Rendered as:
Note that the text "Inside the box" is shown as a title, in a bigger font.
block element
Used for: paragraph-like elements
Configured as:
<block xpath="self::mycontext" 
    type="cannotbesplit-and-candirectlycontaintext">
  <label>Context</label>
  <defaulttextcontainer elementname="myp" />
  <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.
We set the defaulttextcontainer to myp, so that when the user types enter it will wrap both text lines inside mycontext into a myp element, so the texts will end up on 2 lines in the final publication.
Rendered as:
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.
inline element
Used for: phrase elements (ph) or their specializations
Configured as:
<inline xpath="self::mytm" enddelimiter="™">
  <label>Trademark</label>
</inline>
Rendered as:
Note that the sentence just continues around the TM symbol, which is configured as inline
highlighting element
Used for: highlighting elements
Configured as:
<highlighting xpath="self::myb" bold="yes">
  <label>Bold text</label>
</highlighting>
Rendered as:
list element
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>
Rendered as:
image element
Used for: imageelements or their specializations
Configured as:
<image xpath="self::myimage">
  <label>Image</label>
  <description>Image</description>
</image>
Rendered as:
blockgenericicon element
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
Configured as:
<blockgenericicon xpath="self::myobject" 
     icon="external-link">
  <label>Object</label>
</blockgenericicon>
Rendered as:
inlinegenericicon element
Used for: showing an inline placeholder to give the user an indication that there is XML content there, without showing all the content
Configured as:
<inlinegenericicon xpath="self::mydata" 
     icon="properties">
  <label>Data</label>
</inlinegenericicon>
Rendered as: the same as the blockgenericicon, but can appear inline with the text.
definitiontable element
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>
Rendered as:
readonlynarrowtable element
Used for: representing a very basic table whose 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>
Rendered as:
structureviewitem element
Used for: showing specializations of topicref elements in the Outline view
Configured as:
<structureviewitem xpath="self::mymap" 
icon="folder-open-o" priority="3"/>
Rendered as:
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.

extramenu element
Description:
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.
Configured as:
<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>
The configuration will render an extra Custom API Reference menu if you are in an API Reference document.
Rendered as:
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.
menuitemref element
Description: This 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.
Configured as:
<menuitemref ref="add-functionname" icon="code"/>
Rendered as: a button or menu item with the label of the referenced menuitem. See extramenu example.
menuseparator element
Configured as:
<menuseparator/>
Rendered as: a vertical line between buttons or a horizontal line between menu items. See extramenu example .
menuexpandgroup element
Description: groups a number of menuitemref or menuseparator elements in a drop-down button or expandable menu (if the menuexpandgroup is nested inside another menuexpandgroup)
Configured as:
<menuexpandgroup>
  <label>Advanced</label>
  <description>Choose one of the advanced elements</description>
  <menuitemref ref="add-paramlist"/>
  <menuseparator/>
  <menuitemref ref="add-remarks"/>
 </menuexpandgroup>
Rendered as: See extramenu example.

Tips about precedence of configuration rules in 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 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-ISHFontoSchemaExperience command, the apiref2 XML document is rendered as follows:
Configuration: no configuration yet
When 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.
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>
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: 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: 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>
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; 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 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.

You can use the following attributes:
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), or l. The sidebar can be resized by the user and the size attribute 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 for ClientName are: DraftSpace, ReviewSpace or CollectiveSpaces.
Configuration example:
<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:

Note that
  • Information visible inside the extra sidebar is rendered by a custom application specified in theurl attribute 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.

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

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

To define the list of elements the user is able to conref, have a look at the following example for the 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.