Content Type Definition

From Sense/Net 6.0 Wiki

Jump to: navigation, search

Content Type Definition (CTD) describes a Content Type. It is an XML file that contains a list of fields for the content. On the shot, you can see the GenericContent type, which, as its name would suggest, is a generic type for creating other types with inheritance. All the fields of an ancestor are inherited to the new type.

  • Before you read on, make sure that you are familiar with Sense/Net 6.0's Content Type System.

Sense/Net Content Repository stores the content type definitions and the contents created from them. Content type definitions are stored in the /Root/System/Schema/ContentTypes folder.


Contents

[edit] Benefits of Content Type Definitions

With the help of Content Type Defininons you can construct complex objects without any programming knowledge. By specifying the XML document and registering it as described in the Content Type installation guide working with your own custom objects has never been so easy. Content Type Definition describes and contains all the data that is to be stored by the desired object, their semantics and their way of display. A With CTD hierarchy you can control the storage model, fundamental business logic (e.g. semantic validation), and basic user interface (e.g. web form generation).

To define a CTD you have to create a Content Type Definition XML containing some mandatory and many optional tags.

[edit] CTD tags

  • ContentType
    • name attribute - unique name of the Content Type as it will be referenced within the system. Required.
    • handler attribute - name of the parent Content Type. It is suggested that all Content Types inherit from SenseNet.ContentRepository.GenericContent or any of its descendants. Required.
    • parentType attribute - name of the parent Content Type. Not required but it is suggested that all Content Types inherit from SenseNet.ContentRepository.GenericContent or any of its descendants.
    • xmlns - the XML namespace of the XML file. The value is http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition.
    • Title element - user friendly name of the Content Type. Multi language will be supported. Not required.
    • Description element - short functional description of the Content Type. Multi language will be supported. Not required.
  • Fields element - contains Field elements. Not required if it is empty.
  • Field element - defines a data element of the Content Type.
    • name attribute - the name of the Field. If there is a Field with this name already defined in the and types do not match, a collision will occur when registering the CTD. Otherwise if types are the same registration will be successfull. Field name is required and must be unique in the CTD. A field in the current CTD overrides an ancestor CTD’s field if their names are equal.
    • type attribute - the type of the Field (e.g. ShortText). Mandatory if handler attribute is not specified. Has to be a value from the List of Content Field Types.
    • handler attribute – If you develop a custom Field you can define it in this attribute with fully qualified class name. If handler attribute is defined the type attribute will be neglected.
    • Title element - user friendly name of the Field. Multi language will be supported. Not required.
    • Description element - short functional description of the Field. Multi language will be supported. Not required.
    • Bind element - specifies a binding to the storage model. Not required, default value is the name attribute of the parent Field element. See #CTDADVANCED
    • Configuration element - field specifying field properties depending on the type of the Field. Not required. (to be continued).

[edit] Example

The example below is the CTD for a Car, which is inherited from the generic type. The XML is pretty straightforward and speaks for itself. If you were to store the list of your company's Cars in a database, think again, and use an ECMS. The only thing you need is this CTD file (which you can copy-paste and modify) and you have dozens of services, including a GUI, search and enterprise level security, etc.

This Car Content Type Definition defines a Content Type with the follwoing properties:

  • Basic metadata
    • Name is Car
    • Parent is GenericContent
    • Handler is the default handler (SenseNet.ContentRepository.GenericContent)
  • Fields
    • Company - A text field, describing what kind of company produced the car
    • Model - A text field specifying the model of the car
    • Style - A list field specifying whether the car is a Sedan, Coupe, Cabrio, Roadster, SUV or Van.
    • StartingDate - A date field specifying when the car was bought.
    • Color - A color field specifying the color of the car.
    • EngineSize - A text field specifying engine size.
    • Power - A text field specifying car horsepower.
    • Price - A number field specifying car price in dollars.
    • Description - A longer text field describing other car characteristics.

The Content Type Definition Schema for the above defined Car is the following.

<ContentType name="Car" parentType="GenericContent" handler="SenseNet.ContentRepository.GenericContent"  xmlns="http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition">
  <Title>Car</Title>
  <Description>Car</Description>
  <Icon>Car</Icon>
  <Fields>
    <Field name="Company" type="ShortText">
      <Title>Company</Title>
      <Description>e.g. Mazda, Ferrari etc.</Description>
    </Field>
    <Field name="Model" type="ShortText">
      <Title>Model</Title>
      <Description>e.g. RX-8, F-40 etc.</Description>
    </Field>
    <Field name="Style" type="Choice">
      <Title>Style</Title>
      <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>
    <Field name="StartingDate" type="DateTime">
      <Title>Starting Date</Title>
      <Description>Starting Date</Description>
    </Field>
    <Field name="Color" type="Color">
      <Title>Colour</Title>
      <Description>Colour</Description>
    </Field>
    <Field name="EngineSize" type="ShortText">
      <Title>Engine Size</Title>
      <Description>Engine Size (litres)</Description>
    </Field>
    <Field name="Power" type="ShortText">
      <Title>Power in hp</Title>
      <Description>Power in hp</Description>
    </Field>
    <Field name="Price" type="Number">
      <Title>Base price</Title>
      <Description>Base price $</Description>
    </Field>
    <Field name="Description" type="LongText">
      <Title>Description</Title>
      <Description>Description</Description>
    </Field>
  </Fields>
</ContentType>

On this picture below you can see how this content type is presented in Content Explorer's user interface when you are about to create it (for example you are to enter a new car's data into the database).

[edit] In the trenches

Ok, now let's try to get a little deeper into it.

<ContentType name="Car" parentType="GenericContent" handler="SenseNet.ContentRepository.GenericContent"
 xmlns="http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition">
  • The content type definition starts with a "ContentType" tag.
  • The "name" attribute is required, and it has to be unique in the whole system. The available characters are [a-zA-Z_][0-9a-zA-Z_].
Important:
Type and Field names may no longer continue a period sign (.)
  • The "parentType" attribute is optional, it defines the content type from which this particular content type is derived. It is optional, but we suggest you to use this feature, because it has a few benefits first of all:
    • When you derive a content type from an ancestor content type and you later decide to alter the content type definitions by let's say adding a new field to every content type, it can be done simply by adding the particular field only to the parent content type. In this case every content type derived from it will inherit the modifications, so you have to do this only once instead of modifying any given content types one by one in the system.
  • The "handler" attribute is required, and a fully qualified name of an existing ContentHandler has to be set. If you do not want to add custom logic to the content type, you can use the built-in handler: SenseNet.ContentRepository.GenericContent.
  • The "xmlns" attribute is also compulsory. It defines the namespace of the CTD.
<Title>Car</Title>
<Description>Car</Description>
<Icon>Car</Icon>
  • The "Title" tag is an optional one. If you don't define a title, the title of the parent content type will be used. If the content type is not derived from any parent content type there will be no such field displayed.
  • The "Description" tag is also an optional one. If you don't give a description, the description of the parent content type will be used. If the content type is not derived from any parent content type there will be no such field displayed.
  • The "Icon" tag is also an optional one. The same rules apply as above.
  <Fields>
    <Field name="Make" type="ShortText">
      <Title>Make</Title>
      <Description>e.g. Mazda, Ferrari etc.</Description>
    </Field>
    <Field name="Model" type="ShortText">
      <Title>Model</Title>
      <Description>e.g. RX-8, F-40 etc.</Description>
    </Field>
    <Field name="Style" type="Choice">
      <Title>Style</Title>
      <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>
</Fields>
</ContentType>
  • "Field" tags must be enclosed in a"Fields" tag.
  • The "name" attribute of the "Field" tag is required, and it has to be unique in the whole system. The available characters you can use is [a-zA-Z_][0-9a-zA-Z_]
Important:
Type and Field names may no longer continue a period sign (.)
  • The "type" attribute is required if there is no field handler defined. A list of the available field types is available here.
  • The "handler" attribute is required if there is no field type defined. This attribute is he fully qualified name of an existing FieldHandler (as the example shows below).
<Field 
	name="Make1"
	handler="SenseNet.ContentRepository.Fields.ShortTextField">            <== equivalent: type="ShortText"
</Field>
  • The "Title" tag is an optional one, if you don't give a title, the title of the field from the parent content type will be used.
  • The "Description" tag is an optional one. Same rules apply as in case of the title.
  • The "Icon" tag is also an optional one. Same rules apply as in case of the title.
  • The "Configuration" tag is optional. It can define numerous settings for the content field's behaviour. (You can find more, specific information about these here). If there is no other configuration set the configuration of the parent type's same field will be in effect.
<Field name="InheritanceTest" type="Integer">
	<Configuration
		handler="ContentRepositoryTest.Schema.CustomFieldSetting">      <== changes default FieldSetting 
		<EvenOnly>true</EvenOnly>
	</Configuration>
</Field>

[edit] Schema for Content Type Definition

Here below you'll find a schema of Content Type Definition. With these schema we are trying to make you familiar with the usage of Content Type Definition.

<xs:schema targetNamespace="http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition"
			xmlns="http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition"
			xmlns:tns="http://schemas.sensenet.hu/SenseNet/ContentRepository/ContentTypeDefinition"
			xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="unqualified" elementFormDefault="qualified">
	<xs:element name="ContentType" type="ContentTypeDecl">
		<xs:annotation>
			<xs:documentation>
				Required attribute: @name, @handler. Subelement order: Title, Description, Icon, Fields
			</xs:documentation>
		</xs:annotation>
		<xs:unique name="UniqueContentName">
			<xs:selector xpath="."/>
			<xs:field xpath="@name"/>
		</xs:unique>
	</xs:element>
	<!-- -->
	<xs:complexType name="BaseDecl" abstract="true">
		<xs:sequence>
			<xs:element minOccurs="0" name="Title" type="xs:string" />
			<xs:element minOccurs="0" name="Description" type="xs:string" />
			<xs:element minOccurs="0" name="Icon" type="xs:string" />
		</xs:sequence>
		<xs:attribute name="name" type="TypeName" use="required" />
	</xs:complexType>
	<!-- -->
	<xs:complexType name="ContentTypeDecl">
		<xs:complexContent>
			<xs:extension base="BaseDecl">
				<xs:sequence>
					<xs:element minOccurs="0" name="Fields">
						<xs:complexType>
							<xs:sequence minOccurs="0" maxOccurs="unbounded">
								<xs:element minOccurs="0" name="Field" type="FieldDecl" />
							</xs:sequence>
						</xs:complexType>
						<xs:unique name="UniqueFieldName">
							<xs:selector xpath="tns:Field"/>
							<xs:field xpath="@name"/>
						</xs:unique>
					</xs:element>
				</xs:sequence>
				<xs:attribute name="handler" use="required" type="xs:string">
					<xs:annotation>
						<xs:documentation>
							Contains fully qualified class name of a content handler.
						</xs:documentation>
					</xs:annotation>
				</xs:attribute>
				<xs:attribute name="parentType" use="optional" type="xs:string">
					<xs:annotation>
						<xs:documentation>
							Contains an existing ContentType name.
						</xs:documentation>
					</xs:annotation>
				</xs:attribute>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="FieldDecl">
		<xs:annotation>
			<xs:documentation>
				Required attributes: @name, @type or @handler.
				Subelement order: Title, Description, Icon, Bind, Configuration, UI
			</xs:documentation>
		</xs:annotation>
		<xs:complexContent>
			<xs:extension base="BaseDecl">
				<xs:sequence>
					<xs:element name="Bind" type="BindDecl" minOccurs="0" maxOccurs="unbounded" />
					<xs:element name="Configuration" minOccurs="0">
						<xs:complexType mixed="true">
							<xs:sequence minOccurs="0" maxOccurs="unbounded">
								<xs:any namespace="##any" processContents="skip" />
							</xs:sequence>
							<xs:attribute name="handler" use="optional" type="xs:string">
								<xs:annotation>
									<xs:documentation>
										Contains fully qualified class name of a field handler configurator class (inherited from FieldSetting).
										The given class overrides the default configurator of Field.
									</xs:documentation>
								</xs:annotation>
							</xs:attribute>
						</xs:complexType>
					</xs:element>
					<xs:element name="UI" minOccurs="0">
						<xs:complexType mixed="true">
							<xs:sequence minOccurs="0" maxOccurs="unbounded">
								<xs:any namespace="##any" processContents="skip" />
							</xs:sequence>
						</xs:complexType>
					</xs:element>
				</xs:sequence>
				<xs:attribute name="type" use="optional" type="xs:string">
					<xs:annotation>
						<xs:documentation>
							Contains short name of a field handler.
						</xs:documentation>
					</xs:annotation>
				</xs:attribute>
				<xs:attribute name="handler" use="optional" type="xs:string">
					<xs:annotation>
						<xs:documentation>
							Contains fully qualified class name of a field handler. If @handler is specified, the @type will be neglected.
						</xs:documentation>
					</xs:annotation>
				</xs:attribute>
			</xs:extension>
		</xs:complexContent>
	</xs:complexType>
	<xs:complexType name="BindDecl">
		<xs:annotation>
			<xs:documentation>
				Specifies a binding to a property of the given ContentHandler. The count of Bind elements and their orders are stressful. See the documentation of concrete Field.
			</xs:documentation>
		</xs:annotation>
		<xs:attribute name="property" type="xs:string" use="required" />
	</xs:complexType>
	<xs:simpleType name="TypeName">
		<xs:restriction base="xs:string">
			<xs:pattern value="[a-zA-Z_][0-9a-zA-Z_]*"/>
		</xs:restriction>
	</xs:simpleType>
</xs:schema>

[edit] Related articles

Personal tools