Apply Now  | Knowledge Base  |  About Us | Locations |  Contact Us
  Knowledge Base

About .NET
LINQ
WPF
About SQL Server 2005
About Business Intelligence
Technical Articles
.NET Articles
SQL Server 2005 Articles
SharePoint 2007 Articles
Business Intelligence Articles
Online Resources





 Live chat by LivePerson



Site Columns, Content Types, and Features in SharePoint Services 3.0

Submitted by:  Robert Holmes
June 15, 2007

Site Columns, Content Types, and Features solve some common problems with prior versions of the technology. You may have noticed from the last article in this series, when you create a metadata definition, or column, in a list (a List Column in the new parlance) it is available in that list only. Naturally you can imagine creating the same column multiple times, hoping each time that you get it exactly right. What then happens when you need to make a change to that metadata definition? As you saw in the last article of the series, each repository in SharePoint defines the structure of its content, such as the metadata and template. The problem that can arise here is that content that logically should be grouped together, but has different elements, needs to be put in its own list. For example a project may require only 1 or 2 Word documents, and the same number of Excel workbooks, and other document types, each with its own template and metadata. Or maybe a list that needs to handle multiple types of tasks? Should we create multiple lists or document libraries, or find some way to include each type, with its own structure definition in the same library? Finally, when a user provisions a site, then wants to modify its structure, he or she must do so manually for each item: a master page, new list, Site Column, etc., and do that for each site that requires that particular change. If you make a change that you do not like, or need to modify the choices are to correct the mistake in each site the change was applied to, or reset the entire site back to its site definition, undoing all modifications.

Site Columns and Content Types, and Features solve these problems. Site columns can be created in a site's galleries, then used on any list. Should changes be necessary, that column can be changed in the interface, with the option of propagating the changes out to all lists that have used that column. Content Types allow a developer to create differing content types such that multiple types can coexist in the same repository, or the same type can be used in multiple sites. Once a new type, or column, has been created, the way an administrator can make them available on actual living sites is to deploy via Features. In fact Features is the only right way to deploy any new functionality in the new version. Features allow discrete functionality to be activated, or deactivated, selectively on sites, or the farm, and to redeploy any modifications to an already deployed Feature. This article will also briefly touch upon solutions which is a mechanism of deploying functionality out to sites and farms.

As a final note realize that these are features of Windows SharePoint Services(WSS) v3, and that since MOSS is built on this foundation, everything in this article applies equally to MOSS.


Site columns in Windows SharePoint Services v3

Site Columns, as discussed above, are a way to create a column, or metadata definition, that can be used on any list in a given site. Site Columns are created at the site level, and are available for use in that site, and any children site. Typically you will create them at the level of a top level site, so that they are accessible from anywhere in the site collection. In order to create one, select, from the 'Site Actions' menu, 'Site Settings'. If you have a site installed from the Collaboration(Intranet) template, or another of the MOSS templates, you may get a fly out menu with an option 'Modify All Site Settings', that you will need to select instead:


 

There you will see a number of columns of links, with one in the middle that says 'Galleries'. From there select 'Site columns' to get to a listing of the Site Columns currently on your site. If you select the 'Create' link just above the list, you will get to the New Site Column page.

From here it is similar to any new column as we discussed in the last article. For our example we will create a column named 'Regions' and make it a choice, for which we will enter the options below like so: 
 
(Note: this site was created using the MOSS specific Collaboration Portal template. The choices for type of column may differ.)

The next action is to select the group to add it to:

In this case I added it to a new group. Having now added this group, it will be available for new Site Columns that I create. This helps in sorting through the available Site columns when adding one to a list. Now I just have to complete any remaining tasks; in this case to add a description, some options, and determine how these will be presented to the user: 
 

The only additional point to keep in mind is that when I go to modify an existing Site Column, I will be presented with the question: 'Update all list columns based on this site column?'. The reason for this is that when I add a Site column to a list, it gets cached as xml in the list itself; the list does not reference some single, central copy. If I make a change, by default, SharePoint will update all the columns based on it, however I may select not to do so. Just remember it is all or nothing; I cannot decide which lists to update, and which to not.

Now when you go to the settings for any list at this level, or lower, this column will appear as one of the options.

SharePoint Content Types

Content Types were created to solve a couple of specific issues involving reusability and flexibility. First off, for clarity, consider the structure of an item in a list, including document libraries, which are now a type of list, is a content type. When you configure a list to contain items with certain data, of a certain type, defaults, required elements, etc., you have defined the content type for that list. Creating definitions for list items this way makes them contained to the list itself, i.e. that type cannot be used in any other list. For example you may want Sales and Marketing to have Client Task items in their respective WSS sites. Without Content Types, you would have to define, and maintain that definition in each list separately; or maybe you want a document type with specific metadata, and template, available to multiple document libraries. Further enhancing reusability is the fact that each Content Type inherits from another, so that you can create one Content Type for the base of our task list items, defining what is shared between types of task items, such as a due date and responsible person, then deriving from that to add what is particular to each type.

The flexibility issue comes into play with Content Types when you want to have a single list that can accommodate multiple types of items. A couple of examples might be that our Marketing department may want to have, in the same list as Client Tasks, Media Tasks for communication with the media. Now all that is possible using SharePoint Content Types by deriving from the same base Content Type as Client Tasks, then defining unique metadata, such Campaign to be pulled from a list of current campaigns.

Enough blather, let's create a couple. To get started go to the same Site Settings page as with Site Columns, and from the same column, Galleries:


 

Selecting Site content types, brings us to the list of currently available Content Types at the site and level that we are at, with a link for each either on the name to the definition page for that content type, or on the source, to the gallery where it is defined. Remember, that like Site Columns, Content Types are available to the site it is created on, and all child sites. It is possible using Collborative Application Markup Language (CAML) to create a definition for one once, then to deploy that definition to any site that we want via a Feature. The Visual Studio Tools for WSS 3.0 can help you with this. Doing it this way also allows us to attach code to the Content Type, such as event handling routines, workflows, etc. ... but I get ahead of myself.

At the top of that list there is a link that sayes 'Create', which takes me to this page:
 

Here I have already entered the new Content Type name, 'SetFocus Task', and given it a description. As I mentioned each Content Type derives from a preexisting one, so in this case I chose to derive from 'Task' which is in the group 'List Content Types'. The last thing I need to do when creating a new Content Type is to decide which group it belongs in. This allows me to filter the list when viewing the full list, or adding one to a list. In this case I chose 'New Group', then SharePointGuy. Clicking OK at this point brings us to a screen very similar to the one when modifying a list:


 

Under Settings there are a number of options. The first is self explanatory. The second takes you to a page that allows you to mark this Content Type as read-only, and another 'Update all content types inheriting from this type?' The latter allows you to push out changes made to the other Settings options, which are outside the scope of this article, to all the derived Content Types. Under Columns it is substantially the same as the same section when modifying a list, as you saw in the last article. For illustrations sake I click the link 'Add from existing site columns', and add the Region Site Column I entered earlier. I also created two more, using this one as the parent Content Type. The first was 'Client Tasks', and I added a site column that  looks up the items in a list of clients that I also created. The second was 'Media Tasks', to which I added a site column that looks up data from a links list.

Using SharePoint Content Types

Now that we have our Content Types, what do we do with them? To use a Content Type in a list, in that list you must first allow management of content types. To illustrate I create a new list using Tasks as the basis. I call it Sales Tasks for the sales department, then go into the settings for the list (Settings --> List Settings). Clicking on 'Advanced settings' brings me to a new page whose first option is 'Allow management of content types?'.


 

Having done that there is now a new section in the list settings page: 


 

I click the 'Add from existing ..' link once and select 'Client Task', and 'Media Task'. Clicking on the link for the existing Task content type, I click 'Delete this content type' to remove the default type from the list (maybe next time Microsoft can make it not seem to ominous) , so that only tasks of the type that I defined are allowed to be added to the list. Another thing that happens when I delete the Task type is that SharePoint will select one of the new content types as the default, in my case 'Client Task'. Now when I click the down arrow next to 'New' on the list's menu I get this:

Depending on which I click, I will get a new item of that type. If I had simply clicked 'New', I would have gone directly to a new item of the type marked as the default. In our example both would differ from a standard task item in that it would contain an additional piece of metadata (column) named Region, that would look up data from out Site Column that we created earlier. They would differ from each other in that a Client Task would have an additional column that looks up its values from the Clients list, and a Media Task would have one that gets its data from the Media Contacts link list. In order to see the data from the new content type, you will need to go into the default view for the list (remember you are never seeing the list per se, only a view of it), and show the columns from one or all of the added content types. For our example I have done that and this is what you now see:


 

The first item is of the type 'Media Task', and the second 'Client Task'. Where Content Types will truly earn their lunch is in the context of document libraries. In that case the types may differ only by the templates used to create new documents. For example, I have a construction company for a client. When they are bidding on a job they need various Word, Excel, and other documents. Then if they get the bid it becomes a job. During the bidding process they need a Excel document based on a specific template for estimating the cost of the job, plus one or two more for other purposes. There are some other templates for creating Word documents that may be needed during the cycle, and other document types such as CAD drawings. Each type needs not only its own template but specific metadata describing the document and exposing it to search. In the past I would have had to create a separate document library for each type, each containing only one or two documents for each job being bid or built. Instead I am creating site templates that will be used to create a new site for each job to be bid, with a single document library containing multiple types.

In wrapping up this topic, I am suggesting, as an exercise to the reader, that you create two new Content Types, both based on the existing Document type, one for Excel documents, and another for Word. When you base a new type on Document, then go into advanced settings, you will have the option to upload a template for that type. Maybe also add some Site Columns to use with your new Content Types. Then create a document library, allow for management of content types, and specify each of the new types you just created. If you added custom Site Columns to the types, then, in the list's settings, edit the default view to expose that metadata. Now, going to that list, click the new button and then the first option. Save the document created from the template associated with that type to the library. Then create a new document for each of the new types that you added, filling in data for each of the extra columns added, if any.

Features

Features, as mentioned above, allow a developer, administrator, or anyone with privileges to copy out data to the 12 hive, run stsadm.exe, and site administrator, to add functionality to a WSS site, or even the farm. Features is one of the 'killer features' of the new version (who says no one at Microsoft has a sense of humor?). First some explanation. When an administrator installs WSS or MOSS, a new folder is created in the CommonProgramFiles system folder, under Microsoft Shared\web server extensions, called 12 (%12% for convenience's sake). Under that folder, or as some refer to it hive, there are a number of other folders that WSS uses to manage itself, the farm, sites, etc. For example if you look under %12%\TEMPLATE\SiteTemplates, you will see the templates for sites that you see when you create a new site. The naming on the file system is somewhat cryptic, agreed, but they are there.

As an experiment, go to the Site Settings for a site, then under 'Site Administration', click the link that says 'Site features'. There you will see a list of all the features available to you at the site level that you are at. There is a button to activate, or deactivate, each one. Now go look at %12%\TEMPLATE\FEATURES and you will see a folder for each one that you see in the feature administration page, plus many more!). Again it may not be obvious as to the naming but they do correspond. For example, you should see a feature for 'Team Collaboration Lists'. In the Features folder this corresponds to the folder 'TeamCollab'. Each Feature's folder has at least one file named feature.xml. If that is all there, such as in the TeamCollab folder, then the feature may be comprised solely of references to other features. If you open the xm file you should be able to make some sense of it. (The references to '$Resources:...' are a topic for another day, but a clue is in the DefaultResourceFile attribute, and the fact that WSS is extremely xml-centric.)

Creating Features

The first step in creating a feature is to have access to an xml editor tool (preferably one that does not add its own gunk, such as Word). I prefer Visual Studio (VS) so that I can create a folder structure away from the 12 hive that duplicates what I want the end result to be, then copy that out to the Features folder. I create a new VS project, then the first thing that I do is to create a folder named Feature. When I am ready to deploy my feature, I can copy out the contents of this folder (but not the folder itself!). Now in that folder I create another that will be the name of my feature, then inside that folder I add an xml file named feature.xml. 


 


To make my life easier I set a reference to the wss.xsd schema in %12%\TEMPLATE\XML folder so that I get intellisense support.

Here is the caml I put in feature.xml:
<?xml version="1.0" encoding="utf-8" ?>
<Feature
      Id="7E6B0F4C-BBF4-47cc-BF1A-9CB47B8888C9"
      Title="SetFocus Feature"
      Description="A feature for use on SetFocus built sites."
      Scope="Web"
      Hidden="FALSE"
      xmlns="http://schemas.microsoft.com/sharepoint/"
   >
   <ElementManifests>
      <ElementManifest Location="setfocus.xml"/>
   </ElementManifests>
</Feature>

The key points to focus on here are the ID attribute, which I created using the VS Create GUID tool (removing the curly brackets), the Scope attribute, which in this case determines that the scope of the feature is on the site on which it is deployed/activated (if you get the intellisense you will see the other options!), and the ElementManifests element. This last refers to a file that has the definition for the feature and where the real power comes from.

The file that the Elements refers to is also an xml file so remember to reference wss.xsd. At the least the file referenced by elements element file will look like this:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
</Elements>

In between the tags is the functionality to be deployed to whatever scope is specified in the feature.xml file, then activated, or not, at that scope. One option is to use the CustomAction tag to modify items in a buit in menu, the Module element to provision additional content such as custom pages, etc. For the sake of my examples, to accomplish the same things using features and CAML. To do this I used the ListInstance element so:
<ListInstance Title="SetFocus Clients"
   FeatureId = "00BFEA71-7E6D-4186-9BA8-C047AC750105"
   TemplateType = "105"
   Id = "SampleContacts"
   Description="SetFocus Clients"
   OnQuickLaunch = "True"
   Url="Lists/Clients"
>

The keys are that the TemplateType attibute refers to the base list this new one is to be based on, and FeatureId is the FeatureId or that base list. In this example my new list is to be based on the out of the box Contacts list. I have also done the same to create another list for links to media contacts based on the out of the box Links list. All the details are out of the scope of this article, but can be seen in this blog post from my blog. In the full example I also show how you can add data when creating the list.

Going back to the first Feature example that references the file 'setfocus.xml', I have multiple Field and ContentType elements. To give a feel for how the Site Columns are defined here is the CAML for the Region column:
<Field ID="{C76C7829-742E-43ae-97FD-A2DEACA8D1D0}"
   Name="Regions"
   Group="SharePointGuy"
   Type="Choice"
   DisplayName="Region"
   SourceID="http://schemas.microsoft.com/sharepoint/v3/fields"
   StaticName="SetFocusRegionStatic"
   Hidden="FALSE"
   Sealed="FALSE"
   AllowDeletion="FALSE"
   Description="Regions for SetFocus"
   FillInChoice="FALSE"
   >

One important thing to notice here is that the ID attribute is the GUID with the curly brackets included, and the Feature will fail without them, unlike other content elements that you can via a Feature that will fail with them included. The other thing to notice is the Type element. Choosing Choice makes this column a choice column. Using sub elements of the Field element, you can add the choices that are available, and the default. I also added a definition for the Departments fields we added via the interface above. I also added another two fields that are lookup from existing lists. The main difference is that the value of the Type attribute is 'Lookup', and there is an additional atribute, 'List', whose value needs to be the ID (GUID) of the list that is to provide the data.

In addition to the Site Columns, I also add Content Types in the same setfocus.xml file. Here is the CAML for the new base task that are to be used as the basis for the two other content types that I created above:
<ContentType ID="0x01080D"
   Name="SetFocus Task"
   Group="SharePointGuy"
   Description="Base Task Content Type for SetFocus Tasks"
   Version="12"
   >
   <FieldRefs>
   <FieldRef ID="{C76C7829-742E-43ae-97FD-A2DEACA8D1D0}" Name="Region"    Required="TRUE" />
   </FieldRefs>
</ContentType>

A few things about this bear mentioning. First is that, recalling that all Content Types derive from one other. How this is accomplished by taking the ID of the type that is to be the basis for the new one, appending some other text to distinguish it. You can find this by going to the 12 folder, and from there 'Template\Features\ctypes\ctypeswss.xml. There I found that the out of the box Task Content Type has an ID of 0x0108, so I then added 0D for the ID of my new Content Type. Also you will notice that the ContentType element has a sub element FieldRefs. This is where you can add additional Site Columns to the new Content Type. Since the ID attribute is the same as the ID of the Regions Site Column created above. Finally the column I add to the new field is Region and make it required.

Deploying Features

The final step in developing your new Feature is to deploy it. Recall from the beginning of this discussion, that each Feature exists in its own folder from the %12%\Templates\Features folder. Create a new folder from here, then copy all you files there, or better yet develop all the files that you will need for your Feature, then copy this entire folder to the Features folder when you are ready to deploy. Keep in mind that the name your new Feature will be the name of this folder. Once having done this you will need to go to a command prompt, and run the tool stsadm.exe that exists in the %12%\bin folder, either by going to that folder, or adding thebin folder to your path. The specific command that you will run is this:
   stsadm -o deactivatefeature -filename SetFocusLists\feature.xml

After that you will need to either run IISRESET, or recycle the aplication pool for the Feature to be available. You can recycle the application pool by running this command from a command prompt:
   %windir%\system32\cscript.exe c:\windows\system32\iisapp.vbs /a "Name of your Application Pool" /r

The final step is to activate your Feature. Where in the interface you do this depends on the value of the Scope attribute in the feature.xml file. If you selected Farm you will need to go to the Central Administration page, click the Operations tab, then under 'Global Configuration', 'Manage farm features'. If you chose Web or Site then go to the site collection you targeted with the -url parameter of the stsadm command, then Site Settings. If the scope was web, then go to 'Site features' under 'Site Administration'. If the scope was Site then under 'Site Collection Administration' choose 'Site collection features'. In either case you should see your Feature, with a buton next to it saying 'Activate'. If you do not see your feature, then it did not install, so you will need to investigate.

Solutions

The last piece of this puzzle is Solutions. What this allows you to do is wrap up all the pieces required by your Feature into a CAB format, then run the stsadm command using the -o installsolution parameter. Once you do this you can go to Central Administration, then within the operations page, you can go to 'Solution management', and push the feature out to sites. If you use the Visual Studio Extensions for WSS, then Visual Studio will do it for you.

Conclusion

An essential reference for creating CAML is the Windows SharePoint Services SDK. In there you can find all the possible elements and the options for all of them. Also you will want to try as many of the elements and attributes that you can by using IntelliSense, assuming that you reference the wss.xsd schema in your xml files.

As I hope you have seen there are some very powerful and useful tools in WSS v3 for customizing your sites. Using these tools you can easily and productively create some very unique site customizations that are tailored for your sites. Again you can see all the details of the Features discussed here by going to this blog entry.

About the author:

Robert Holmes is a software developer from the Boston area working almost exclusively with Microsoft products for over ten years. Over that time he have worked extensively with Visual Basic, MS Access, and Office product development as an independent consultant for a variety of organizations of all sizes, in both the public and private sectors.

Over the last 4 years Robert has been heavily invlolved with .NET technologies as a developer, user group leader and presenter, the last two using SharePoint heavily as a collaboration, and application platform. Robert has been involved with the current version of SharePoint technology since the beta 1 days in February of 2006, and is currently involved in the deployment of MOSS at two medium sized companies. Robert is available for development work as well as mentoring and guidance.

Contact Robert:


   Email this pageprinter-friendly version   

Add the above content to:


 Google   Y! MyWeb   Furl   Simpy   Spurl   Blink  Del.icio.us   Digg  add to technorati Technorati


Microsoft Certification | Visual Studio 2005 | SQL Server 2005 |.NET Framework
HomeApply Now  | Master's Program℠  |  Corporate Services  |  .NET Courses  |  .NET Resources  |  Site Map  |  Trademarks