Posts tagged ‘taxonomy’

September 16, 2010

Provisioning taxonomy type site columns in a feature

Taxonomy type site columns give us the same issues as Lookup type site columns have historically, with a slight twist.

Where, with Lookup fields, we can specify all the attributes in the XML correctly but they don’t get picked up correctly; with Taxonomy fields we don’t have attributes for all the necessary pieces of information – particularly the TermSetId and the SspId (Id of the Term Store).

To get round this issue, we can use a similar method to that which we used for Lookup fields in MOSS 2007, whereby we attached a feature receiver to correctly set the List GUID based on the List name we had specified in the CAML field definition.

To this end we firstly need some CAML in our Elements file, to provision the Site Column

<Field ID="{5d0d24ee-c332-465d-8efc-83d40ab615ff}"
         Group="My Fields"
         DisplayName="My Taxonomy Field"
          <Value>Managed Metadata Service</Value>
          <Value>Keywords Group</Value>

As can be seen, we have defined some additional custom properties to set the service application name, the termstore group, and the termset which we want the field to access. We must do this since there aren’t any attributes in the schema that we can use for these purposes.

In addition, Taxonomy Fields require a note type field alongside them. Above, the name can be seen stored as a custom property, so in order for this to work, we need to define this site column in CAML as follows:

<Field ID="{700a3d33-a85c-47dd-80d1-2eba10439b46}"
         Group="My Fields"
         DisplayName="My Taxonomy Field Text"
         Type="Note" />

We now need to write a feature receiver for the Site scoped feature which holds this solution element. Inside the FeatureActivated method, we want to traverse the Xml of our Elements file, and detect where the type of field is TaxonomyFieldType.

When we have that we can then update the column so that its definition is correct as follows (XML references as XPath, replace with whichever method you use – XmlDocument, XDocument, XPathDocument etc.)

//Get the current field

TaxonomyField taxonomyField = web.Fields[Field/@ID] as TaxonomyField;

TaxonomySession taxonomySession = new TaxonomySession(||Current site from properties.Feature.Parent||);

string sspName = {Property[Name='SspName']/Value}
string groupName = {Property[Name='TermGroup']/Value}
string termSetName = {Property[Name='TermSet']/Value}
string textFieldId = {Property[Name='TextFieldId']/Value}

//Set the term store id
taxonomyField.SspId = session.TermStores[sspName].Id;

//Set the term set id
taxonomyField.TermSetId = session.TermStores[sspName].Groups[groupName].TermSets[termSetName].Id;

//Set the text field's id
taxonomyField.TextField = new Guid(textFieldId);

//Save the changes

Note: TaxonomyField and TaxonomySession classes used above are from the Microsoft.SharePoint.Taxonomy assembly/namespace, located in 14/ISAPI; you will also need to import System.Text.RegularExpressions

When this is run the Site Column will be correctly provisioned against the Managed Metadata Service. We can substitute in different values for this to work against alternative Service Applications, Groups and Term Sets.