Customizing the User Experience of SharePoint: Content Type User Interface (Part 4 of 6)
After a considerably shorter break, it is time for the fourth part of the “Customizing the User Experience of SharePoint” series. This article is also the second day of SharePoint User Experience week here on SharePoint Magazine. One full week, focusing only on understanding SharePoint architecture from a user experience point of view. Christmas all week long, if you ask me.
The Customizing the User Experience of SharePoint series aims to explain how the user experience works, from how the interface is built down to details on how columns in lists get created.
The series is also an exclusive preview of the topics from my upcoming book, “Building the SharePoint User Experience”, which deals with SharePoint user experience for 350 pages. Actually, as with this series, the book explains the SharePoint architecture from a user experience perspective.
Here is an article outline for the six parts:
Part 1: Overview of the default SharePoint interface from a technical point of view
In the first article we will look at how the default SharePoint interface is built. We will look at a site, going from top-down, explore some of the the default lists, the fields used to create the basic field types, which content types are available, and how list forms are rendered.
Part 2: Modifying the default experience
This article will show you which options are available for you to modify and improve the default setup. Learn how to override the default rendering of fields or forms without voiding your supported state.
Part 3: Lists and custom list forms
The third article will cover the basics of customizing lists using different views, custom list forms, and fields.
Part 4: Content types user interface
The next article will explore how you can utilize content types to display different input forms and display forms.
Part 5: Custom fields deep dive
Ever wanted to create a new field type? SharePoint enables you to do this and it is a very powerful tool for customizing the user experience.
Part 6: Fast track to feature generation
Writing custom lists with content types by hand can take a massive amount of time. In the final installment I will share with you some tools and techniques that makes list, field, and content type generation very fast.
This time, however, we’ll focus on a really cool feature of SharePoint…
Content Types
If you haven’t worked with content types before you haven’t worked with SharePoint since WSS2 and the SPS2003 era. You may not realize this, but Content Types are the method by which you store data in SharePoint, whether you like it or not.
Content Types are schemas for information, defining what your items or documents should contain, how they should behave, and, most importantly for us in this article, how they should appear.
Before we go into user experience customization of content types, you should also know a few more things about content types:
- Everything stored in SharePoint uses a content type, even if you do not explicitly enable content types on a list or library.
- Folders themselves are just special items created from a folder content type.
- Content types can also store metadata about their derived items.
- Content Types support inheritance, meaning you can have a content type hierarchy and store common information in a parent type.
- Scoping of content types means you can target content types to specific site collections or sites and have child sites have access to the same content types.
The second issue of Understanding SharePoint Journal deals exclusively with content types, showing off some of the magnificent things you can accomplish if you understand this technology.
However, for this article we will focus on learning how we can make content types appear the way we want.
The Anatomy of a List Form
As we have explored earlier in this series, list forms are customizable forms used to display, edit, or create new items in a list. These forms are made up of form pages, which we can customize to make a nicer interface for the users. For most of the default list templates in SharePoint, a single ASP.NET page, the [12]\TEMPLATE\Pages\form.aspx page, is used to render all list forms.
However, in a single list we can have multiple content types. For example we can have a document library store both Financial and Legal documents, each of which may require a separate set of metadata. There must be a way for SharePoint to know which set of metadata to display or which form fields we need to fill in to update or create an item.
The answer is that a list form is made up of two parts. One is the list form page, which determines the outline of the form. The other part is the content type form, which defines the specifics of the individual item or document.
In the above image, the area inside the red square is made from the content type’s display form, while the rest of the page is made up of the list’s display form. Of course, the list form page can also be made up of master pages and regular content, as is the case for all the default list forms.
There is also another option, which is to have the whole page tied to a content type. In such a case, the list form page would not be used at all. We will look at this in a moment.
Now, to understand how this anatomy is constructed we need to dig a bit into how content types are created and learn a bit about how content type inheritance works.
As you would also know you can override these forms by creating a new .ascx user contol in the CONTROLTEMPLATES folder and put a SharePoint:RenderingTemplate control inside with the same ID as the template you want to replace.
Content Type inheritance
Content types support inheritance, with a bit of a peculiar method of defining inheritance. In simple terms this means that you can create a hierarchy of content types, just like a class hierarchy, and have child content types inherit properties from parents and grandparents.
What differs significantly from other hierarchical systems is a rather awkward method for describing inheritance in SharePoint content types. Every content type in SharePoint has a unique identifier, the content type Id. When you create a content type you define a content type id that is of the format 0xNNNNNNN where NNNNNNN is a number. That number not only identifies this content type but also from which parent content type we should inherit. That’s right, no kidding, inheritance is hidden inside the identifier string.
All you need to do to inherit from a content type is to include the parent content type id in your content type id and then add a few numbers.
Crafting Content Type IDs
Oh, yeah, how you add those numbers matter a great deal. Let’s look at the default content types to see how this is done. Open the [12]\TEMPLATE\FEATURES\ctypes folder and then the ctypeswss.xml file. This is where all the default content types are defined.
First, notice that the first ContentType element, named System, has an ID value of 0x. All content types must inherit at least from this system content type. The type itself defines only a single column or field reference, the ContentType field.
The next content type is the Item content type, and you can see from the ID value the first method of creating inheritance. Adding two numbers, for example 01, 02, or 99, is one way of inheriting from a parent type. If you wanted to inherit directly from System you could have your content type have and id of 0×02, 0×03, etc.
The other method for crafting content type ids is to add 00 and then a Guid string without the hypens. For example you may have an id that inherits directly from Item as such:
0x01001A48C1A2B071432EACA85A0A35FF5185
Break that ID down and you will see System (0x), Item (01), two zeros (00), and a GUID (1A48C1A2B071432EACA85A0A35FF5185).
The properties of a content type are inherited from its parent. In the Item content type this means we inherit the ContentType column from System, and, as you can see, adds a new field, the Title field. In addition the Item content type defines an XmlDocument which contain a FormTemplates element. Inside the FormTemplates are names of forms that will be used for display, edit, and new forms for items based on the Item content type. And, knowing that these properties are inherited we can deduce that all content types inheriting from Item will use the ListForm template.
Overriding property inheritance
Now, using the same form for all content types may be a bit too limiting for you. You’ll be thrilled, I’m sure, to learn that you can override any property for child content types simply by adding an overriding value. The Document content type is an examle of this. To examine property overriding, scroll further down in the ctypeswss.xml file to the Document content type, which, in my file, is around line 32.
Notice that the Document content type adds the Title field again, even if it is added in the parent Item content type. If you examine the FieldRef elements of Item and Document, however, you will notice that the attributes differs. This way, in Document based items, the Title is not required, and will not appear in NewForm.
Item Title FieldRef:
<FieldRef ID=”{fa564e0f-0c70-4ab9-b863-0177e6ddd247}” Name=”Title” Required=”TRUE” ShowInNewForm=”TRUE” ShowInEditForm=”TRUE”/>
Document Title FieldRef:
<FieldRef ID=”{fa564e0f-0c70-4ab9-b863-0177e6ddd247}” Name=”Title” Required=”FALSE” ShowInNewForm=”FALSE” ShowInEditForm=”TRUE”/>
Another thing to notice is that Document also overrides the FormTemplates to replace these with DocumentLibraryForm.
Customizing Content Type Forms
Now, as I am certain you have been reading the first and second parts of this series you know a few things about where these forms are actually stored. To remind you, the default forms used by SharePoint, such as ListForm and DocumentLibraryForm, as stored in the [12]\TEMPLATE\CONTROLTEMPLATES\DefaultTemplates.ascx file.
However, that may not be a possibility for you. First of all, overriding is am all-or-nothing deal; you override for all templates throughout the farm. Second you can only override once, meaning if you have overridden the ListForm template once you cannot add a second ListForm template and expect some magic to determine which one will be used. In fact, from what I’ve been able to deduce, file naming determines which rendering template will be used if you add two templates with the same Id. In the next image I have added two rendering template files, one called aform.aspx and one called bform.aspx, both of which simply displays a text, either A or B, and as you can see, the B Form is used:
However, I do not actually know this since this part of the code in Microsoft.SharePoint.dll is obfuscated.
Still, nothing prevents us from creating our own forms for use with our own content types.
- Start out by creating a new .ascx file in the [12]\TEMPLATE\CONTROLTEMPLATES folder.
- Name it whatever you like. Next, copy the directives from the defaulttemplates.ascx file:
<%@ Control Language=”C#” AutoEventWireup=”false” %>
<%@ Assembly Name=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
<%@ Register TagPrefix=”SharePoint” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”
Namespace=”Microsoft.SharePoint.WebControls” %>
<%@ Register TagPrefix=”SPHttpUtility” Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c”
Namespace=”Microsoft.SharePoint.Utilities” %>
<%@ Register TagPrefix=”wssuc” TagName=”ToolBar” Src=”~/_controltemplates/ToolBar.ascx” %>
<%@ Register TagPrefix=”wssuc” TagName=”ToolBarButton” Src=”~/_controltemplates/ToolBarButton.ascx” %>
<%@ Register TagPrefix=”WebPartPages” Namespace=”Microsoft.SharePoint.WebPartPages”
Assembly=”Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c” %>
- Then, just to make things simple, copy the ListForm rendering template from the same file, but change the ID from ListForm to MyListForm. Make some random change to recognize your custom form, for example by adding My list form after the Span HTML tag:
Congratulations, you’ve just created a new content type form.
Now you need to attach it to a content type. I’ll walk you through a simple example to demonstrate.
- Create a new site content type from the site settings page. Name it whatever you like, and inherit from the Item content type. Add some site columns if you like.
- In a test list, go to list settings and then Advanced Settings. Enable ‘Allow management of content types’ and hit Ok.
- Back in the site settings, add a content type from existing site content types, and add your new content type.
- Go back the list and add a new item based on your content type.
Now we have an actual content type to which we can attach our new form.
- Get SharePoint Manager 2007. Yeah, it’s free, and it’s the best tool you’ll ever own, including whatever free chocolate machine you may already have.
- Browse to the site where you created your content type and open the Content Types node. Locate your new content type.
- In the properties window, locate the DisplayFormTemplateName. Notice that it is set to ListForm. Change this to MyListForm and then hit Save. I’ll repeat the last instruction. Hit Save.
In case you missed it, you need to hit Save before your changes are added to SharePoint.
Next, re-open your item in the list.
And at this point you are likely going to be very angry with me because your form will not work at all and be completely blank. However, there is a very reasonable explanation for this, and I just wanted you to see this error, since I make it myself all the time.
You see, control templates are only read after an IISRESET. So, to make your wonderful new form appear, simply IISRESET (c:\>iisreset) and your form should appear just fine, including your customizations:
Cool, eh?
Stop being so cool!
Ok, I think we had enough for this article. We’ve covered the basics of content types and examined how inheritance works. You’ve seen how content types are defined and also how you can create your own content type forms.
However, this is only the beginning of content types. If you think what you have seen here is cool, issue 2 of Understanding SharePoint Journal will totally blow your mind. We’ll examine behavior with workflow and event receivers, look at how folders are content types and how you can use this in SharePoint, and also how you can extend your content types using XmlDocuments.
As of this writing, issue 2 is not out yet, but you can always sign up for the Understanding SharePoint Journal mailing list to be notified when the issue ships. Or, if you are reading this article later than the issue date you can visit the USP Journal webpage and grab a copy.
The next part of this series will deal with columns and field types, teaching you the basics you need to understand how these elements influence the user experience.
Until next time, however I hope you have a great time with what you’ve learned here.
.b



24. Feb, 2009 








Author