Setting the Title field for Content Types

This is one I’ve been meaning to blog about for a while. I was using a Content Type where I was trying to set the display name of ‘Title’ field. I was happy to have a Title column, but I wanted it to have a different name.

I tried doing this declaratively:

<FieldRef ID="{fa564e0f-0c70-4ab9-b863-0177e6ddd247}" Name="Title" DisplayName="Request" Required="FALSE" />

However, I found this didn’t work in SP2010 – the field still appeared as ‘Title’. This was frustrating.

Instead, I had to set the Title’s display name in code:

foreach (SPFieldLink fldLnk in contentType.FieldLinks)
{
if (fldLnk.Id == SPBuiltInFieldId.Title)
{
fldLnk.DisplayName = "Request";
}
}
contentType.Update(false);

This was a bit strange – other fields can have a DisplayName set in CAML quite happily. This seems to just be a feature of the Title column.

EDIT: I also had to use a similar approach on setting the Title column for a content type used on a list – but using:

private void SetTitleField(SPWeb web, string listname, string contentTypeName, string newTitleName)
{
SPList list = web.Lists[listname];
SPContentType ct = list.ContentTypes[contentTypeName];

foreach (SPFieldLink fldLnk in ct.FieldLinks)
{
//Necessary to set title field - when using content types, this seems to set it to "Title" irrespective of what is set in the Content type or list's XML.
if (fldLnk.Id == SPBuiltInFieldId.Title)
{
	fldLnk.DisplayName = newTitleName;
	ct.Update(false);
	break;
}
}
foreach (SPField fld in list.Fields)
{
if (fld.Id == SPBuiltInFieldId.Title)
{
	fld.Title = newTitleName;
	fld.Update();
	break;
}
}
}
Setting the Title field for Content Types

CAML queries of Lookup columns support query by ID

When you run a CAML query, you have to specifiy a value you’re searching for:

query.Query = "<Where><Eq><FieldRef Name='MyField' /><Value Type='Text'>WhatILookFor</Value></Eq></Where>";

Well, that’s fine, but what about lookup columns? They actually have 2 elements – the text, and an ID.

E.g. You might have a lookup to a ‘Country’ list, and “United Kingdom” might be ID 45.

If I wanted to find items on my list that referenced the “United Kingdom” value, my query would be:

query.Query = "<Where><Eq><FieldRef Name='MyField' /><Value Type='Lookup'>United Kingdom</Value></Eq></Where>";

However, this doesn’t make much sense. The ID is our primary key to the ‘country’ list. Why are we querying by value? I mean, if the United Kingdom had a revolution and suddenly became, say, the ‘United Republic’, all of my CAML queries would break.

(That might be the least of my worries, but you get my point).

So, we’d like to query by ID. Well, you can – I’ve mentioned it before, and the MSDN documents neglect to mention it themselves. There is a property on the FieldRef of LookupId. Set that to True, and you can query by ID.

query.Query = "<Where><Eq><FieldRef Name='MyField' LookupId='TRUE' /><Value Type='Lookup'>43</Value></Eq></Where>";

Edit: One of my colleagues pointed out that in SharePoint 2010, if you update the text of a referenced item, it is updated within the items that reference it. This is different to SharePoint 2007, where the referencing items retained the original text value. He’s right – but I’d still prefer to query by ID as it’s indexed, unique, and simple.

CAML queries of Lookup columns support query by ID

Hide Column type from Lists

So, you’ve created a new custom Field (or column) type, but you don’t want it to be available to add directly to Lists and Libraries – that is, you want to force users to create columns as Site Columns, and add those to the list. Conversely, maybe you want to prevent a column being created as a Site column, and only available to add directly to lists (though I can’t thinik why).

Well, it turns out that that is possible. In the CAML defining your field in fldtypes_???.xml, you can have something like the following:

<FieldTypes>
    <FieldType>
        <Field Name="TypeName">MyCustomField</Field>
        <Field Name="ParentType">MultiChoice</Field>
        <Field Name="TypeDisplayName">My Custom Field</Field>
        <Field Name="ShowOnColumnTemplateCreate">TRUE</Field>
        <Field Name="ShowOnListCreate">FALSE</Field>
        <Field Name="ShowOnDocumentLibraryCreate">FALSE</Field>
        <Field Name="ShowOnSurveyCreate">FALSE</Field>
        <Field Name="Sortable">FALSE</Field>
        <Field Name="Filterable">TRUE</Field>
        <Field Name="ShowInEditForm">FALSE</Field>
        <Field Name="UserCreatable">TRUE</Field>

ShowOnColumnTemplateCreate controls visibility as a Site Column type. The other ‘Show On X’ values control visibility as a List Column Type for different types of List. You could, therefore, have a Column Type that can only be used on, say, Document Libraries. Hope that helps.

Hide Column type from Lists

Why I hate (and love) Site Definitions

I love the idea of site definitions. The idea that we can just say ‘give me a site for X’ and in a puff of magic smoke have a site with a feature rich experience just appear – that’s neat! And with SharePoint’s Feature mechanism and object model, we should be able to to a lot with them.

Strangely, after two and a half years working with SharePoint, I’d never built a site definition. (I don’t know how I managed that!) Recently, though, I’ve written several, and all I can say is that I’m older, and greyer than I was before. The reality of Site Definition development did not live up to my hopes. Continue reading “Why I hate (and love) Site Definitions”

Why I hate (and love) Site Definitions

ContentTypeRef vs ContentTypeBinding

Interesting question came up as a result of a post of Chris O’Briens:

Interesting you raise ContentTypeBinding. I use this in other areas (e.g. associating content types with Pages libraries). Don’t think it had occurred to me that I could use it here also.

Which kinda makes me wonder why the schema provides two ways of doing the same thing, but that could lead to whole ‘nother discussion 😉

Well, I get interested by questions like that. As far as I can tell…:

  • ContentTypeBinding elements exist in the Elements of a feature. They’re so that a feature can bind a new content type to a list
  • ContentTypeRef elements exist in the schema of a List definition (List > MetaData > ContentTypes > ContentTypeRef)

So, you can use the ContentTypeRef to create a list with a content type, or you can use a ContentTypeBinding to add it later. And you should be able to do it in the same feature – you could use a ListInstance to create a list using your definition, and then bind your content type. And yes, it does rather look like all three bits could be in the one Feature.

  1. List to define the list
  2. ListInstance to create one in your site
  3. ContentTypeBinding to add your content type.

I wonder what happens if you try to create a list definition without a content type reference? Might try that for a giggle sometime.

Side note: the Property element on a File element in a publishing site with the key PublishingAssociatedContentType is for associating the file (a page layout) with a page content type, not for associating the page content type to the Pages library. You have to do that as well, using a ContentTypeBinding element. (Thanks Waldeck, that was driving me nuts!)

ContentTypeRef vs ContentTypeBinding

Modify ListItem Display to show referencing items…

SharePoint is made up of lists of items, where an item is a set of data. Here is the standard display of an item’s properties:

As you can see, we’ve got a item, and it has some fields of data, and they’re being displayed inside a web part. Those fields are columns on the list:

All very familiar, I’m sure. It gets interesting when we start using Lookup columns, though. These are columns that refer to items in other lists. For example, this is a list of documents, but they refer to items in the above list (that’s what the Item Ref column is doing):

Cool, but wouldn’t it be great if I could show a list of items referring to a particular item on it’s display page? For example, in this case wouldn’t it be good to show a list of ‘Item Documents’ on the DispForm.aspx page used to show the Item’s properties? Well, you can:

(Edit: one of my colleagues points out that Microsoft did this in one of the Fab 40 templates – but I didn’t know).

So how does it work? Continue reading “Modify ListItem Display to show referencing items…”

Modify ListItem Display to show referencing items…

The format of Dates in CAML

So, a colleague asked me about what format dates should be put into the where clause of a CAML query as. I’d had a lot of problems finding this out myself, and ultimately I found that a .ToString(“u”) on a DateTime object did the trick. The produces a time of the form 2006-04-17 21:29:09Z

For example, using a StringBuilder to create my CAML query (for my SPQuery object), this might look like:

caml.Append("<Leq>");
caml.Append("<FieldRef Name='MyDueDate'/>");
caml.Append("<Value Type='DateTime'>");
caml.Append(System.DateTime.Today.ToString("u"));
caml.Append("</Value>");
caml.Append("</Leq>");

(This query contains the date contained in the MyDueDate column with the current date and time).

The format of Dates in CAML