SharePoint: Data Connection List Template is not Available

2 03 2010

You’re trying to create a Data Connection Library in a SharePoint site and you find that the template isn’t available. Note that the Data Connection list template is only available in MOSS 2007.

The Data Connection list template feature (feature id: 00BFEA71-DBD7-4F72-B8CB-DA7AC0440130) isn’t actiavted against all site definitions, and if you are using a custom site definition, you may not have activated it in your WebFeatures section. The Data Connection list template feature is stapled (feature stapler feature id: CDFA39C6-6413-4508-BCCF-BF30368472B3) to the following site definitions;

  • STS#0
  • STS#1
  • STS#2
  • MPS#0
  • MPS#1
  • MPS#2
  • MPS#3
  • MPS#4
  • WIKI#0
  • BLOG#0
  • BDR#0
  • OFFILE#0
  • SPS#0
  • SPSPERS#0
  • SPSMSITE#0
  • SPSNEWS#0
  • SPSNHOME#0
  • SPSSITES#0
  • SPSREPORTCENTER#0
  • SPSPORTAL#0
  • SRCHCEN#0
  • PROFILES#0
  • CMSPUBLISHING#0

 The good news is that you can just activate the feature manually using STSADM, as shown below;

stsadm -o activatefeature -name DataConnectionLibrary -url {site url}

Alternatively, if you’re using a custom site definition, you can just add the feature to your WebFeatures section;

<WebFeatures>
    <!-- Activate the Data Connection List Template -->
    <Feature ID="00BFEA71-DBD7-4F72-B8CB-DA7AC0440130"/>

</WebFeatures>




SharePoint: Create a Publishing Page in a Site Definition using a Custom Page Layout

25 02 2010

In a publishing environment we often create custom page layouts based on our own content types, and of course if we are also creating custom site definitions, we’ll probably want to create pages in the site defs which are based on our custom page laouts – how do we do this?

Again, it’s all done using a CAML module element as shown below;

<Module Name="PublishingHomePage" Url="$Resources:cmscore,List_Pages_UrlName;" Path="">
	<File Url="Default.aspx" Type="GhostableInLibrary">
		 <Property Name="Title" Value="Hom" />
		 <Property Name="ContentType" Value="My Location Page" />
		 <Property Name="PublishingPageLayout" Value="~SiteCollection/_catalogs/masterpage/MyLocationPage.aspx, My Location Page Layout" />
		 <Property Name="PublishingPageContent" Value="Welcome to the Publishing Site" />
	</File>
</Module>

The Property elements are used to set the column values of the new listitem which is created in the Pages library for this page.

  1. Title – The page title, this is what is usually displayed at the top of the browser window
  2. ContentType – the listitems contentype (name), which should be the content type used as the basis of the page layout
  3. PublishingPageLayout – this is the important one, this tells SharePoint what page layout to associate with the listitem (page), it has a very specific format and a gotcha (see below)
  4. PublishingPageImage, PublishingPageContent etc – you can populate any other columns here.

The PublishingPageLayout property format is;

{the url of the page layout}, {the title value of the page layout}

The gotcha is in the use of the comma (,); either don’t use it and just specify the url of the page layout, or, if you do use it make sure you leave a space character after the comma.

The title value specified after the comma is displayed in the “Page Layout” column in the Pages library.





SharePoint: Provision a Page Layout using a Feature

24 02 2010

In a publishing environment, we undoubtedly create new page layouts based either on existing or custom page layout content types, examples of stock publishing page layout content types include;

  1. Article Page
  2. Welcome Page

When we create a new page layout and want to provision it into SharePoint as part of a greater solution you will want to package it up as part of a feature. This is done using a CAML Module element as shown.

Create a new element manifest file called pagelayouts.xml and reference it in your feature manifest file.

<?xml version="1.0" encoding="utf-8"?>
<Feature  Id="bf7f11b6-4ec1-44fc-9c0f-84ccc3e78637"
          Title="Page Layouts feature"
          Description="This feature provisions page layouts."
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Site"
          DefaultResourceFile="core"
          xmlns="http://schemas.microsoft.com/sharepoint/">
	<ElementManifests>
		<ElementManifest Location="pagelayouts.xml"/>
		<ElementFile Location="MyLocationPage.aspx"/>
	<ElementManifests>
</Feature>

In the pagelayouts.xml file insert the following CAML;

<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
	<Module Name="PageLayoutsModule"
			  Url="_catalogs/masterpage"
			  Path="layouts"
			  RootWebOnly="TRUE">
		<File Url="MyLocationPage.aspx" Type="GhostableInLibrary" IgnoreIfAlreadyExists="TRUE">
			<Property Name="Title" Value="My Location Page"></Property>
			<Property Name="MasterPageDescription" Value="A Location Page ."></Property>
			<Property Name="ContentType" Value="$Resources:cmscore,contenttype_pagelayout_name;"></Property>
			<Property Name="PublishingPreviewImage" Value="/_layouts/images/FTS/preview/PreviewLayoutLocation.png"></Property>
			<Property Name="PublishingAssociatedContentType" Value=";#My Location;#0x010100C568DB52D9D0A14D9B2FDCC96666E9F2007948130EC3DB064584E219954237AF39005AD7C37FF2B8AB4AAD81FBF15F35702C;#"></Property>
		</File>
	</Module>
</Elements>

The Modue and File elements are pretty standard CAML. Remember that the masterpage gallery is actually a list and what we are doing is creating a new listitem in that list. So it should come as no surprise that the Property elements are used to populate the listitems columns. The Property elements are described below;

  1. Title – the value used for the Page Layouts title
  2. MasterPageDescription – a brief description of the page layouts
  3. ContentType – since this is a page layout we want to set the list items content type to be a “Page Layout”, use the resource strings rather than free text since they are localizable
  4. PublishingPreviewImage – the url to a custom or stock page layout preview image
  5. PublishingAssociatedContentType – this is the really important one and it associates the page layout with an underlying content type, the so called page layout content type

The format of the PublishingAssociatedContentType value is;

;#{Content Type Name};#{Content Type ID};#





SharePoint: Setting Web Properties using a Feature in Custom Site Definitions

26 01 2010

In this post we’ll create a feature which sets property values of the SPWeb instance against which the feature is activated. The feature is designed to be used within custom site defintions to allow the created web site to be configured in ways suitable to the site defintion.

The feature has the following characteristics;

  1. There are no feature manifests
  2. The properties to set and their values will be provided using feature defintion properties
  3. The feature will have a feature receiver
  4. The feature should be able to set the SPWeb’s object model properties
  5. The feature should be able to set or create an SPWeb’s property bag properties

Building the Feature.

Create a standard Web scoped feature with a feature receiver class;

<Feature  Id="cfb3318a-88bd-45c4-9037-ab3d09cd32b5"
          Title="Per Web Properties"
          Description="This feature is used to set Web properties and is intended for use within Site Definitions."
          Version="12.0.0.0"
          Hidden="FALSE"
          Scope="Web"
          DefaultResourceFile="core"
          ReceiverAssembly="PerWebProperties, Version=1.0.0.0, Culture=neutral, PublicKeyToken=34303ed68254af5e"
          ReceiverClass="PerWebProperties.PerWebProperties"
          xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>

As you can see there are no feature manifest files. Next write the code for the feature receivers FeatureActivated method;

public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
	var featWeb = (SPWeb)properties.Feature.Parent;
	var featWebID = featWeb.ID;

	using (var web = featWeb.Site.OpenWeb(featWebID))
	{
		var propsUpdated = false;
		foreach (SPFeatureProperty featProperty in properties.Feature.Properties)
		{
			if (string.IsNullOrEmpty(featProperty.Name)) continue;
			if (string.IsNullOrEmpty(featProperty.Value)) continue;

			var featPropNameParts = featProperty.Name.Split(new[] {':'}, StringSplitOptions.RemoveEmptyEntries);
			if (featPropNameParts.Length == 1)
			{
				// set object model properties
				switch(featPropNameParts[0].ToLower())
				{
					// special case properties
					case "locale":
					{
						var ietfLocaleString = featProperty.Value;
						if (!web.Locale.IetfLanguageTag.Equals(ietfLocaleString, StringComparison.OrdinalIgnoreCase))
						{
							var nci = new CultureInfo(ietfLocaleString);
							web.Locale = nci;
						}
						break;
					}
					// for non special case properties just use reflection
					default:
					{
						SetWebProperty(web, featPropNameParts[0], featProperty.Value);
						break;
					}
				}
			}
			else if (featPropNameParts.Length == 2)
			{
				if (featPropNameParts[0].ToLower() == "p")
				{
					// Properties (SPPropertyBag)
					if (web.Properties.ContainsKey(featPropNameParts[1]))
						web.Properties[featPropNameParts[1]] = featProperty.Value;
					else
					{
						web.Properties.Add(featPropNameParts[1], featProperty.Value);
						propsUpdated = true;
					}
				}
			}
		}

		if (propsUpdated)
			web.Properties.Update();
		web.Update();
	}
}

The code which sets SPWeb properties with reflection is shown;

private static void SetWebProperty(SPWeb web, string propertyName, string propertyValue)
{
	if (web == null)
		throw new ArgumentNullException("web");
	if (string.IsNullOrEmpty(propertyName))
		throw new ArgumentNullException("propertyName");

	var t = web.GetType();
	if (t == null) throw new Exception("Invalid reflection object");
	var pi = t.GetProperty(propertyName);
	if (pi == null) throw new Exception("Invalid property: " + propertyName);

	if (!pi.CanWrite)
		throw new NotSupportedException("Property " + propertyName + " is Read Only!");

	try
	{
		var ovalue = Convert.ChangeType(propertyValue, pi.PropertyType);
		pi.SetValue(web, ovalue, null);
	}
	catch (Exception ex)
	{
		throw new Exception(string.Format("Unable to set property: {0} to: {1}",
										propertyName, propertyValue), ex);
	}
}

Finally build, package and deploy the solution to the farm.

Using the Feature in a Custom Site Defintion.

To use the feature in a custom site definition add the following snippet to the WebFeatures section of your site defintions Configuration element, obviously setting those properties as appropriate.

 <!-- Per Web Properties -->
 <Feature ID="cfb3318a-88bd-45c4-9037-ab3d09cd32b5">
	  <Properties xmlns="http://schemas.microsoft.com/sharepoint/">
			<Property Key="MasterUrl" Value="/_catalogs/masterpage/default.master"/>
			<Property Key="CustomMasterUrl" Value="/_catalogs/masterpage/default.master"/>
			<Property Key="Locale" Value="en-GB"/>
			<Property Key="p:myCustomProperty" Value="woo hoo, some useless data value"/>
	  </Properties>
 </Feaure>

You can specify the property name in 2 ways, to specify a property bag property, prefix the property name value with p:

E.g. p:myCustomProperty

To specify an object model property to set, just specify the SPWeb property name;

E.g. MasterUrl





Attaching an Information Management Policy to a Content Type using Feature Activation

15 01 2010

An MSDN article demonstrating how to attach an Information Management Policy to a content type using a feature receiver.