Taxonomy site columns can be provisioned just like other columns through a Feature. There are already excellent tutorials out there on how to deploy site columns via Feature--for instance, this post on Fabian William's blog. However, there are some pitfalls to getting the Elements file right for Managed Metadata fields (MM for short hereafter). This post covers:
- How to provision a MM field
- TargetTemplate property's function and it's effect on TaxonomyFieldControl
- How to enable multi-select
Hidden Note Field
Firstly, each MM field must be paired with a hidden Note field. The MM field stores the value of the metadata term, while the associated Note field holds the term's taxonomy ID. If you provision just the MM one, it'll show up on the site, but you'll probably run into this error once you try to put values in: Failed to get value of the “{0}” column from the “Managed Metadata” field type control. See details in log. Exception message: Invalid field name. {00000000-0000-0000-0000-000000000000}.The example below deploys a new MM column called Keywords, and a Note column called KeywordsTaxHTField0. The Note field can be named anything, but I use the TaxHTField0 suffix to be consistent with SharePoint's convention.
The MM field's TextField property references the Note field's ID. This is what links the two columns.
<Field ID="{AFFCC398-1B80-49B4-9367-5980C74AF556}"
Type="Note"
Name="KeywordsTaxHTField0"
StaticName="KeywordsTaxHTField0"
DisplayName="Keywords_0"
ShowInViewForms="false"
Hidden="true"
CanToggleHidden="true"
Group="Custom" />
<Field ID="{9D21CCB4-B815-483E-A1C1-9947A1514187}"
Type="TaxonomyFieldType"
Name="Keywords"
StaticName="Keywords"
DisplayName="Keywords"
ShowField="Term1033"
Required="false"
Group="Custom">
<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">
AFFCC398-1B80-49B4-9367-5980C74AF556
</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
Type="Note"
Name="KeywordsTaxHTField0"
StaticName="KeywordsTaxHTField0"
DisplayName="Keywords_0"
ShowInViewForms="false"
Hidden="true"
CanToggleHidden="true"
Group="Custom" />
<Field ID="{9D21CCB4-B815-483E-A1C1-9947A1514187}"
Type="TaxonomyFieldType"
Name="Keywords"
StaticName="Keywords"
DisplayName="Keywords"
ShowField="Term1033"
Required="false"
Group="Custom">
<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">
AFFCC398-1B80-49B4-9367-5980C74AF556
</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
TargetTemplate and TaxonomyFieldControl Rendering
Sometimes, in my twisted dreams, SharePoint comes to me, a goddess with eyes afire, whose alien desires and inscrutable whims lay waste to entire farms. She passes judgement atop a giant hourglass, a literal timer job run on the raging souls of a thousand broken developers. A simpler metaphor might be a box of chocolates. The point is, some crazy, existential sh*t happens on SharePoint.TargetTemplate and TaxonomyFieldControl Rendering
Say you add a MM field to an Enterprise Wiki and put down a TaxonomyFieldControl on the page to display the new field, right under the OOB Wiki Categories control with this markup:
<Taxonomy:TaxonomyFieldControl
FieldName="Wiki_x0020_Page_x0020_Categories"
EmptyValueDescriptionForTargetTemplate="<%$Resources:cms,enterwiki_nocategories_assigned%>"
DisableInputFieldLabel="true"
runat="server" />
<Taxonomy:TaxonomyFieldControl
FieldName="Keywords"
EmptyValueDescriptionForTargetTemplate="No keywords tagged"
DisableInputFieldLabel="true"
runat="server" />
FieldName="Wiki_x0020_Page_x0020_Categories"
EmptyValueDescriptionForTargetTemplate="<%$Resources:cms,enterwiki_nocategories_assigned%>"
DisableInputFieldLabel="true"
runat="server" />
<Taxonomy:TaxonomyFieldControl
FieldName="Keywords"
EmptyValueDescriptionForTargetTemplate="No keywords tagged"
DisableInputFieldLabel="true"
runat="server" />
The declarations are identical except for the fieldname and message to display when the field is empty. The two TaxonomyFieldControls render completely differently:
OOB wiki categories display line by line, each linked to a page listing all articles tagged with that category. The second taxonomy control is a comma-separated text list. It also refuses to display the EmptyValueDescription when no tags are selected. Scritch... scritch...
Much blood, tears and other fluids were unwillingly shed--unspeakable rituals performed--in search of an answer. It turns out, to get the TaxonomyFieldControl to render like Wiki Categories, the Managed Metadata field it points to must have it's TargetTemplate property set. TargetTemplate specifies the URL for the term hyperlinks. For instance, TargetTemplate for Wiki Categories is /_layouts/Categories.aspx, a page which lists all articles tagged with the category. You can point to that, or make a better looking custom page. To set TargetTemplate, include the following property in your MM field declaration:
<Property>
<Name>TargetTemplate</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema"
p4:type="q6:string"
xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">
/_layouts/Categories.aspx
</Value>
</Property>
<Name>TargetTemplate</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema"
p4:type="q6:string"
xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">
/_layouts/Categories.aspx
</Value>
</Property>
Allow Multiple Values
To make a multi-select MM field, declare the field Type as TaxonomyFieldTypeMulti instead of TaxonomyFieldType, and set Mult to true. You must also explicitly set Sortable to false; otherwise multi-select will not be enabled despite the Type and Mult properties!Allow Multiple Values
The full example below provisions a multi-select MM field with TargetTemplate, along with the associated hidden Note field:
<Field ID="{AFFCC398-1B80-49B4-9367-5980C74AF556}"
Type="Note"
Name="KeywordsTaxHTField0"
StaticName="KeywordsTaxHTField0"
DisplayName="Keywords_0"
ShowInViewForms="false"
Hidden="true"
CanToggleHidden="true"
Group="Custom" />
<Field ID="{9D21CCB4-B815-483E-A1C1-9947A1514187}"
Type="TaxonomyFieldTypeMulti"
Name="Keywords"
StaticName="Keywords"
DisplayName="Keywords"
ShowField="Term1033"
Required="FALSE"
Mult="TRUE"
Sortable="FALSE"
Group="Custom">
<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">
AFFCC398-1B80-49B4-9367-5980C74AF556
</Value>
</Property>
<Property>
<Name>TargetTemplate</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema"
p4:type="q6:string"
xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">
/_layouts/Categories.aspx
</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
Type="Note"
Name="KeywordsTaxHTField0"
StaticName="KeywordsTaxHTField0"
DisplayName="Keywords_0"
ShowInViewForms="false"
Hidden="true"
CanToggleHidden="true"
Group="Custom" />
<Field ID="{9D21CCB4-B815-483E-A1C1-9947A1514187}"
Type="TaxonomyFieldTypeMulti"
Name="Keywords"
StaticName="Keywords"
DisplayName="Keywords"
ShowField="Term1033"
Required="FALSE"
Mult="TRUE"
Sortable="FALSE"
Group="Custom">
<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">
AFFCC398-1B80-49B4-9367-5980C74AF556
</Value>
</Property>
<Property>
<Name>TargetTemplate</Name>
<Value xmlns:q6="http://www.w3.org/2001/XMLSchema"
p4:type="q6:string"
xmlns:p4="http://www.w3.org/2001/XMLSchema-instance">
/_layouts/Categories.aspx
</Value>
</Property>
</ArrayOfProperty>
</Customization>
</Field>
10 comments:
Im new to sharepoint and need to take advantage of this. Where do you Place the code?
This code is for deploying managed meta data site columns via a Feature. It goes into the feature's Elements.xml file. For a step by step tutorial on how to create the feature in Visual Studio, please take a look this post on Fabian's blog: http://fabiangwilliams.wordpress.com/2010/07/03/how-to-create-content-types-with-site-columns-in-code-visual-studio-2010-for-sharepoint-2010
Thanks for the reply! Great blog
Hi, do you know if it's possible to set the TargetTemplate through the UI or SharePoint Designer, rather than in code? I can't see it anywhere.
You'll have to use a UI tool like SharePoint Manager 2010 (free download from Microsoft's CodePlex: http://spm.codeplex.com) Run SPM as an admin (needs to run on SharePoint server), drill down to your list and find the MM field, update TargetTemplate property, do File --> Save changes to SharePoint, and you should be good to go.
Awesome posts!
One quick question, if i'm deploying content types with the managed metadata fields, do I need to include the hidden note field also OR is that handle automatically?
Hi Scott,
I have not tried that exact scenario, but I don't think it's handled automatically. I created managed metadata site columns, and added those to a content type. In that case I had to explicitly include the note field, and I imagine directly defining the columns in the CT would be the same.
hi when i set the Target Template value /_layouts/Categories.aspx from Sharepoint Manager and click Save to Sharepoint it is saving but when i refresh the field and check the value is set back to /layouts/Categories.aspx without underscore ?.. why is this or only using code this value can be set
Dinesh.
Hi even when i set the _layouts/Categories.aspx to the TaxonomyFieldMulti it is not working.. Still look the same as comma-separated text list and unclickable.
Great follow up article/post Im was actually going to blog how to do that, but came upon yours. keep it up
Post a Comment