Richard Dias has already covered this topic before on his blog but I felt that the issue could do with even a few more examples of how to get custom datatypes working in sitecore.
I’ve created a firstname/secondname textfield combo which stores the data as attributes on an xml element. This is how sitecore stores data internally for situations like these, a good example been the image field. Do try switching on raw mode and having a look at how sitecore stores the various data types.
Installing the datatype is as defined in steps 10 and 11 of the SDN article, firstly you add the following to <controlSources> in web.config (don’t forget to change the namespace and assembly details):
<source mode=”on” namespace=”Project.Namespace” assembly=”Project.Assembly” prefix=”ExampleCustomDatatype”/>
And then you create a “template field type” item representing your field in “/system/field types” on the core database. The “template field type” template has 3 fields, the first 2 been the assembly and class of the control and the third requires the prefix defined in the web.config, followed by :, followed by the class name. In this case it would be ExampleCustomDatatype:ExampleCustomDatatype.
Finally below is the code that I’m using in this example:
using System;
using System.Web.UI;
using Sitecore.Shell.Applications.ContentEditor;
using Sitecore.Web.UI.HtmlControls;
namespace Project.Namespace
{
public class ExampleCustomDatatype : Input
{
private XmlValue XmlValueStore
{
get
{
XmlValue viewStateProperty = base.GetViewStateProperty("XmlValueStore", null) as XmlValue;
if (viewStateProperty == null)
{
viewStateProperty = new XmlValue(string.Empty, "ExampleCustomDatatype");
this.XmlValueStore = viewStateProperty;
}
return viewStateProperty;
}
set
{
base.SetViewStateProperty("XmlValueStore", value, null);
}
}
public override string Value
{
get
{
return XmlValueStore.ToString();
}
set
{
XmlValueStore = new XmlValue(value, "ExampleCustomDatatype");
}
}
private string FirstName
{
get
{
return XmlValueStore.GetAttribute("firstname");
}
set
{
XmlValueStore.SetAttribute("firstname", value);
}
}
private string SecondName
{
get
{
return XmlValueStore.GetAttribute("secondname");
}
set
{
XmlValueStore.SetAttribute("secondname", value);
}
}
protected override void OnLoad(EventArgs e)
{
if (!Sitecore.Context.ClientPage.IsEvent)
{
Text firstNameField = new Text {ID = GetID("firstName"), Value = FirstName};
this.Controls.Add(firstNameField);
this.Controls.Add(new LiteralControl(Sitecore.Resources.Images.GetSpacer(0x18, 16)));
Text secondNameField = new Text {ID = GetID("secondName"), Value = SecondName};
this.Controls.Add(secondNameField);
}
else
{
Text firstNameField = FindControl(GetID("firstName")) as Text;
Text secondNameField = FindControl(GetID("secondName")) as Text;
if (firstNameField != null)
{
if (FirstName != firstNameField.Value)
{
this.TrackModified = true;
this.SetModified();
}
FirstName = firstNameField.Value;
}
if (secondNameField != null)
{
if (SecondName != secondNameField.Value)
{
this.TrackModified = true;
this.SetModified();
}
SecondName = secondNameField.Value;
}
}
base.OnLoad(e);
}
}
}
Once all is said and done you can add the new field type to a template and try editing in an item. You should see two plain text fields and when you enter say “Steve” into the first and “Green” into the second you will see the following in raw mode:
<ExampleCustomDatatype firstname=”Steve” secondname=”Green” />
Finally you can pull the content out in just the same way you would with any other field that stores data as attributes in an xml element:
<xsl:value-of select=”sc:fld(‘fieldname’,.,’firstname’)”/>
<xsl:value-of select=”sc:fld(‘fieldname’,.,’secondname’)”/>