List columns in a SharePoint content type? How is that possible?

One thing struck me as odd. SharePoint content types can only contain references to existing site columns. You cannot add a new column to a content type, you must first create a new site column and then add that site column to the content type. You shouldn’t be surprised at this if you have developed a few content types in your life.

So, tell me, or actually, I’ll tell you in a moment, why, when you have multiple content types in a list, and you create a new list column, are you asked whether you want to add the new list column to all content types?

21.03

This really shouldn’t be possible. SharePoint content types can only contain references to site columns, and, last time I checked, list columns != site columns.

Not just that, but by default, if you only have a single content type in your list or library, any new list or library columns are automatically added to the default content type. This puzzle must be solved!

The mystery becomes clearer if you examine how a content type is stored in SharePoint. You can do this by examining the output from the SPContentType.SchemaXml property, or, as I do, use SharePoint Manager 2007 to examine this property.

If you have read the Fast Track to Feature Generation on SharePoint Magazine, or the expanded version in Building the SharePoint User Experience book, you know that the SchemaXml output is not directly usable for a new content type defined in CAML. In fact, when you export the SchemaXml property you get Fields instead of FieldRefs, and you need to change the Field elements to FieldRef elements in order for your content type to be deployable as a feature.

The SchemaXml property of a content type contains Fields because SharePoint does not store the references to site columns at all, but rather makes a copy of those columns and stores the copy as a Field in the content type.

You may wonder why this is a good idea. The reason, quite simply, is that it allows you to customize a list column on a content type basis. You may have seen the most basic of examples of this if you go to edit a site or list column in a content type, where you will be allowed to change the required, optional, or hidden state of a column.

Figure2

Now, with this knowledge you might think that since a content type stores fields you should be able to modify other settings than required, optional, and hidden. For example, you might want to do something like this:

SPContentType ct = list.ContentTypes[“My Content Type”];

SPField field = ct.Fields[“List column”];
field.Title = “Custom list column”;
field.Update();

but if you do you will only get an exception, “This functionality is unavailable for fields not associated with a list.”

Dang!

Fear not, young Skywalker, there is help in another method, namely updating the FieldLinks of the content type:

SPContentType ct = list.ContentTypes[“My Content Type”];
SPFieldLink fieldLink = ct.FieldLinks[“List_x0020_column”];
fieldLink.DisplayName = “Customized list column”;
ct.Update();

Note that you must reference the internal name of the column (List_x0020_column) instead of the display name, and that you update the content type (ct.Update()) instead of the SPFieldLink.

The result?

Figure3

Cool, eh? Sadly, the default SharePoint user interface does not let you change this.

Before I let you go I just want to show you the IntelliSense list for SPFieldLink, because it holds and interesting property:

Figure4

See the Customization property? I have absolutely no idea what that does. The documentation doesn’t say, and as far as I have been able to tell, it is not used in any default SharePoint functionality. Reflecting the SPFieldLink class reveals nothing interesting; just a fairly standard getter and setter, a slightly more complex setter, but otherwise nothing special.

Perhaps this could be used for something interesting? I can certainly think of scenarios where having custom data connected to a particular column in a particular content type might be useful.

I’ll leave that for another show.

.b

Found this article valuable? Want to show your appreciation? Here are some options:

a) Click on the banners anywhere on the site to visit my blog's sponsors. They are all hand-picked and are selected based on providing great products and services to the SharePoint community.

b) Donate Bitcoins! I love Bitcoins, and you can donate if you'd like by clicking the button below.

c) Spread the word! Below, you should find links to sharing this article on your favorite social media sites. I'm an attention junkie, so sharing is caring in my book!

Pin It

Published by

Bjørn Furuknap

I previously did SharePoint. These days, I try new things to see where I can find the passion. If you have great ideas, cool projects, or is in general an awesome person, get in touch and we might find out together.

10 thoughts on “List columns in a SharePoint content type? How is that possible?”

  1. Bjorn,

    Don’t get confused between “Site Content Types” and “List Content Types” – they’re not the same!

    As you’ve seen, when you add a content type to a list, you’re actually adding a child of the Site content type to the list. Changes to that child won’t affect the parent – though obviously the reverse isn’t true!

  2. Andy:
    Thanks for mentioning this, it might not be known to all users. At least not to those who have not yet read the lastest Understanding SharePoint Journal :-).

    However, technically you are incorrect. Site content types and list content types are both stored in the ContentTypes SQL table. There are stored in exactly the same fashion. So, they are very much the same, from a technical point of view.

    The techniques shown here, however, apply to both list content types as well as site content types.

    .b

  3. I’m using the following code to add a link between the ContentType and the Custom List:

    //list is the SPList
    SPContentType ct = list.ContentTypes[“My Content Type”];
    SPFieldLink fieldLink = ct.FieldLinks[“InternalName”];
    fieldLink.DisplayName = “Customized list column”;
    ct.Update();

    The problem that i’m facing is : the DisplayName does not appear in the CustomList but it does in the ContentType.
    did you face such issue? if yes, can you post the solution?

    Thank you in advance.

    1. Jamil,

      Keep in mind, your view has columns independent of the content types. You need to update the views of your list in order to get the column visible there.

      .b

  4. Hello Bjorn,

    We have a library that is inheriting from the Parent Site Collection a Content Type called Policy. Now each department will have different policies so, within their own document libraries where they are using the Policy Content Type, they are adding a Site Column called PolicyType. The Policy Type Column is getting values from a list and at the bottom of this configuration, they are checking off the option to “Apply to all Content Types”. So they would like for this column (PolicyType) to also be applied to other CT’s added to the library.

    The problem is that this new column is not applying to all Content Types within the Library.

    Can you offer any comments on this as I am sure that we are misunderstanding the use of this function (Add to all Content Types).

    Thank you so much!
    Tim

    1. Hi Bjorn,

      I have discovered part of the problem. The users created READ ONLY content types at the parent level so when they created a new site column at the library level and checked off “Add to existing Content Types” the column could not be added.

      Now that they have unchecked READ ONLY, how can we get that column to apply to the Content Type at the library level. There is no refresh at the column settings page.

      Thoughts?

      Thank you Bjorn!

Leave a Reply

Your email address will not be published.