March 10, 2010 - 20:13, by Steven Van de Craen
Categories: Content Types, InfoPath, MOSS 2007, Search Server 2008, SharePoint 2007, WSS 3.0
When you have multiple Form Content Types with each their respective form templates assigned to the same Form Library by some magic it will automatically save a new form in the correct Content Type. How it does this ?
The new form’s XML contains an InfoPath processing instruction with a “href” attribute set to the XSN template URL. At save time the Content Types configured in the Form Library are iterated and a match is made based on Template URL. If no match is found it will use the default Content Type.
Even works in code if you do a SPFileCollection.Add() so no need to specify the Content Type explicitly during saves !
It doesn’t seem to take Alternate Access Mappings into account so that’s a bit of a downer, but still powerful.
March 10, 2010 - 20:13, by Steven Van de Craen
Categories: .NET, MOSS 2007, Search Server 2008, SharePoint 2007, WSS 3.0
You can add pages to meeting workspaces through the User Interface (browser) and then you get the options to manage them. It is also possible to add pages through code, but there’s one catch you need to be aware of and that is the InstanceId of the meeting. This ID is used in meeting workspaces to distinguish content per instance of a recurring event. So each meeting instance has its own set of documents and list items througout each List or Library on the site.
Consider the following code:
string url = "http://moss/meeting1";
string newPageUrl = String.Empty;
using (SPSite site = new SPSite(url))
{
using (SPWeb web = site.OpenWeb())
{
SPMeeting meeting = SPMeeting.GetMeetingInformation(web);
meeting.AddPage(String.Format("Page {0}", DateTime.Now.ToString("HHmmss")), meeting.InstanceId, out newPageUrl);
}
}
By adding the page using the InstanceId of the current meeting workspace it will be added to a folder named after the InstanceId in the Pages library. This has the following effects (also applies to items in the other lists and libraries on the meeting workspace):
- the page cannot be managed through the UI (sorting, removal, etc)
- the page is visible only in a single meeting instance in case of recurring events
If you want to add a page regardless of instance you can provide a zero (0) to the instanceId parameter of the AddPage method and it will behave identical to pages added through UI.
January 29, 2010 - 15:09, by Steven Van de Craen
Categories: .NET, Content Types, Debugging, MOSS 2007, Office 2003, Office 2007, Search Server 2008, SharePoint 2007, WSS 3.0A while ago I stumbled upon a serious design limitation regarding Content Types and centralized document templates. What then followed was a series of testing, phone calls with Microsoft, finding alternative solutions and deep dive into Office Open XML.
Request from the customer
“We want to use MOSS 2007 to create a collaboration site per project for our 400+ projects. These collaboration sites all use the same Content Types and document templates. We want to centrally manage those document templates so that we don’t need to make the same change 400+ times.”
Approach
Due to sizing we architected a solution with a dozen of Site Collections that would each hold a collection of project sites. We ‘Feature’-ized our Content Types and Site Columns so that they could quickly be activated on all Site Collections and used by the child sites. Document templates would be stored in a central document library and we would link to them in the Content Types on the project sites.
First issue
Linking to document templates really doesn’t play well with the Document Information Panel (DIP). I have blogged about this here:
Centralizing Document Templates in a library- Document Information Panel shows incorrect properties
We proposed a solution where the document templates in the central library would be pushed to the Content Type resource folder on site level. The code to perform the push would have to connect to the Site Collections, copy the template to the resource folder (http://sitecollectionurl/_cts/contenttypename) and link template and Content Type together.
When a Site Content Type is associated with a List it will be a List Content Type inheriting from the Site Content Type and the document template will be copied to the List Content Type resource folder (http://sitecollectionurl/listurl/Forms/contenttypename).
Second issue
Did I tell you that the column values (metadata) have different values based on the project site ? So when a project site is created we automatically update the List Content Type Column default value with the values for that specific project site. Unfortunately this is not supported when working with Office 2007 file formats because they only react on changes to the Site Column.
Consider the following scenario:
1) Set up a document library with a Content Type that has a text column with a default value
2) Upload a new .doc or .docx as Content Type template
TEST 1) Create a new document:
.DOC: the DIP will contain the text column with the default value
.DOCX: the DIP will contain the text column with the default value
3) In SharePoint, modify the default value of the text column
TEST 2) Create a new document:
.DOC: the DIP will contain the text column with the updated default value
.DOCX: the DIP will contain the text column with the original default value
Microsoft confirmed that this is by design.
Third issue
When designing our document templates with Content Controls mapped to our SharePoint fields we didn’t know that internally in the DOCX file it uses a GUID for mapping the Content Control with the SharePoint Metadata XML. For fields (Site Columns) created in the UI or through API this is the SPWeb.ID of where they were created. For fields created declaratively through Features this is the SPList.ID of where their Content Type is associated to.
So some things to notice
- Creating a single document template with Content Controls mapped to your declaratively added Fields cannot be used in two different Document Libraries because the Content Controls lose the connection with Field (because the ID of the List is different and not updated in the Content Control)
- The solution here is to create your fields in the UI or through the API (this could be in a Feature Activating event)
- Copying a document template across Site Collections means different Web ID’s so it also affects fields created in the UI or the API
Finally
In the end we wrote some wrapper classes for Office 2007 file formats using System.IO.Packaging that would manipulate our document templates once they were copied over to a different Site Collection. We also rewrote our Features to create our Fields through the API (SPWeb.Fields.AddFieldAsXml()).
- Remove the SharePoint Metadata XML so that association of the Content Type to a List it would be regenerated automagically
- Loop through every Content Control and find to which Field they were mapped using information in it’s XPath. Then we would update the GUID’s in the Content Control to match the SPWeb.ID
Next time I’ll definitely take these design limitations into account. Lessons learned I’d say !
November 7, 2009 - 11:31, by Steven Van de Craen
Categories: Advanced Computed Field, SharePoint 2007, Search Server 2008, WSS 3.0, MOSS 2007, Custom Field Types
I got a question on how to use the Advanced Computed Field for conditional formatting and when I finished writing up the response I figured I might as well share it with the community, being you all :)
Here’s the config I used:
<FieldRefs>
<FieldRef Name="TestField" />
</FieldRefs>
<DisplayPattern>
<Switch>
<Expr>
<Field Name="TestField" />
</Expr>
<Case Value="value1">
<HTML><![CDATA[<div style='color: green;'><b>GREEN</b></div>]]></HTML>
</Case>
<Case Value="value2">
<HTML><![CDATA[<div style='color: blue;'><b>BLUE</b></div>]]></HTML>
</Case>
<Case Value="value3">
<HTML><![CDATA[<div style='color: red;'><b>RED</b></div>]]></HTML>
</Case>
<Default>
<HTML><![CDATA[<div style='color: brown;'><b>BROWN</b></div>]]></HTML>
</Default>
</Switch>
</DisplayPattern>
October 26, 2009 - 22:14, by Steven Van de Craen
Categories: SharePoint 2007, Search Server 2008, MOSS 2007, WSS 3.0Funny thing last week when I wrote a “Page Information Web Part” (something that showed something like ‘This page was last modified by X on Y’) and it didn’t update at all when Web Parts were added, modified or deleted.
I can see why it wouldn’t but I still think this is a flaw because there’s no way to see if the page was modified (ie. Web Parts added, modified, removed), not even with Versioning on.
A quick fix for me was to check in my Web Part if the page was just in Edit Mode and then call an SPListItem.Update() on it.
October 26, 2009 - 21:54, by Steven Van de Craen
Categories: jQuery/JavaScript, MOSS 2007, Search Server 2008, SharePoint 2007, WSS 3.0Still one of my most popular posts ever is the extension I wrote on the Rooms and Equipment Reservations template for SharePoint 2007 which allows you to manage reservations for meeting resources.
The idea behind RER is simple, but the architecture Microsoft chose (and unfortunately me too) is flawed. For each resource there are two types of reservation items; “Available” and “Reserved”. When making a reservation the “Available” item is shrunk, split or replaced with a “Reserved item”. The list of reservation items for a certain resource should thus be continuous based on their respective start and end times.
Since quite a few people from the community and also some customers are using the RERv2, I get a lot of feedback on these flaws, which I tend to ‘consistency issues’. These issues can’t really be traced back to bugs in code but seem to happen at random. For every 100 reservations are made I typically see 3 consistency issues. They don’t all have a great impact; some are not even noticed, others are blocking future reservations for that resource.
Ideally the mechanism would have to be rewritten to just use “Reserved” items. This would make the fault ratio significantly smaller. However that project has been put in the fridge until further notice I’m afraid.
There is a sparkle of light at the end of the tunnel however ! I am releasing a Web Part that allows you to quickly correct consistency issues. And it’s even free ! ;)
Downloadables
Installation Instructions
1) WSP
The installation package (above) contains a SharePoint Solution (.wsp) to deploy using STSADM:
STSADM -o addsolution -filename RER.v2.ConsistencyCheckWebPart.wsp
STSADM -o deploysolution -name RER.v2.ConsistencyCheckWebPart.wsp -immediate -allowgacdeployment
2) Web Parts
Next in SharePoint create a Document Library (e.g. Pages) in the RER site where you upload the jQuery.js and RERAdmin.txt files from the install package. These make up the formatting and collapsing behaviour of the resources and reservations.
Also create a Web Part Page in this library called RERAdmin.aspx .
Add the ConsistencyCheckWebPart and RERAdmin_CSS_and_JS Web Parts on the RERAdmin page. You can import these Web Part directly if you go through Add Web Part > Advanced Web Part gallery and options > Import
It is best to break permissions and tighten security on the Web Part page so that users don’t inadvertently access the Consistency Check Web Part !
Usage Instructions
The Web Part must be placed in a site based on RERv2. It will automatically load the list of resources and corresponding reservations. If the CSS and JavaScript are in place the reservations are collapsed by default and the items will either have a green (good) or red (bad) icon. If it’s red that means there are consistency issues in the stream of reservation items for that resource.
The editor on the bottom of the Web Part will allow you to make changes directly to reservations.
NOTE: The number between square brackets is the item ID of either the resource or reservation item. You will need this to Modify or Delete a reservation !
Possible causes:
| ISSUE | EXPLANATION | FIX |
| There are no reservations | The workflow on the Resource hasn’t run (yet). | Add an “Available” reservation for the resource with no specified end time, or recreate the resource to trigger the workflow. |
| There are two adjacent “Available” reservations | They should be merged into a single “Available” item. | Delete one of the items and Modify the remaining item to become ‘continuous’. |
| There are overlapping reservations | A resource was booked twice. Normally this is prohibited but could occur in some rare conditions. | Remove on of the items or Modify the start and/or end times to resolve this. |
| Reservations are not continuous | All items should form a ‘continuous stream’ based on their start and end times. | Modify the timings so that they become ‘continuous’. |
October 1, 2009 - 22:35, by Steven Van de Craen
Categories: Custom Field Types, jQuery/JavaScript, MOSS 2007, Search Server 2008, SharePoint 2007, WSS 3.0, Advanced Computed Field
A common question to receive is on list items with a long body (eg. Announcements) and then show only X characters and optionally a ‘read more’ link. Many ways to solve this but I went for the following: a Custom Field Type that renders the short text with ellipsis using jQuery.
This is another example using the Advanced Computed Field in a creative way. The ACF allows you to create computed fields referencing other fields or data in your list and manipulating them through CAML or JavaScript. It has the advantage that this can be done from within the browser, however I admit CAML isn’t the easiest of things to comprehend in the SharePoint technology stack.
Ellipsis sample
This ellipsis displays the first 20 characters of the plain text version of the Announcement Body

<FieldRefs>
<FieldRef Name="Body" />
<FieldRef Name="ID" />
</FieldRefs>
<DisplayPattern>
<HTML><span style="display:none;" id="el_</HTML>
<GetVar Name="WPQ" />
<HTML>_</HTML>
<Field Name="ID" />
<HTML>"></HTML>
<Field Name="Body" />
<HTML></span></HTML>
<HTML>
<script type="text/javascript">
$(function()
{ var mySpan = $('#el_</HTML>
<GetVar Name="WPQ" />
<HTML>_</HTML>
<Field Name="ID" />
<HTML>');
var myShortText = $(mySpan).text().substring(0, 20);
if ($(mySpan).text().length > 20)
myShortText += '...';
$(mySpan).show().html(myShortText); });
</script></HTML>
</DisplayPattern>
Notes
- If you prefer to not escape the brackets you can use CDATA tags: <HTML><![CDATA[<b>hello</b>]]></HTML>
- GetVar ‘WPQ’ returns the unique Web Part ID. This takes care of multiple List View Web Parts on the same page
- You could optimize the output by extracting most of the script and placing it in an externally referenced JavaScript file
- My JavaScript/jQuery skills aren’t the best. I’ll have to ask Jan for some jQuery pointers next time :)
August 20, 2009 - 09:56, by Steven Van de Craen
Categories: Content Types, MOSS 2007, Office 2007, Search Server 2008, SharePoint 2007, WSS 3.0 Every once in a while I get the request to manage all document templates centrally in a Document Library. This can easily be done by configuring your Content Types to ‘link’ to the document template by location and then applying those Content Types to lists on several locations.
However there’s a gotcha in Word 2007 with the Document Information Panel.
Consider the following scenario:
- You have a “MyTemplates” Document Library for storing the Word templates (.doc, .docx)
- You have a “Documents” Document Library configured with Content Types linking to your templates as noted above. These Content Types have custom metadata (text fields, date fields, lookup fields, etc.)
- You create a new document with a given Content Type
When the new document opens in Word 2007 the Document Information Panel is showing properties from the “MyTemplates” Document Library instead of your Content Type. Once you save the document it will refresh and show the correct set of properties. If you have required metadata it will prompt you to fill that in before actually saving.
I believe this to be a bug in Word 2007. It has been confirmed by Microsoft that this is a design limitation.
A workaround An alternative solution for some scenario’s could be to set the Content Type of your templates to the target Content Type.
This would of course still not work when you want to use the same template for multiple Content Types.
Definitely something to keep in mind when planning your setup…
August 7, 2009 - 13:23, by Steven Van de Craen
Categories: MOSS 2007, Search Server 2008, SharePoint 2007, WSS 3.0
One can easily create a Content Type on a child web through the SharePoint interface.
One can easily create a Content Type on a child web through the SharePoint Object Model.
One cannot create a Content Type on a child web through a Feature declaratively (you could create it through code in the Feature Handler of course but that's not my point).
| Last Operation Result: |
The installation of features failed during deployment of the solution. |
| Last Operation Details: |
DEVMOSS08 : Elements of type 'ContentType' are not supported at the 'Web' scope. This feature could not be installed.
|
Silly.
August 4, 2009 - 09:12, by Steven Van de Craen
Categories: General, MOSS 2007, Search Server 2008, SharePoint 2007, SharePoint Updates, WSS 3.0The download for SharePoint 2007 SP2 has been updated to no longer change your environment to trial mode.
Next >>