Uncategorized


Good news everyone!

I’ve joined Sitecore as a Solution Architect in their Brisbane Australia office!

Things have been pretty hectic since I decided to jump ship for the other hemisphere which hopefully explains the lack of blog posts. Once everything is settled I’m sure I’ll get back into the swing of things.

I’ve been keen to work for Sitecore for a while now but why Brisbane? Below is a sample of what tempted me back to the the Antipodes:

I’ve been looking at the new Visual Studio 2010 beta and it looks like it’s going to make all sorts of improvements over VS2008.

One of the features I really like is the web.config transformations; this is exactly what I’ve been looking for in Sitecore installs. When you’re deploying Sitecore to a production server there is always a raft of settings that need changing, you can manually keep track of them or use features like configSource attributes but there always seems to be problems. In VS2010 however you can keep a set of transformation web.configs for your various deployments:

image

Part of the MSBuild deployment process is that it creates a new web.config with the changes you’ve specified in the transformation files. The files themselves contain the settings that need changing and details on how to match them within the original web.config:


<?xml version="1.0"?>
<!-- For more information on using web.config transformation visit http://go.microsoft.com/fwlink/?LinkId=125889 -->
<configuration xmlns:xdt="http://schemas.microsoft.com/XML-Document-Transform">
  <connectionStrings configSource="App_Config\ConnectionStrings.Debug.config" xdt:Transform="Replace" />
  <sitecore database="SqlServer">
    <sc.variable name="dataFolder" value="E:\WebApplications\vs2010test\data" xdt:Transform="Replace" xdt:Locator="Match(name)"  />
    <sites>
      <site name="vs2010test_english" xdt:Transform="Replace" xdt:Locator="Match(name)" language="en" hostName="english.vs2010test.local" ...
      <site name="vs2010test_japanese" xdt:Transform="Replace" xdt:Locator="Match(name)" language="ja-JP" hostName="japanese.vs2010test.local" ...
      <site name="vs2010test_german" xdt:Transform="Replace" xdt:Locator="Match(name)" language="de-DE" hostName="german.vs2010test.local" ...
    </sites>
    <settings>
      <setting name="IndexFolder" xdt:Transform="Replace" xdt:Locator="Match(name)" value="E:\WebApplications\vs2010test\data\indexes" />
    </settings>
  </sitecore >
  <system.web>
    <customErrors mode="RemoteOnly" xdt:Transform="Replace"/>
  </system.web>
</configuration>

The important attribute is xdt:Transform=”Replace” which replaces the setting in the original web.config with the new one. This works fine when there is just a single node of that type such as <connectionStrings/>.

For nodes with multiple instances such as <site/> you can distinguish them using xdt:Locator=”Match(name)” which tells the transformer to match the element to the original using the name attribute.

Once all the changes are made you should end up with a new web.config that is configured for your deployment target machine. There is the added bonus that all of these transform files are stored in source control alongside the original web.config.

I’ve also been looking at the Team Development for Sitecore product from Hedgehog software (deserves own blog post), combined with this and I think my deployment issues will be solved. Hopefully :)

Bit of a mini-post, I saw a writeup on how to create new template types for Visual Studio so I went ahead and created one for the Sitecore XSLT Rendering files. Save the below file to your Visual Studio templates folder (Tools->Options->Projects & Solutions) and you’re done. When you next go to add an xslt file you can pick the Sitecore XSLT Rendering (which I got from the latest 6.2 release) listed under my templates.

InsertRendering

If you wish to modify it you can just make changes to the xsl.xslt file in the zip file.

The File

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’)”/>

Welcome to my new Blog concerning all things web development, ASP.Net and Sitecore in sunny London.

Standard disclaimer follows:

The opinions expressed herein are my own personal opinions and do not represent my employer’s views in any way, shape or form, implied directly, indirectly or even if stated clearly. All statements past, present and future in no way are related to my current, past or potentially future employment with any company, municipality, NGO, charity and/or any self-perpetuating anarcho-syndicalist commune.