If you have been following my recent posts, you will be aware that I have been trying to skill up on Content Types, and in thinking about them, I wondered if the vision I had of them is based in reality or not.
My initial thoughts were that I could create a Content Type, ensure that it had all the fields I really wanted to capture about a piece of Content, deploy it and let my users use the Type without breaking it, but still allow them to add additional metadata to lists as required.
A practical example of this might be a Project Task list, where I want to be sure I capture the Client and Project Names, and obviously task columns such as due date etc, but a user I have likes to add additional columns to any Task related lists, such as a purchase order number. For them this data is required on certain jobs as they don't get paid without it, but not on others. So, I don't want purchase order to be on my base list of columns as it is only used infrequently and it's not always required.
So my plan was to created some sort of read-only Content Type which I could deploy and users could use in their task list - I might even make it part of a solution, but where the could also add their own relevant meta-data.
Making a Content Type read-only is not really what I want though, because making it read-only through the UI from the Advanced Settings page, doesn't really cut it. Any user who has manage list rights can go and make it read-only, and my users need manage list rights in order to add their additional columns!
The answer is to make the Content Type Sealed! Sealing a content type is something only a Site Collection Administrator can do, and you can't do it through the UI, only via a Feature or the Object Model (acontenttype.sealed=true;). Once a Content Type is sealed, no one can make any changes to it, the columns within it no longer have urls to edit pages and you cannot un-seal it as a user with Manage List rights.
So I created a feature with a new site column and a Content Type to test the theory.
Here is the Column definition and save it as SampleColumn.xml:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<Field ID="{C5054CF3-6DFB-4af1-B395-AE5590E787FF}"
Name="SampleNote"
DisplayName="Sample Note"
Group="Sample Site Columns"
Type="Note" ShowInListSettings="FALSE"/>
</Elements>
Note that I added the ShowInListSettings="FALSE" attribute too. This is because even though no one can edit my Content Type, people can still delete or edit the column once the Content Type is added to the List just by clicking on it - so I hide it so as not to tempt them!
Now I create a Content Type and save it as SampleContentType.xml:
<Elements xmlns="http://schemas.microsoft.com/sharepoint/">
<ContentType ID="0x010100EB12092854E04d8aB59FDEFF336FA6B2"
Name="Sample Content Type"
Group="Sample Content Types"
Description="..."
Version="0" Sealed="TRUE">
<FieldRefs>
<!-- Add the Sample Site Column -->
<FieldRef ID="{C5054CF3-6DFB-4af1-B395-AE5590E787FF}" Name="SampleNote" Required="TRUE"/>
</FieldRefs>
</ContentType>
</Elements>
And, finally a Feature.xml to install my bits:
<Feature Id="61336D8A-984B-491c-99DA-A97ED1759950"
Title="Sample"
Description="This feature..."
Version="1.0.0.0"
Scope="Site"
xmlns="http://schemas.microsoft.com/sharepoint/">
<ElementManifests>
<ElementManifest Location="SampleColumn.xml" />
<ElementManifest Location="SampleContentType.xml" />
</ElementManifests>
</Feature>
Then I install the feature, create a list and add the content type to it. So, not I have a content type no one can break, and a field people can see in the add and edit forms, and use in views, but can't delete or change the settings of!
Almost there, but NOT! Now if I try and add a new field to the list the magic disappearing column problem happens. Because my Content Type is sealed, even when the Add to All Content Types checkbox is checked for the new field, it does not show up in the Add and Edit forms, because it can't be added to my Content Type.
So, either I deal with the fact that users can't add their own columns and be happy that I can force them to use only my columns (without changing them), or I don't Seal my Content Types, and don't give anyone Manage List rights and the IT department (or some lucky person) gets to do all the changes to lists that I'm worried about.