Adding Managed Metadata Fields to SharePoint Publishing Pages
The Managed Metadata functionality provided by SharePoint 2010 allows you to centrally manage metadata and keywords. In a previous post I covered how to provision a SharePoint 2010 managed metadata field and add this to a content type and a list definition. In this post I will cover how to add these types of fields to a publishing page layout so that content authors can add metadata and keywords to webpages they create using these layouts.
If there are a large number of content pages this type of tagging can help users find information as these columns can be used as filters on a list, items in a tag cloud or as search refinements.
The steps to add a managed metadata field to a publishing page are:
A) Create a managed metadata field
- Provision a managed metadata field using type TaxonomyFieldType (or TaxonomyFieldTypeMulti to allow multiple values)
- Configure the managed metadata column to reference an existing term set
- Provision a hidden field of type Note
- Configure the managed metadata column to use the hidden Note field
- Ensure that the TaxonomyFieldAdded feature is activated on the site collection
B) Create a page layout that uses a managed metadata field
- Create a site scoped feature for the page layout
- Create a content type based on the ‘Page’ content type that uses the managed metadata fields
- Create a page layout that uses the new content type
- Create a web scoped feature for the content type association
- Associate the content type with the pages library
As I’ve covered the process to create a managed metadata field in a previous article I won’t repeat that. Instead you can download the example solution and use the steps below to add the field to a page layout, or just use the steps below if you already have completed part A.
1. Create a site scoped feature for the page layout
In this example I’ve created two features – a site scoped feature named ‘Metadata Page’ and a web scoped feature named ‘Metadata Page Web’. The site scoped feature needs to contain the content type and page layout as these are deployed at the site collection level. It should also include a feature activation dependency on the feature(s) used in part A and the publishing infrastructure feature to ensure these features are available.
2. Create a content type based on the ‘Page’ content type that uses the managed metadata fields
Once you have deployed a managed metadata field you should create a content type that inherits from the Page content type (or one that derives from it such as the Article Page or Welcome Page). You will then want to include your managed metadata field and the hidden note field as well as any other fields you want to use in your layout. The example below adds the PublishingPageContent rich text field, the Regional Office managed metadata field and the associated hidden note field, and the Enterprise keywords field (a non-hierarchical open term set).
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Parent ContentType: Page (0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39) -->
<ContentType ID="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900e20db8f48c7c44d0938059ab05bace32"
Name="Metadata Page"
Group="Custom Content Types"
Description="My Content Type"
Inherits="TRUE"
Version="0">
<FieldRefs>
<FieldRef ID="{f55c4d88-1f2e-4ad9-aaa8-819af4ee7ee8}" Name="PublishingPageContent"/>
<FieldRef ID="{dcb76480-4735-11e0-ab07-0800200c9a66}" Name="RegionalOffice"/>
<FieldRef ID="{9EDAB26E-CC44-4027-AB05-CB44EA3A6F72}" Name="RegionalOfficeTaxHTField0"/>
<FieldRef ID="{23f27201-bee3-471e-b2e7-b64fd8b7ca38}" Name="TaxKeyword" />
</FieldRefs>
</ContentType>
</Elements>
Note that unlike the previous post I’m not adding the TaxCatchAll or TaxCatchAllLabel fields to my content type as these are added to the list automatically when you associate the content type with the Pages list (covered in step 3). This step is only required if you are creating a list definition – more details are in the post on issues provisioning SharePoint 2010 managed metadata fields.
3. Create a page layout that uses the new content type
To create the page layout you need to create an ASPX page and a module that will deploy this to the masterpage gallery. One way of creating the ASPX page is to use the CKS:Dev Visual Studio extensions that allow you to create this by right clicking on the content type in server explorer.
Alternatively you can just create an empty module and add a standard ASPX page with the mark-up shown below:
<%@ Page language="C#" Inherits="Microsoft.SharePoint.Publishing.PublishingLayoutPage,Microsoft.SharePoint.Publishing,Version=14.0.0.0,Culture=neutral,PublicKeyToken=71e9bce111e9429c" meta:webpartpageexpansion="full" meta:progid="SharePoint.WebPartPage.Document" %>
<%@ Register Tagprefix="SharePointWebControls" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="WebPartPages" Namespace="Microsoft.SharePoint.WebPartPages" Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="Taxonomy" Namespace="Microsoft.SharePoint.Taxonomy" Assembly="Microsoft.SharePoint.Taxonomy, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<asp:Content ContentPlaceholderID="PlaceHolderPageTitle" runat="server">
<SharePointWebControls:FieldValue id="PageTitle" FieldName="Title" runat="server"/>
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderPageTitleInTitleArea" runat="server">
<SharePointWebControls:FieldValue FieldName="Title" runat="server"/>
</asp:Content>
<asp:Content ContentPlaceholderID="PlaceHolderAdditionalPageHead" runat="server">
<SharePointWebControls:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/page-layouts-21.css %>" runat="server"/>
<PublishingWebControls:EditModePanel runat="server">
<!-- Styles for edit mode only-->
<SharePointWebControls:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/edit-mode-21.css %>"
After="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/page-layouts-21.css %>" runat="server"/>
</PublishingWebControls:EditModePanel>
<SharePointWebControls:CssRegistration name="<% $SPUrl:~sitecollection/Style Library/~language/Core Styles/rca.css %>" runat="server"/>
</asp:Content>
<asp:Content ContentPlaceHolderId="PlaceHolderMain" runat="server">
<h2><SharePointWebControls:TextField runat="server" FieldName="Title"/></h2>
<p>
<strong><PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Display">Regional Office:</PublishingWebControls:EditModePanel></strong>
<Taxonomy:TaxonomyFieldControl FieldName="RegionalOffice" InputFieldLabel="Regional Office" runat="server"></Taxonomy:TaxonomyFieldControl>
</p>
<p>
<strong><PublishingWebControls:EditModePanel runat="server" PageDisplayMode="Display">Tags:</PublishingWebControls:EditModePanel></strong>
<Taxonomy:TaxonomyFieldControl FieldName="TaxKeyword" InputFieldLabel="Tags" runat="server"></Taxonomy:TaxonomyFieldControl>
</p>
<div class="article-content">
<PublishingWebControls:RichHtmlField FieldName="PublishingPageContent" HasInitialFocus="True" MinimumEditHeight="400px" runat="server"/>
</div>
</asp:Content>
In your elements.xml file you then configure this page layout to be deployed to the masterpage gallery and use the content type you created in step 1 by using the following mark-up:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Module Name="PageLayouts" Url="_catalogs/masterpage" Path="PageLayouts" RootWebOnly="TRUE">
<File Url="MetadataPageLayout.aspx" Type="GhostableInLibrary">
<Property Name="Title" Value="Metadata Page" />
<Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;" />
<Property Name="PublishingPreviewImage" Value="~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png, ~SiteCollection/_catalogs/masterpage/$Resources:core,Culture;/Preview Images/DefaultPageLayout.png" />
<Property Name="PublishingAssociatedContentType" Value=";#Metadata Page;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900e20db8f48c7c44d0938059ab05bace32;#"/>
</File>
</Module>
</Elements>
4. Create a web scoped feature for the content type association
At this point you should check your features to make sure the content type and page layout are associated with the Metadata Page site scoped feature. You should also create a web scoped feature to use for the following item.
5. Associate the content type with the pages library
The last step is to associate the content type with the pages library. If you miss this step then users can still create pages using your page layout but if they only have contribute permission then the managed metadata functionality is not configured properly within the pages library correctly and you get the following error:
Failed to get value of the “{0}” column from the “Managed Metadata” field type control. See details in log. Exception message: Invalid field name. {1}
To create this association create an empty module element with the following mark-up:
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Metadata page binding -->
<ContentTypeBinding
ContentTypeId="0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF3900e20db8f48c7c44d0938059ab05bace32"
ListUrl="Pages"
/>
</Elements>
The web scoped feature that is used for this should be activated on all sites that will use the page layout you created earlier. It tells SharePoint to add the content type to the pages library as well as all associated fields and will correctly configure the managed metadata functionality when this is activated. To setup this association you might want to add this feature in your custom web templates (or site definitions) or use a FeatureSiteTemplateAssociation to associate your feature with existing site definitions such as the publishing site.
Once this is deployed you should be able to create a new page and select your page layout from the ribbon as shown below:
I’ve included the code used in the steps above in a Visual Studio 2010 project to add a managed metadata field to a publishing page layout. This builds on the previous example to create a managed metadata field so it also includes the code to create a list definition.
Thanks for the post! Nice work deciphering the managed metadata fields 🙂
Bill
15 Nov 11 at 9:24 pm
Thank you, worked like a charm 🙂
KjellSJ
21 Apr 12 at 10:16 am
Hi thanks for this post. Everything worked as expected except for searching… Indeed when I run a full crawl, the crawled properties are found but nothing inside. The same for the enterprise keywords column. When I run a full crawl no elements are referenced in the index for this crawled property. Please help !
Win
14 May 12 at 10:41 am
[…] Understanding Managed Metadata in SharePoint 2010: its Impact on Taxonomy, Navigation and Search Adding Managed Metadata Fields to SharePoint Publishing Pages How to: Create a Simple SharePoint 2010 People Directory How to Create a Custom Page Layout for […]
My Links – SP2010 « sharepointarchitecture
4 Aug 12 at 12:24 pm
thanks a lot for the post. your post is the only one the handled associating the metadata content type with the pages library. i kept banging my head against the wall to handle the error message but your solution worked like a charm. thanks again
Sherif
8 Jan 13 at 8:27 am
Very helpful to create a OOTB MMS field called “taxkeyword” within the page layouts through content type but when we made this field required not able to publish the page directly while creating the page, rather need to do check-in and then publish
Any thoughts on this ?
Roopesh
15 Jan 13 at 3:42 pm