So there I was, tasked with creating some custom site columns that would be later used to create some custom content types for a customer. None of the SharePoint books that I was looking through really gave me a "soup to nuts" version of what I was looking for. A quick Internet search revealed some of the parts that I needed so I thought that I would try and document my thought processes here to give others a head start.
First step was to create a Visual Studio project that would hold my site column feature. In keeping with the way that Microsoft had designed the Publishing features, we decided to create a feature that would hold the site columns needed for another feature that would actually create both some page layout content types as well as some descendents of the Document built in content type. I used a couple of Ken Schaefer’s posts (one on using resource files and one on creating a Visual Studio project for feature development) to get me started. If you need some background on what the feature.xml file is supposed to look like, check out this MSDN article. In there are some great links to the feature element schema.
Once I had that all set up, I started the creation of the file that would hold all of the custom site columns. You can call it whatever you like since you tell the feature.xml file what it is called using the ElementManifests element, which is a child of the Feature element.
Here is a sample listing from that file, complete with Visual Studio color coding:
<?xml version="1.0" encoding="utf-8" ?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{B2B7FF58-3C2D-4afc-8CE0-23B08D2E4E05}"
Name="EventTime"
StaticName="EventTime"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Group="$Resources: MyResources,SiteColumnGroup;"
DisplayName="$Resources:MyResources,EventTimeDisplayName;"
Description="$Resources: MyResources,EventTimeDescr;"
Type="Text"
Required="FALSE"
Sealed="TRUE"
MaxLength="255">
</Field>
<Field ID="{3BA6DF46-39FF-49e4-B180-99EF2BAF019B}"
Name="IssueComments"
StaticName=" IssueComments "
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Group="$Resources: MyResources,SiteColumnGroup;"
DisplayName="$Resources: MyResources,IssueCommentsName;"
Description="$Resources: MyResources,IssueCommentsDescr;"
Type="Note"
NumLines="6"
Required="FALSE"
Sealed="TRUE">
</Field>
<Field ID="{C9C915CE-08C8-44db-96F7-00AD6F3E8BE8}"
Name="IssueNumber"
StaticName="IssueNumber"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Group="$Resources: MyResources,SiteColumnGroup;"
DisplayName="$Resources: MyResources,IssueNumberName;"
Description="$Resources: MyResources,IssueNumberDescr;"
Type="Number"
Required="FALSE"
Sealed="TRUE">
</Field>
<Field ID="{6A85F726-6035-47e3-B88A-0B540CFBB7C2}"
Name="ManagementReportMonth"
StaticName="ManagementReportMonth"
SourceID="http://schemas.microsoft.com/sharepoint/v3"
Group="$Resources: MyResources,SiteColumnGroup;"
DisplayName="$Resources: MyResources,ManagementReportMonthName;"
Description="$Resources: MyResources,ManagementReportMonthName;"
Type="Choice"
FillInChoice="FALSE"
Required="TRUE"
Sealed="TRUE">
<CHOICES>$ResourcesNoEncode: MyResources,MonthChoices</CHOICES>
<Default>$Resources: MyResources,ReportMonthDefault;</Default>
</Field>
</Elements>
NOTE: It is a bad idea to use a space in the text for either the Name attribute or the StaticName attribute. Using a space here will make it hard to use these columns as custom fields in a CQWP
If you are wondering how I pieced together this file, wonder no more. There is a file that SharePoint uses to create all of it’s built in site columns that you get out of the box. It can be found it the 12 Hive under TEMPLATEFEATURESfields. It is called fieldswss.xml. To use this file, I would go into a SharePoint site and find a built in column that was similar to the one that I wanted to create. I would then do a search in the fieldswss.xml file to find that field and pattern my column after that one. Another a big help was a MSDN posting that outlines the Field element which was sent to my by a co-worker that we found while we were chatting after I had finished my work. Thanks Oscar!
Scattered throughout this file you will see some references to the resources file that I used as per Ken’s post. The one thing that Ken didn’t mention was the "$ResourcesNoEncode" directive. This little ditty will allow you to specify XML in your resource file. In this case, my resource file contained a string that listed out all of the months:
<CHOICE>January</CHOICE>
<CHOICE>February</CHOICE>
<CHOICE>March</CHOICE>
<CHOICE>April</CHOICE>
<CHOICE>May</CHOICE>
<CHOICE>June</CHOICE>
<CHOICE>July</CHOICE>
<CHOICE>August</CHOICE>
<CHOICE>September</CHOICE>
<CHOICE>October</CHOICE>
<CHOICE>November</CHOICE>
<CHOICE>December</CHOICE>
That directive tells whatever preprocessor gets run to insert the resource values into the XML to not encode the value and just drop it in "as is". This prevented me from having to put in one resource file entry for each month and then one CHOICE element for each month. Pretty slick…
Another thing I want to point out is that each Field element needs a unique GUID. I just used the Visual Studio GUID creation tool (Tools->Create GUID) to get that.
The last gotcha that I want to point out is that when you pick the Name attribute, make it something pretty unique. This is what SharePoint uses to tell if you have duplicate fields in a list. Here is what the MSDN article says about it:
"Optional Text. The name of a field. This is the internal name of a field and is guaranteed never to change for the lifetime of the field definition. It must be unique with respect to the set of fields in a list. The name is autogenerated based on the user-defined name for a field."
That’s pretty much it. If you have done everything right, you should just have to install and activate the feature and your custom site columns should magically appear.
I hope that this post helps get you started. I am sure that I have much to learn about this topic but this should be a good starting point.
PS – If you are wondering where the phrase "soup to nuts" comes from, check out this Wikipedia article.