All about Microsoft Office SharePoint Server Content Type – Part 1

In this article I would like touch upon the following areas.

  • What is a content type
  • How content types work
  • Extending content types
  • Attaching Workflows to a content type
  • Attaching event handlers to a content type
  • Deploying a content type as a feature

What is a Content Type:

A content type is a reusable settings that describe the shared behaviors for a specific type of content. or in other words Content types enables us to manage the metadata and behavior of a document or a list item type in a centralized manner, that is reusable.

Content types can be defined for documents, list items, folders. Content types can be used organize content across multiple lists and libraries across the site collection. Also a list or a library can contain references to multiple Content types.

How Content types work:

Content Type Terminologies:

  • Site Content type – Content types are created at the site level and they act as a template which can be instantiated in a list under a sub site.
  • List Content type – The instance of the Site content type is called a list content type. When we add a site content type to a list SharePoint creates a copy of the Site content type  onto the list.
  • Content type scope – The scope depends on the site where the content type is created. The content type is then available to all the sub sites.
  • Parent content type – All the content types follow a hierarchy. The following image(Fig – Base content type hierarchy) shows the relationship between the different content types. Ultimately all the content types inherit from System content type.
  • Groups – Categorizing content types into groups to make it easier for users to find them.(Fig – Content Type Groups)

Base content type hieararchy

Fig – Base Content type hierarchy

image

Fig – Content Type Groups

 

Creating a new List Content Type :

In this example we are going to create a new content types called Project Task

  • Go to the Site or Site Collection top level site where you want to create the content type.
  • On the Site Actions menu click Site Settings
  • In the Galleries column select Site content types

image

 

  • This opens the gallery listing all the existing site content types, click Create
  • Enter the Content type name as ‘Project Task’ and choose ‘List Content Types’ group and ‘Item’ as the Parent Content Type and click OK.

  image

  • The content type gets saved and navigates to the admin page of the content type. Go to Columns section and click ‘Add from new site column’. We will now create new site columns to be added to this content type.

image

 

  • Add 2 columns Project Task – Single line of text, Project Details – Multiple lines of text.

image

image

  • Go to the custom list to which we are going to associate this new content type.
  • Click Settings->List Settings->Choose Advanced settings from the General Settings section.
  • Make sure that the ‘Allow management of content types’ is selected.

image

image

  • Get back to the settings page and select ‘Add from existing site content types’

image

  • Choose the ‘Project Task’ from the list box and click ‘Add’ and click OK.
  • Now we are done with associating a content type with the list.

image

  • Now when you click ‘New’ from the list’s all items view page you will see an option ‘Project Task’

image

  • This opens a new item page with the columns that we associated with the content type.

image

  • At this point the list has instantiated a copy of ‘Project Task’ content type. Lets see how it behaves when we update the content type. Let us add a new column called ‘Task Owner’.  Go To Site Actions->Site Settings->Site Content Types->Select the ‘Project Task’ content type->Go to columns Section and click ‘Add from new site column’.

image

image

  • Enter ‘Task Owner’ in the column name and choose ‘Person or Group’ and make sure the ‘Update all content types inheriting form this type’ is selected.(default selection)
  • Go back to the Project Tasks list which uses the ‘Project Task’ content type->Click New Project Task. Here you will see the newly updated column Task Owner appearing in the form.

image

Creating a new Document Content Type :

In this example we are going to create 2 new document content types called Project Proposal and Technical Design and associate it with a document library named Project Documents 

  • Go to the Site or Site Collection top level site where you want to create the content type.
  • On the Site Actions menu click Site Settings
  • In the Galleries column select Site content types
  • This opens the gallery listing all the existing site content types, click Create
  • Enter Project Proposal as the name of the content type and choose Document under the Document Content Types group. Click OK.

image

  • The content type gets saved and navigates to the admin page of the content type. Go to Settings section and click ‘Advanced Settings’. We can associate a document template that is available in the site or can associate a document template from your local computer. In this case I have chosen to associate a .dotx template i have in my local drive.

image

image

  • Repeat the above steps and add a new content type called ‘Technical Design
  • Go to the ‘Project Documents’ document library to which we are going to associate the content types. Click Settings->Document Library Settings->Advance Settings->Make sure that the Allow Management of content types is selected.

image

  • From the content types section choose ‘Add from existing site content types’
  • Select ‘Project Proposal’ and ‘Technical Design’ from the Available site content types. Click OK

image

  • Remove the default document content type.
  • Go to the Project Documents library and now you will have 2 options in the ‘New’ menu option.

image

Creating a new Folder Content Type :

Now imagine that we should have 2 folders, one for the Project Proposal Documents and one for the Technical Design Documents. And those folders should host only the respective type of documents.

  • Go to the Site or Site Collection top level site where you want to create the content type.
  • On the Site Actions menu click Site Settings
  • In the Galleries column select Site content types
  • This opens the gallery listing all the existing site content types, click Create
  • Enter ‘Proposal Documents’ as the name of the content type and choose Folder under the Folder Content Types group. Click OK.
  • Create another folder content type with another name ‘Proposal Documents’

image

  • Go to the Project Documents library->Document Library Settings->Under the content types click ‘Add from existing site content types’.
  • Select ‘Design Documents’ and ‘Proposal Documents’ and click OK

image

  • Go back to the Project Documents library->Document library settings->Advanced Settings->Set the Display ‘New Folder’ to No.
  • Go back to the Project Documents library and click ‘New’ you will now see the 2 new folder content types.

image

image

  • Create a new Folder for Design Documents. Lets say we name it as ‘Design Docs – 2009
  • Select ‘Change New Button Order’ option from the folder context menu.

image

  • Choose ‘Technical Design’ (document content type we added earlier. refer to the creating a document content type in this same article) and unselect all other content types

image

  • Now when we click ‘New’  in the Design Docs – 2009 folder you will see the ‘Technical Design’ document as the only option.

image

* To be continued in Part 2 of the post

Useful Links:

Part – 1 , Part – 2 , Part – 3 , Part – 4

Querying SharePoint Calendar for Recurring Events using CAML Query

Calendar items in SharePoint fall into several categories. Single events are those which don’t repeat and only appear once on the calendar, while recurring events may show up any number of times depending on the recurrence pattern selected by a user.

 

Recurring event pattern is set using the options presented when the ‘Make this a repeating event’ checkbox is selected.

image

 

Querying SharePoint Calendar list is a bit tricky. Let me run through the following query scenarios:

  • Querying for all the events that has the start or end date matching current date.
  • Querying for all the events that happens in the same week of a given date.
  • Querying for all the events that happens in the same month of a given date.
  • Querying for all the events that happens in the same year of a given date.

I created a repeating event starting from Jan 1, 2009 with no end date.

Querying for all the events that has the start or end date matching current date :

 
Code :
using (SPSite oSPSite = new SPSite("http://myserver/sites/Events"))
            {
                using (SPWeb oSPWeb = oSPSite.OpenWeb())
                {
                    tSPList = oSPWeb.Lists["EventsCalendar"];
                    CalDate = new DateTime(2009,2,1);
                    oQuery.ExpandRecurrence = true;
                    oQuery.Query = "<Where><DateRangesOverlap>;
<FieldRef Name='EventDate' /><FieldRef Name='EndDate' />
<FieldRef Name='RecurrenceID' /><Value Type='DateTime'><Today />
</Value></DateRangesOverlap></Where>"
                    oQuery.CalendarDate = CalDate;
                    tSPListItems = tSPList.GetItems(oQuery);
                }
            }

In the above snippet note that the value is sent as “Today” and the date set as Calendar date is Feb 1, 2009

 

<Value Type='DateTime'><Today /></Value>

 

This will result in fetching all the events that has the start or end date coinciding with today’s date.

The result bound to the grid will look like this

 

image

It shows all the events happening on Feb 1, 2009

 

Querying for all the events that happens in the same week of a given date :

 
Code :
 
using (SPSite oSPSite = new SPSite("http://myserver/sites/Events"))
{
    using (SPWeb oSPWeb = oSPSite.OpenWeb())
    {
        tSPList = oSPWeb.Lists["EventsCalendar"];
        CalDate = new DateTime(2009,2,1);
        oQuery.ExpandRecurrence = true;
        oQuery.Query = "<Where><DateRangesOverlap><FieldRef Name='EventDate' />;
        <FieldRef Name='EndDate' /><FieldRef Name='RecurrenceID' />
        <Value Type='DateTime'><Week /></Value>
        </DateRangesOverlap></Where>"
        oQuery.CalendarDate = CalDate;
        tSPListItems = tSPList.GetItems(oQuery);
    }
}

In the above snippet note that the value is sent as “Week” and the date set as Calendar date is Feb 1, 2009

 

<Value Type='DateTime'><Week /></Value>

This will result in fetching all the events that has the start or end date coinciding with that week The result bound to the grid will look like this

image

It shows all the events starting from Feb 1, 2009 till Feb 8,2009 (Sunday to Sunday) . It is actually picking all the days from the current week and also one extra day from the next week !. The result remains the same for input dates starting Feb 1 through Feb 7.

 

Querying for all the events that happens in the same month of a given date :

 
Code :
 
using (SPSite oSPSite = new SPSite("http://myserver/sites/Events"))
{
    using (SPWeb oSPWeb = oSPSite.OpenWeb())
    {
        tSPList = oSPWeb.Lists["EventsCalendar"];
        CalDate = new DateTime(2009,2,1);
        oQuery.ExpandRecurrence = true;
        oQuery.Query = "<Where><DateRangesOverlap><FieldRef Name='EventDate' />;
        <FieldRef Name='EndDate' /><FieldRef Name='RecurrenceID' />
        <Value Type='DateTime'><Month /></Value>
        </DateRangesOverlap></Where>"
        oQuery.CalendarDate = CalDate;
        tSPListItems = tSPList.GetItems(oQuery);
    }
}

In the above snippet note that the value is sent as “Month” and the date set as Calendar date is Feb 1, 2009

 

<Value Type='DateTime'><Month /></Value>

 

The results that are fetched with this query is a little confusing !!!

image

image

image

 

It gets the events that occurred in the last 7 days from the Jan, 2009 and the entire month from Feb , 2009 and last five days from March , 2009.

Querying for all the events that happens in the same year of a given date :

 
Code :
 
using (SPSite oSPSite = new SPSite("http://myserver/sites/Events"))
{
    using (SPWeb oSPWeb = oSPSite.OpenWeb())
    {
        tSPList = oSPWeb.Lists["EventsCalendar"];
        CalDate = new DateTime(2009,2,1);
        oQuery.ExpandRecurrence = true;
        oQuery.Query = "<Where><DateRangesOverlap><FieldRef Name='EventDate' />;
        <FieldRef Name='EndDate' /><FieldRef Name='RecurrenceID' />
        <Value Type='DateTime'><Year /></Value>
        </DateRangesOverlap></Where>"
        oQuery.CalendarDate = CalDate;
        tSPListItems = tSPList.GetItems(oQuery);
    }
}

In the above snippet note that the value is sent as “Year” and the date set as Calendar date is Feb 1, 2009

 

<Value Type='DateTime'><Year /></Value>

 

The results that are fetched with this query continues to baffle me !!!

image

image

 

It gets all the events that occurs starting from today Feb 20, 2009 all the way through Feb 19, 2011.

 

 

I have no clue why the Month and Year filters did not work as someone would expect…

SPDisposeCheck Tool is available now !!!

SharePoint Dispose Checker Tool is available now for download.

 

SPDisposeCheck is a tool to help you to check your assemblies that use the SharePoint API so that you can build better code. It provides assistance in correctly disposing of certain SharePoint objects to help you follow published best practice. This tool may not show all memory leaks in your code. Further investigation is advised if you continue to experience issues.
SPDisposeCheck.exe takes the path to a managed .DLL or .EXE or the path to a directory containing many managed assemblies. It will recursively search for and analyze each managed module attempting to detect coding patterns based on the MDSN article.
Please review the MSDN article on using Deploy in SharePoint applications here
The SPDisposeCheck tool can be downloaded here.
Roger Lamb maintains a blog for the SPDisposeCheck team here.
Note: The -xml command line switch is unreliable. We recommend that you do not use this command line switch on this release.

Usage : The –XML command line switch currently has issues, so pipe the output to a text file.

SPDisposeCheck <assembly> > <OutputFileName>.txt

And finally don’t forget to read Roger Lamb’s post on the Dispose Patterns.

Using SPQuery to filter lists by Domain User Account and SPUser ID

If you want to filter a list based on the value in the look up field that is of type ‘Person or Group’, We have to consider the following options:

  • Filter by the User Name.
  • Filter by SPUser ID Property
  • Filter by Domain User account

Filter by the User Name:

By default the settings for the ‘Person or Group’ column will have the following settings.

assignedto11

The Show Field will have the “Name with Presence” selected.

When we run a SPQuery search on the list using the following code we will be able to filter the list based on the fullname of the user.

   1: using (SPSite oSite = new SPSite("http://vslearnwss:801"))
   2:            {
   3:                using (SPWeb oWeb = oSite.OpenWeb())
   4:                {
   5:                    oList = oWeb.Lists["Project Tasks"];
   6:                    SPQuery query = new SPQuery();
   7:                    query.Query = "<Where><Eq><FieldRef Name='AssignedTo' /><Value Type='User'>Karthikeyan K</Value></Eq></Where>";
   8:                    SPListItemCollection items = oList.GetItems(query);
   9: 
  10:                }
  11:            }

Filtering by SPUser ID :

If you want to filter the list based on the SPUser ID then follow the steps below.

  • Add an additional attribute ‘LookupId’ for the queried field in your CAML query
<FieldRef Name='AssignedTo' LookupId='TRUE'/>
 

The updated code is as follows.

   1: using (SPSite oSite = new SPSite("http://vslearnwss:801"))
   2:            {
   3:                using (SPWeb oWeb = oSite.OpenWeb())
   4:                {
   5:                    oList = oWeb.Lists["Project Tasks"];
   6:                    SPQuery query = new SPQuery();
   7:                    query.Query = "<Where><Eq><FieldRef Name='AssignedTo' LookupId='TRUE'/><Value Type='User'>7</Value></Eq></Where>";
   8:                    SPListItemCollection items = oList.GetItems(query);
   9:                }
  10:            }

Filtering by Domain User Account :

If you want to filter the list based on the Domain User Account then follow the steps below.

  • Change the ‘Show Field’ Settings of the Person or Group lookup column to ‘Account’

assignedto21

 

 

 

 

 

 

 

  • Modify your code to include the domain account in the filter value.
using (SPSite oSite = new SPSite("http://vslearnwss:801"))
            {
                using (SPWeb oWeb = oSite.OpenWeb())
                {
                    oList = oWeb.Lists["Project Tasks"];
                    SPQuery query = new SPQuery();
                    query.Query = "<Where><Eq><FieldRef Name='AssignedTo' /><Value Type='User'>learnmoss\vinod</Value></Eq></Where>";
                    SPListItemCollection items = oList.GetItems(query);
                }
            }