Here are the steps to take to provision Managed Metadata columns.
- Start with an empty SharePoint Project in Visual Studio 2010.
- Add a new Item to the project and select the Empty Element template.
- In this new Element file, add the following xml definition for a Managed Metadata column and it’s associated hidden Note field:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{F2B1920F-2025-41EB-84DC-F59E29D17D33}" Type="TaxonomyFieldType" DisplayName="Contributor" ShowField="Term1033" EnforceUniqueValues="FALSE" Group="Custom Metadata" StaticName="Contributor" Name="Contributor" Overwrite="TRUE">
<Customization>
<ArrayOfProperty>
<Property>
<Name>TextField</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema" p4:type="q6:string" xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">{35732AE5-9782-42F6-A44B-AF07ED2809CE}</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
<Field ID="{35732AE5-9782-42F6-A44B-AF07ED2809CE}" Type="Note" DisplayName="Contributor_0" StaticName="ContributorTaxHTField0" Name="ContributorTaxHTField0" ShowInViewForms="FALSE" Required="FALSE" Hidden="TRUE" CanToggleHidden="TRUE" RowOrdinal="0" />
</Elements>
Updated: Aug 11, 2011 updated to add the Customization ArrayOfProperty that is required to make your content type be re-deployable. Without this, you will get a message that the hidden note field already exists.
- Then we will add a new Content type to consume this new column. To do this add a new Item to the project and select Content Type in the templates. Provide a name and pick the content type that will be the base for this new content type.
- In the Elements.xml file of the new content type add the following FieldRefs:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Parent ContentType: Article Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D) -->
<ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900242457EFB8B24247815D688C526CD44D00426fe9e90dd14ec8a88a4599ec58c3fd"
Name="Article Page"
Group="Article Page Layout Content Types"
Description="Base for all article pages"
Inherits="TRUE"
Version="0">
<FieldRefs>
<FieldRef ID="{35732AE5-9782-42F6-A44B-AF07ED2809CE}" Name="ContributorTaxHTField0"/>
<FieldRef ID="{F2B1920F-2025-41EB-84DC-F59E29D17D33}" Name="Contributor"/>
</FieldRefs>
</ContentType>
</Elements>
- Make sure the Hidden field is added first so there won’t be an automatic Note field created by the Managed Metadata column and cause conflicts.
- Now we need to add a feature event receiver on Feature1 of the project. (right clicking the Feature1 will give you the option of creating this)
- In the feature event receiver, we need to uncomment the FeatureActivated block and add the following code to it:
using Microsoft.SharePoint.Taxonomy;
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
SPWeb web = properties.Feature.Parent as SPWeb;
SPSite sitecoll = web.Site;
//Attach Metadata Fields to Store
AttachManagedMetadataFieldToStore("{F2B1920F-2025-41EB-84DC-F59E29D17D33}", "TaxonomyTermSetName", "TaxonomyTermGroupName", web, sitecoll, "{35732AE5-9782-42F6-A44B-AF07ED2809CE}");
}
- You will also need the following helper functions to complete the feature:
public Group GetByName(GroupCollection groupCollection, string name)
{
if (String.IsNullOrEmpty(name)) throw new ArgumentException("Not a valid group name", "name");
foreach (var group in groupCollection)
{
if (group.Name == name)
{
return group;
}
}
throw new ArgumentOutOfRangeException("name", name, "Could not find the group");
}
public void AttachManagedMetadataFieldToStore(string guid, string TS, string TG, SPWeb web, SPSite site, string NoteGuid)
{
Guid fieldId = new Guid(guid);
if (web.Fields.Contains(fieldId))
{
TaxonomySession s = new TaxonomySession(site);
if (s.DefaultKeywordsTermStore != null)
{
var termStore = s.DefaultKeywordsTermStore;
var groupCol = termStore.Groups;
var group = GetByName(groupCol, TG);
var termSet = group.TermSets[TS];
TaxonomyField fld = site.RootWeb.Fields[fieldId] as TaxonomyField;
// Attach Properties to field
fld.SspId = termSet.TermStore.Id;
fld.TermSetId = termSet.Id;
fld.AnchorId = Guid.Empty;
fld.TargetTemplate = string.Empty;
fld.TextField = new Guid(NoteGuid);
fld.Update();
}
}
}
This SharePoint solution can be packaged up and will provision the columns for you on activation.
Please note: Managed Metadata Columns do have limitations like not having any support in Infopath, not being supported in datasheet views, not being supported by Office 2007, etc… The complete list can be found on this post here: https://www.nothingbutsharepoint.com/sites/eusp/Pages/Managed-Metadata-Column-Limitations.aspx
I will add a second part to this article soon on how to create the taxonomy term store using an xml import file instead of the OOTB csv import file so the GUIDs remain unchanged from deployment to deployment (handy for dev/qa/uat/prod multi-level environments.)