You
created a site column and content type through a browser. The question
is, if you can do it through the browser why should you ever do it in
code? The answer is they are many situations in which doing it through
code is necessary. Frequently, many overloads of some methods in the
SharePoint API expect the content type ID. While you could write 100%
generic code to filter out the content type ID based on a content type
name, that code is neither reliable nor a pleasure to write. Frequently,
you will need to keep content IDs across various environments
(Development, QA, and Production) consistent.
Secondly,
there may be a time where you have a single content ID across many site
collections that has the same meaning. While in SharePoint 2010 you
have the ability of synchronizing content types across cross site
collections, the synchronization may take a while. Therefore, if you are
running custom search scopes based on a content type name, or any cross
site collection functionality that relies on the content type name, you
probably also want to control the actual definition, ID, the value and
structure of that content type across site collections.
It is in these scenarios that you will find yourself writing and deploying content types through code.
Also, as I mentioned earlier, content types live in content type gallery and are built using site columns.
Let's write up a quick
Visual Studio 2010 project that creates a site column based on the
custom field type you created earlier and uses that site column in a
custom content type.
As always, start a Visual
Studio 2010 and create a new solution based on the empty SharePoint
project template. Choose it to be a sandbox solution this time because
all the changes that you will do will go in the content database. Name
this project "Album".
In this project, add the new
SharePoint item and choose to add a content type. Name this content type
"Track". Since every content type must have a parent, Visual Studio
will prompt you to pick the parent of this content type. Choose the
parent to be the item content type, as shown in Figure 1.
To keep your project clean,
rename the elements.xml to TrackContentType.xml. The next step is to add
some site columns into this content type. But you haven't set up any
new site columns yet, especially a site column driven by the custom
field type you just wrote. So, add another SharePoint item into the
project, and this time choose to add an empty element. Name your element
"TrackContentFields". By now, Visual Studio would have added a feature1
feature to your project. Rename that feature1 to "TrackContentType ",
and set its various properties appropriately.
This feature can either be
scoped to web or site (collection). The way content type and site
columns work is that you can declare them at any web level. All the
child webs simply inherit all the created content types and site columns
from the parent web. This technique can also be used to create look up
columns that can work across sites. This is shown in an article I had
written for SharePoint 2007, but is equally applicable to SharePoint
2010 as well.
Coming back to this project, by now I assume that you have created a project structure that looks like Figure 2.
Your "TrackContentType"
feature is scoped to web. Next, let's create site columns in the
TrackContentFields.xml file. The code for TrackContentFields.xml can be
seen in Listing 1.
Example 1. Creating Site Columns
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{52d63c75-2b4e-41f2-9091-c92279c27f75}"
Type="DateTime" DisplayName="ReleaseDate" Required="FALSE"
Format="DateOnly" Group="Music"
StaticName="ReleaseDate" Name="ReleaseDate"
/>
<Field ID="{ 0eb47e64-4a6a-4fbf-b090-03d803967516}"
Type="AutoCompleteField" DisplayName="Song Name" Required="FALSE"
Group="Music" StaticName="Song_x0020_Name" Name="Song_x0020_Name"
Hidden="FALSE" ReadOnly="FALSE"/>
</Elements>
|
As you can see from Listing 1,
you have created two site columns, one that is called ReleaseDate based
on that DateTime out of the box field definition and the second called
SongName, based on the AutoCompleteField custom field definition that
you wrote earlier. The weird looking Song_x0020_Name is simply "Song
Name ", with the unicode character for a space, %20 inserted in a
special format typical to SharePoint. The ID you see in these Site
Columns are GUIDs that I generated using GUIDGEN.exe. You can run
GUIDGEN from Visual Studio under Tools\Create GUID.
Next, let's tie these site
columns in a content type. The content type that you had added earlier,
and had subsequently renamed the elements.xml to "TrackContentType.xml
", already contains the bare bones structure information of the content
type. Under the FieldRefs element, you need to reference various site
columns that will be a part of this content type. Of course, there are
many other things you can specify in a content type such as associated
workflows, information management policies, document templates, and so
forth. Shortly I will share a trick with you that will greatly ease your
task of writing these XML files. But for now, edit the
TrackContentType.xml file to reflect what is shown in Listing 2.
Example 2. Track Content Type Definition
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<!-- Parent ContentType: Item (0x01) -->
<ContentType ID="0x0100ce2744e3baea4734b2333d043aa5dd2c"
Name="Track" Group="Music"
Version="0">
<FieldRefs>
<FieldRef
ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title"
DisplayName="Title" Sealed="TRUE" />
<FieldRef ID="{52d63c75-2b4e-41f2-9091-c92279c27f75}"
Name="ReleaseDate"/>
<FieldRef ID="{0eb47e64-4a6a-4fbf-b090-03d803967516}"
Name="Song_x0020_Name"
Required="TRUE"
Hidden="FALSE" ReadOnly="FALSE"/>
</FieldRefs>
</ContentType>
</Elements>
|
Next, build and deploy your
project. Create a new list instance based on the custom list definition
and call it album. Inside album under advanced settings, choose to allow
management of content types. Add the newly created Track Content Type
to this list and delete the out of the box item content type. Now back
in the list, choose to add a new track. You will see that your custom
content type along with its custom site columns that build upon the
custom field type are running, as shown in Figure 3.
You just saw a simplistic
example of crafting up a content type from scratch. This ContentType had
only structure in it, but content types can hold numerous other pieces
of information as well. Also, a content type can then be used inside
existing lists or existing list definitions. Writing all this requires
you to write and remember gobs of XML, usually referred to as CAML.
So far you have
written a custom field definition, site columns, and a content type.
Next, let's write a list definition that uses this content type. Also,
through the same Visual Studio solution, you will also create a
provision a list instance based on this newly created list definition.