Nibble

Storing parseable xml data in a datatype

As a follow up on the creating custom umbraco datatypes post I’ll show how to store parseable xml data in a datatype.

By default all propertry values get saved inside a cdata section(in the /data/umbraco.config file, wich has all published content).

Like in this example, a property with the alias test will look like this.

<data alias=”test”><![CDATA[1051;1052;1054]]></data>

But in some cases you would want to override this behavior, especially when you want to store xlm data.

Like the related links datatype in umbraco v4. This will store it’s links as child nodes of the data node.

<data alias=”links”>
        <links>
          <link title=”Same page” link=”http://www.google.com” type=”external” newwindow=”1″ />
          <link title=”Other page” link=”1051″ type=”internal” newwindow=”0″ />
        </links>
</data>

To do this the first step is to create a new class that inherits from umbraco.cms.businesslogic.datatype.DefaultData and overrides the ToXMl method.

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml;
 
namespace umbraco.editorControls.relatedlinks
{
    public class RelatedLinksData : umbraco.cms.businesslogic.datatype.DefaultData
    {
        public RelatedLinksData(umbraco.cms.businesslogic.datatype.BaseDataType DataType) : base(DataType) { }
 
        public override System.Xml.XmlNode ToXMl(System.Xml.XmlDocument data)
        {
            if (this.Value != null) {
                XmlDocument xd = new XmlDocument();
                xd.LoadXml(this.Value.ToString());
                return data.ImportNode(xd.DocumentElement, true);
            } else {
                return base.ToXMl(data);
            }
        }
 
    }
}

 

Final step is to alter the class that implements the umbraco.interfaces.IDataType interface (the one with the guid) so that the new class is used instead of the default one. So just change

public override umbraco.interfaces.IData Data
        {
            get
            {
                if (_baseData == null)
                    _baseData = new umbraco.cms.businesslogic.datatype.DefaultData(this);
                return _baseData;
            }
        }

   

To (depending on how the class is named, in this case it’s RelatedLinksData)

public override umbraco.interfaces.IData Data
        {
            get
            {
                if (_baseData == null)
                    _baseData = new RelatedLinksData(this);
                return _baseData;
            }
        }

6 Comments so far

  1. Adam on November 19th, 2008

    Thanks Tim!

    I have a lot of ideas on how to use this - I think it could be really, really useful!

    Adz

  2. Jesper Ordrup on November 21st, 2008

    Very clever. Highly usefull.

  3. Peter on March 13th, 2009

    Very useful indeed. Any idea how this works with the search in the Umbraco Utilities package? My guess is search results would include xml markup?

  4. Tim Geyssens on March 13th, 2009

    @Peter, I think the links won’t show up in the search results. The search would need to be updated to include the link nodes.

  5. Bex on September 7th, 2010

    @Tim

    How do you implement this this with your revisited version of creating custom umbraco datatypes. This version doesn’t have a class that implements the umbraco.interfaces.IDataType interface so I am unsure where I need to put the bits?

    Your help would be much appreciated!

  6. Bjorn Verryt on May 13th, 2011

    Thanks so much, exactly what I needed. You truly are the master of datatypes!

Leave a Reply