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.

ContentTypeDisplayForm

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.

ctypeswss.xml

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.

DocumentContentType

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.

defaulttemplates.ascx

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:

Bform

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.

  1. Start out by creating a new .ascx file in the [12]\TEMPLATE\CONTROLTEMPLATES folder.
  2. 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” %>

  1. 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:

CustomForm

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.

  1. 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.
  2. In a test list, go to list settings and then Advanced Settings. Enable ‘Allow management of content types’ and hit Ok.
  3. Back in the site settings, add a content type from existing site content types, and add your new content type.
  4. 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.

  1. 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.
  2. Browse to the site where you created your content type and open the Content Types node. Locate your new content type.
  3. 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.

SPM2007

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:

MyListForm

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

Twitter Digg Delicious Stumbleupon Technorati Facebook Email
  • Pradeep Kumar
    Dear Author,
    It's a nice description about Content type.
    As a beginner I got the required information about it.

    I want to know whether a datatype of a column in Content type after connected to a List can be changed.

    Hope,i would get a response.

    Thank You
    With Regards
    Pradeep
  • Ivan
    Great post! I will say that I was giddy with excitement thinking I had an answer to a perhaps-simple question. I did not, so I'll ask you here, If I may. I wanted to change the user experience after creating a new content type. The user pulls down from the list of content types available and selects one. The form that appears basically says: "New Item". How can I change to say "New [Insert Content Type Name Here]", instead of the generic "new Item?".
  • Susi
    I have shared document library which consist of word documents. When I click on the new document or any document template it opens an editor and it prompts for content type at the time of saving. but what I need is when the new button is clicked i dont want the editor to open but i need the content type prompting and add the file to the document library. I am not sure how to do it, nay help pn this issue is higly appreciated.
    Thanks,
  • I'm not sure I fully understand your question. Do you want just a random document to be added when you hit new? I'm not certain where such a scenario would be appropriate, but you can certainly override the 'New' button, and menu, to do mostly whatever you like. I'll encourage you to look at part 3 of this series to get an intro to CAML and then look at how the New item on the toolbar gets contructed. You might also be able to do this using a CustomAction, briefly described in part 2 of this series.

    .b
blog comments powered by Disqus