Tuesday, January 25, 2011

Show reusable data on the master page in Sharepoint

When you create site collection based on OTB publishing portal template, root site contains Reusable Data list. It stores pieces of information (it can be plain or html formatted text) which can be shown on different pages in your portal. In order to show reusable data on the publishing page you need to create or edit existing page and when focus will be on the page content field (rich html field type) in the top ribbon you can choose Insert > Reusable data. It will insert reference on the reusable data list item on your page. So when you will change reusable data list item, it will affect all pages where it is inserted.

However, there can be situations when you need to show reusable data on the master page (i.e. not on publishing pages). It is not so straightforward, because after this you will notice that SPContext.Current.ListItem always contains reference on the publishing page which is shown with you master page. It means that all field controls on the master page will show field values from publishing page, but not from the master page.

In order to show field values from master page I created custom control, which retrieves field value from master page’s metadata and displays it:

   1: public class MasterPageFieldValue : Control
   2: {
   3:     protected override void Render(HtmlTextWriter output)
   4:     {
   5:         try
   6:         {
   7:             if (this.Page.Master == null)
   8:             {
   9:                 return;
  10:             }
  11:             var file = SPContext.Current.Site.RootWeb.GetFile(this.Page.MasterPageFile);
  12:  
  13:             var field = file.Item.Fields.Cast<SPField>().FirstOrDefault(f => f.InternalName == this.FieldName)
  14:             if (field == null)
  15:             {
  16:                 return;
  17:             }
  18:             output.Write(field.GetFieldValueAsHtml(file.Item[this.FieldName]));
  19:         }
  20:         catch (Exception x)
  21:         {
  22:             // log
  23:         }
  24:     }
  25: }

As you can see it gets SPListItem instance for the master page (which is located in Masterpage gallery (_catalogs/masterpage) in most cases) and retrieves field value from its metadata. After that it renders value to output. Notice that it inherits from standard ASP.Net Control class (i.e. not from Sharepoint BaseFieldControl as you may think it should use), because BaseFieldControl uses SPContext.Current.ListItem internally and as I said in our case it is not correct storage for retrieving metadata values.

In order to use this control on you need to add it on the master page by common way:

   1: <%@ Register TagPrefix="uc" Assembly="MyAssembly" %>
   2: ...
   3: <uc:MasterPageFieldValue FieldName="ReusableData" runat="server" />
After that you need to add “ReusableData” field into Publishing Master Page content type (or another content type you use for your master page). Then go to Masterpage gallery (_catalogs/masterpage) and choose Edit properties for your master page. Insert reference on reusable data list item by regular way and check in changes. After this you will have reusable data shown on the master page.

No comments:

Post a Comment