Please help us by completing this survey

Go to survey
Documentation

Docs / Development / Content Type Definition

Content Type Definition

A Content Type Definition is an xml-format configuration file for defining Content Types. The xml configuration (CTD) holds information about

The Content Type Definition xml of a Content Type can be edited by editing the Content Type in Content Explorer (see How to create a Content Type for details).

Default template

This is the default template with the most common options:

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="" parentType="GenericContent" handler="SenseNet.ContentRepository.GenericContent" xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName></DisplayName>
  <Description></Description>
  <Icon>Content</Icon>
  <Preview>false</Preview>
  <AllowIndexing>True</AllowIndexing>
  <AllowIncrementalNaming>true</AllowIncrementalNaming>
  <AllowedChildTypes>ContentTypeName1,ContentTypeName2</AllowedChildTypes>
  <Fields>
    <Field name="ShortTextField" type="ShortText">
      <DisplayName>ShortTextField</DisplayName>
      <Description></Description>
      <Configuration>
        <MaxLength>100</MaxLength>
        <MinLength>0</MinLength>
        <Regex>[a-zA-Z0-9]*$</Regex>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="LongTextField" type="LongText">
      <DisplayName>LongTextField</DisplayName>
      <Description></Description>
      <Configuration>
        <MaxLength>100</MaxLength>
        <MinLength>0</MinLength>
        <TextType>LongText|RichText|AdvancedRichText</TextType>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="NumberField" type="Number">
      <DisplayName>NumberField</DisplayName>
      <Description></Description>
      <Configuration>
        <MinValue>0</MinValue>
        <MaxValue>100.5</MaxValue>
        <Digits>2</Digits>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="IntegerField" type="Integer">
      <DisplayName>IntegerField</DisplayName>
      <Description></Description>
      <Configuration>
        <MinValue>0</MinValue>
        <MaxValue>100</MaxValue>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="BooleanField" type="Boolean">
      <DisplayName>BooleanField</DisplayName>
      <Description></Description>
      <Configuration>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="ChoiceField" type="Choice">
      <DisplayName>ChoiceField</DisplayName>
      <Description></Description>
      <Configuration>
        <AllowMultiple>false</AllowMultiple>
        <AllowExtraValue>false</AllowExtraValue>
        <Options>
          <Option selected="true">1</Option>
          <Option>2</Option>
        </Options>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="DateTimeField" type="DateTime">
      <DisplayName>DateTimeField</DisplayName>
      <Description></Description>
      <Configuration>
        <DateTimeMode>DateAndTime</DateTimeMode>
        <Precision>Second</Precision>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="ReferenceField" type="Reference">
      <DisplayName>ReferenceField</DisplayName>
      <Description></Description>
      <Configuration>
        <AllowMultiple>true</AllowMultiple>
        <AllowedTypes>
          <Type>Type1</Type>
          <Type>Type2</Type>
        </AllowedTypes>
        <SelectionRoot>
          <Path>/Root/Path1</Path>
          <Path>/Root/Path2</Path>
        </SelectionRoot>
        <DefaultValue>/Root/Path1,/Root/Path2</DefaultValue>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
    <Field name="BinaryField" type="Binary">
      <DisplayName>BinaryField</DisplayName>
      <Description></Description>
      <Configuration>
        <IsText>true</IsText>
        <ReadOnly>false</ReadOnly>
        <Compulsory>false</Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse>Show|Hide|Advanced</VisibleBrowse>
        <VisibleEdit>Show|Hide|Advanced</VisibleEdit>
        <VisibleNew>Show|Hide|Advanced</VisibleNew>
      </Configuration>
    </Field>
  </Fields>
</ContentType>

Please note that in case of a Binary field the Compulsory configuration option currently does not work.

Below you can see a fully featured skeleton of a Content Type Definition xml:

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="" handler="" parentType="" xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName></DisplayName>
  <Description></Description>
  <Icon></Icon>
  <Preview></Preview>
  <AllowIndexing></AllowIndexing>
  <AppInfo></AppInfo>
  <AllowIncrementalNaming></AllowIncrementalNaming>
  <AllowedChildTypes></AllowedChildTypes>
  <Fields>
    <Field name="" type="">
      <DisplayName></DisplayName>
      <Description></Description>
      <AppInfo></AppInfo>
      <Bind property="" />
      <Indexing>
         <Mode></Mode>
         <Store></Store>
         <TermVector></TermVector>
         <Analyzer></Analyzer>
         <IndexHandler></IndexHandler>
      </Indexing>
      <Configuration>
        <ReadOnly></ReadOnly>
        <Compulsory></Compulsory>
        <DefaultValue></DefaultValue>
        <VisibleBrowse></VisibleBrowse>
        <VisibleEdit></VisibleEdit>
        <VisibleNew></VisibleNew>
        <FieldIndex></FieldIndex>
        <ControlHint></ControlHint>
      </Configuration>
    </Field>
  </Fields>
</ContentType>

General structure

The following elements make up the general structure of the xml:

Field definition

The following elements build up the field definition:

Content Type inheritance

Content Types are organized into hierarchy according to inheritance. Any Content Type may inherit from another one. The topmost Content Type in the inheritance hierarchy is the GenericContent (with handler SenseNet.ContentRepository.GenericContent), every Content Type must inherit from this, or any of its descendant. When a child Content Type is inherited from a parent Content Type it means that the child Content Type contains all the Fields of the parent, even if they are not defined in the child CTD (see Field inheritance) - and also they share common implemented logic.

Warning! The child Content Type must use the parent's handler, or use a custom content handler derived from it. The child cannot use *SenseNet.ContentRepository.GenericContent* unless the parent also uses that as the handler.

Field inheritance

A Content Type inherits its fields from its parent Content Type (defined byt he parentType attribute). This means that only additional fields have to be defined in the type’s CTD. The inherited fields apply to the Content Type as defined on the parent type, but may also be overridden. The following apply to field inheritance:

Examples

Simple example

Below you can see an extract of the Car Content Type Definition:

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="Car" parentType="ListItem" handler="SenseNet.ContentRepository.GenericContent" 
xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>Car</DisplayName>
  <Description>Car is a leaf content type to demonstrate the ECMS features of sensenet</Description>
  <Icon>Car</Icon>
  <Fields>
    <Field name='Make' type='ShortText'>
      <DisplayName>Make</DisplayName>
      <Description>e.g. Mazda, Ferrari etc.</Description>
    </Field>
    <Field name='Model' type='ShortText'>
      <DisplayName>Model</DisplayName>
      <Description>e.g. RX-8, F-40 etc.</Description>
    </Field>
    <Field name='Style' type='Choice'>
      <DisplayName>Style</DisplayName>
      <Description>Select one</Description>
      <Configuration>
        <AllowMultiple>false</AllowMultiple>
        <AllowExtraValue>true</AllowExtraValue>
        <Options>
          <Option selected='true'>Sedan</Option>
          <Option>Coupe</Option>
          <Option>Cabrio</Option>
          <Option>Roadster</Option>
          <Option>SUV</Option>
          <Option>Van</Option>
        </Options>
      </Configuration>
    </Field>  
  </Fields>
</ContentType>

The above configuration defines a Content Type that is inherited from the ListItem type and defines two ShortText Fields and a Choice Field.

Example for field inheritance

The following CTD defines a simple type:

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="MyType" parentType="GenericContent" handler="SenseNet.ContentRepository.MyTypeHandler" 
xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>My type</DisplayName>
  <Description>My base type</Description>
  <Icon>Content</Icon>
  <Fields>
    <Field name='MyField' type='ShortText'>
      <DisplayName>My field</DisplayName>
      <Description>My field description</Description>
      <Configuration>
        <MaxLength>10</MaxLength>
      </Configuration>
    </Field>
  </Fields>
</ContentType>

Extending base Content Type field set

This second CTD derives from the above one and defines an additional Field.

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="MyDerivedType" parentType="MyType" handler="SenseNet.ContentRepository.MyTypeHandler" 
xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>My derived type</DisplayName>
  <Description>My derived type</Description>
  <Icon>Content</Icon>
  <Fields>
    <Field name='MyOtherField' type='ShortText'>
      <DisplayName>My other field</DisplayName>
      <Description>My other field description</Description>
    </Field>
  </Fields>
</ContentType>

The following table sums up field sets of the two types:

MyType MyDerivedType
MyField MyField
  MyOtherField

Please note that MyDerivedType uses its parent’s handler to use the same implemented content handler logic. This is the correct setting if the derived type does not have its own custom handler.

Overriding a field of base Content Type

The following definition of MyDerivedType overrides MyField.

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="MyDerivedType" parentType="MyType" handler="SenseNet.ContentRepository.MyTypeHandler" 
xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>My derived type</DisplayName>
  <Description>My derived type</Description>
  <Icon>Content</Icon>
  <Fields>
    <Field name='MyField' type='ShortText'>
      <DisplayName>My field overridden</DisplayName>
      <Description>My field description</Description>
      <Configuration>
        <MaxLength>15</MaxLength>
      </Configuration>
    </Field>
    <Field name='MyOtherField' type='ShortText'>
      <DisplayName>My other field</DisplayName>
      <Description>My other field description</Description>
    </Field>
  </Fields>
</ContentType>

The following table sums up field sets of the two types:

MyType MyDerivedType
MyField (DisplayName=’My field’, MaxLength=10) MyField (DisplayName=’My field overridden’, MaxLength=15)
  MyOtherField

Please note that MyDerivedType uses its parent’s handler to use the same implemented content handler logic. This is the correct setting if the derived type does not have its own custom handler.

Example for CTD with composite field

The CTD below shows you how to define a field that is built up of two other fields. Note the Bind element.

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="MyType" parentType="GenericContent" handler="SenseNet.ContentRepository.GenericContent" 
xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>My type</DisplayName>
  <Description>My base type</Description>
  <Icon>Content</Icon>
  <Fields>
    <Field name="ImageRef" type="Reference">
      <DisplayName>Image content</DisplayName>
    </Field>
    <Field name="ImageData" type="Binary">
      <DisplayName>Image binarydata</DisplayName>
    </Field>
    <Field name="Image" type="Image">
      <DisplayName>Composite image</DisplayName>
      <Bind property='ImageRef' />
      <Bind property='ImageData' />
    </Field>    
  </Fields>
</ContentType>

The above defined Image field is a composite field that references ImageRef and ImageData fields. The type of the field is Image Field - which has a custom implementation that handles the corresponding logic: an Image is either persisted to the Content Repository as a separate content (in this case the image content is referenced via a Reference Field) or it is part of the content as a binary (in this case the image is a binary saved to a Binary Field on the content).

Example for Default value setting with JScript.NET

It is possible to set a default value for fields, and even use dynamically executed code which will be evaluated on the fly. You can use a variant of JavaScript for this purpose which is called JScript.NET - which is a JavaScript runtime on top of the .NET Framework. Expressions that you define this way will be evaluated in runtime on the server side.

To use jScripts in CTDs you have to write your code between [Script:jScript] and [/Script] tags. You can use more than one functions in a DefaultValue tag, the appropriate script parts will be evaluated and concatenated.

The following example is an excerpt from the Memo Content Type. The Date Field here is configured to include the current time as the default value. This means that when a new Memo Content is created the Date Field will always show the current date - when the Date Field is visible. If the Date Field is not visible in the Content View this setting does not affect the value of the Field.

<?xml version="1.0" encoding="utf-8"?>
<ContentType name="Memo" parentType="ListItem" handler="SenseNet.ContentRepository.GenericContent" xmlns="http://schemas.sensenet.com/SenseNet/ContentRepository/ContentTypeDefinition">
  <DisplayName>Memo</DisplayName>
  <Description>A content type for short memos or posts on a subject</Description>
  <Icon>Document</Icon>
  <Fields>
    <Field name="Date" type="DateTime">
      <DisplayName>Date</DisplayName>
      <Description>Please set the due date of the memo. Date format: '2010.09.17', time format: '14:30:00'</Description>
      <Configuration>
        <DateTimeMode>DateAndTime</DateTimeMode>
        <DefaultValue>[Script:jScript] DateTime.Now; [/Script]</DefaultValue>
      </Configuration>
    </Field>
  </Fields>
</ContentType>

This next CTD source-fragment shows another example for using jScript functions for default values:

<DefaultValue>12[Script:jScript]"apple".IndexOf("l")+8[/Script]8[Script:jScript]"pear".IndexOf("a")+2[/Script]85</DefaultValue>

The result will be 12118485, because the first script returns 11 and the second 4. These are concatenated to the static values.

Is something missing? See something that needs fixing? Propose a change here.