I’ve finally found a good list of all the functions that you can use in SharePoint calculated columns – and I found a good set of examples too. Interesting.
SharePoint
Folder based Navigation in SharePoint
We have a customer who wants a fairly simple site – all it needs to be is a heirarchy of web pages.
Unfortunately, SharePoint Publishing features don’t really do this very well. Yes, in a document library it does breadcrumbs as you navigate through folders – but you can’t really do that with Pages. For a start, you can’t put folders in pages libraries!
So, instead, they’ve got this deep structure of sites – just to get the navigation. The site permissions and features are the same at all levels. This is a real administrative pain – especially if want to change the definition of the content types used in the pages libraries throughout the site.
What would be better would be to have navigation providers which show Folders in the navigation – so that they’re exposed in the left navigation (and maybe the top – I’m not sure). You could then enable folders in your page library. Users would then be able to navigate down through folders and pages. I guess there is a question as to which page should be the ‘default’ for a folder (obviously the folder itself isn’t a page that can be shown) – but perhaps something like just having a convention that the page ‘default’ is shown would be enough. Or maybe make it part of the metadata for a ‘Publishing Folder’ content type.
This would mean that the whole deep heirarchy and dozens of sites my customer is using could be dealt with in one single site. I can’t quite believe that nobody had this idea when they were planning the WCM features for MOSS. I don’t even think it’d be that hard – I just hope that I get a chance to implement this sometime…
Document Conversion Service doesn't map column data – Part II
(For the purposes of this post, I’ll use Pages with a capital P to mean items in SharePoint of a Page content type, or a child content type of Page. I’ll also refer to all content types in italics)
Previously, I found that the document conversion service doesn’t map site column data from the Document type to the Page type. So, what are our options?
- Get users to fill in the metadata for the converted document
- Put the metadata into the Word document
- Bespoke coding
- Don’t use the conversion service
Let’s look at each in turn.
Get users to fill in the metadata for the converted document
Well, the first option is pretty obvious – get the users to fill in the Site Columns for the converted document’s Page. In my case, this would mean filling in the AWBText column on the ConvertableDocumentPage type. This will work! Unfortunately this means that the page and document’s data is not linked – a change in the AWBText field won’t be replicated between both items, or even just pushed from the ConvertableDocument the next time it’s converted. That sucks a bit, but this might be a valid option.
Put the metadata into the Word document
The second option is quite neat – Word document can have ‘Quick Parts’ – some of which are document properties, and this can be connected to the columns of the content type:
You can put these into the document itself. They’re like document ‘Fields’ in Word pre-2007, but these are much, much better. For a start, you can actually type into the quickpart and it’ll update the document properties – and when you save the document to SharePoint it’ll update the columns of the library! Very cool. Anyway, I updated my Word template from my previous example…
I then created a new document. Note that the AWBText field in the Document Information Panel and the Quick part is linked – I typed in the value in the document and it was reflecting the Document Information Panel.
I then converted these document. This resulted in:
Okay, so I’ve scribbled on this a bit. The area outlined in the purple-pink colour is the content of our document that we converted. You can see that this includes the value of the ConvertableDocument‘s AWBText column. Hurrah! However, above this is the value of the AWBText column on the ConvertableDocumentPage – and it is still empty. In other words, the original document’s metadata is now in the page content – but it still isn’t stored against the Page as metadata. This isn’t really suitable for our customer – they need that column data against the Pages for their navigation. Bah!
Bespoke Coding
Okay, I started to wonder if I could fix this via custom code (i.e. some sort of Feature). I dug through some of the hidden properties of my source ConvertableDocument and destination ConvertableDocumentPage using SharePoint Manager. I knew that there must be some sort of connection as if you Edit the ConvertableDocumentPage is shows you that is has a source document, and lets you edit that document instead. Therefore, they must know where they came from.
In SharePointManager, I found some interesting fields. The ConvertableDocument content type I’d created had a property RcaPageID, which was a GUID. ‘Rca’ stands for ‘Rich Client Authoring’, which is what they seemed to call this page authoring technique until some decided to call it ‘Smart Client Authoring‘ instead. Certainly, internally it’s normally referred to as Rich Client Authoring, or ‘Rca’.
I then checked the ConvertableDocumentPage type, which had a property RcaSourceDocID . This was a GUID, and this ID matched the RcaPageID of the document we used to create the page. Thus, and I’m pretty sure about this, it’s the connection between the source Document and destination Page.
Therefore, I could build an event handler that (when a page is updated or created) gets the Page’s source document, sees what columns they share, and copies across the values of those shared columns. Actually, it’d probably have to exclude some (like title), but you get the idea. Also, it’d have to run a query across all the documents in the site collection, but I’m pretty sure that this is possible.
I like this solution, and think it’s a fairly straight forward, generic candidate for a feature, but unfortunately our customer is unable to make server configuration changes – like installing new features. So that rules that idea out… damn.
Don’t use the Document Conversion Service
I know, this seems a bit crazy – but you could author your content in Word and just copy and paste the content into your pages. This is what our customer was doing. I know, it seems a little crazy to me too, but if you lock down the styles available in a Word template, then the code you’ll copy will have consistent CSS styles in it, and you can prevent any inline CSS through that restriction too. It has no server footprint and no duplication of metadata – but you still have to store the documents (which might require column data too).
So those were the options I was able to come up with. I like the coding option – an event handler could be a very elegant way of dealing with this.
Document Conversion Service doesn't map column data – Part I
(For the purposes of this post, I’ll use Pages with a capital P to mean items in SharePoint of a Page content type, or a child content type of Page. I’ll also refer to all content types in italics)
One of our customers wants to author their Pages in SharePoint in Word. Sounds like a case for the Document Conversion Service – author the content in Word, and then convert the Document to a Page. There is a catch though – they’re wanting to capture some meta-data about the document too, such as business unit, review date, department that ‘owns’ the page, etc.. What would the Document Conversion Service do with this information? I didn’t remember seeing any way of setting up mappings between fields. Would the metadata be copied if both the Document and Page content types shared the same site column?
To find out, I did a bit of testing. Much of what I did was actually stuff like creating a new Page layout, and then customizing it. There are better articles about this that my notes, but I’ll include all the steps. (I do assume that you have the document conversion service running and enabled on your site collection though.) I did the following:
I created a new Site Column – I called it AWBText. It was just a text column.
I created a new Document content type which used that new column. I called this content type the ConvertableDocument content type:
I then created a new Page content type. I called this the ConvertableDocumentPage content type:
I made sure that that also used the AWBText column – and the out-of-box ‘Page Content’ column. This column will hold the content of the converted document. You should probably add another column for holding the style information, but I didn’t bother (‘cos I didn’t need it for the test). You could create your own, but I chose just to use the same ones as the Article Page content type – after all, the data (page content) is still the same, and this is why different content types can share the same columns.
So, now I’ve got my two content types I’m going to test with, and they both share the AWBText column. However, the ConvertableDocumentPage content type needs a page layout to, well, define how the ConvertableDocumentPage‘s content will be displayed. I cracked open SharePoint Designer, opened my site, and created a page layout:
This gives you a page layout to put your content controls into. We’ve only got a couple:
I created a page layout. Here’s the code and how it looked in SharePoint designer:
As you can see, I’m displaying my AWBText field at the top, with the converted content from our converted ConvertableDocument below. Both fields also have labels. I published and approved the layout.
Next, I set up a template Word document – I went to the ConvertableDocument content type’s advanced settings, and edited the template.
I then just saved the template without making any changes – I’ve found that you need to do this to get the Document information panel to work correctly.
Next up, I set up the document conversion through ConvertableDocument content type’s settings:
Then the complex form of the conversion setup:
Take a moment to look at that form. I’ve defined that I want to convert my ConvertableDocument to a page layout of ConvertableDocumentPageLayout – which implies a content type of ConvertablePageLayout. I’m putting the content of the converted content into the Page Content column, and removing any styles (because, as mentioned above, I don’t have a suitable column to put the style information into). Note that there are no settings for other data mappings – no columns of the document to columns of the page mapping.
I saved these settings, added my ConvertableDocument type to a Document Library, and added my ConvertableDocumentPage type to the ‘Pages Library’. Then I created an example document. Note the Document Information Panel at the top shows my AWBText column (and the Title column), and I’ve put in some text.
I saved this, and in the document library I chose to convert the document to a web page:
This resulted in a page that looked like:
And the document library looked like:
So, as we can see, the AWBText column has not been copied across, even though it is the same column. During the configuration process, there was no option to configure mapping of fields. It looks like the Document Conversion Service doesn’t map column data. In Part II, I’ll look at some options.
Duplicate rows from the SharePoint Lists webservice.
Edit: I’ve since learned more about this behaviour – but it’s still not very obvious
I found what I can only describe as a but in the Lists.asmx web service in SharePoint. I was using Lists.GetListItems to get a list of the folders in a Document Library, and I found that I was getting one of the folders twice. However, when I looked in SharePoint, there was only one, and my program showed that both these folders were supposed to be at the same URL. WTF?
Naturally, I went back and had a look at the XML I was getting back from the web service. I expected to get two, so I was somewhat surprised to get 3…
As you can see, 2 records have the same URL, the same internal ID (both of which have to be unique!), and the only difference is in the AWBMultiLookup column. This set alarm bells ringing. Firstly, I was surprised to see it in the results. In GetListItems you can define the fields you want returned in the responses (the ‘view fields’ ). I had only asked for the URL, the ‘link file name’ (the item’s name), and it’s ID. I’d expect to get some other details (the web services always seem to include more), but not field data.
Secondly, AWBMultiLookup is a multi-select lookup column. In other words, it looks up data from another list, and you can can select zero to many items from it. For my folder, I’d selected 2 options from this column (‘A’ and ‘C’), and now I have 2 records with the only difference being the value of the AWBMultiLookup column – ‘A’ or ‘C’. On a hunch, I went and selected a third option (‘B’), and my XML I was getting back became:
Yup, now I got 3 records with different values of AWBMultiLookup, rather than just the one. Clearly, and incredibly, the web service was returning a seperate ‘item’ for each value of the multi-select lookup column that was selected. I can’t think of a situation where that would be the desired behaviour – and everywhere else in the system, multiple values are just encoded into one string. Hence, I’m calling that a bug.
However, this raised a question. Elsewhere in the system I get just the one folder and it was definitely getting the multi-select lookup field correctly. I ran that code and found that the XML I got back was:
Yup, you’ll notice that the results from GetListItems this time shows all the values for the multi-select lookup in one attribute. What gives? What’s different about this query to the other one where multiple items would be returned?
Well, the only difference that seemed like it could be relevant is that this second query requests the ‘AWBMultiLookup‘ column in the ‘view fields’. I decided that I’d test this by modifying the view fields for my first query to include the AWBMultiLookup column like so:
Having done this, my query now worked as I’d expected it to in the first place:
Notice that all values are now encoded in the one attribute, and that I’m getting the two records I’d originally expected.
Or course, this doesn’t help me. When my application is browsing across folders I don’t actually know what the columns against folder really are, so even if I was happy to request the multi-select lookup fields (despite their being superfluous ), I can’t, ‘cos I don’t know what they are yet. I’ve gotta admit, though, that I’ve lost my temper at whoever made the web services work that way. It’s worth noting that the SharePoint API doesn’t behave similarly
One thing I haven’t checked yet is what happens if you hav many multi-select lookups. Combinatorial explosion anyone?
You can do a lot with page layouts…
I’ve been blogging a fair bit lately about Page Layouts – how they affect styles to hide bits of the page, how they are used to replace breadcrumbs and the like – but you can do a heck of a lot with them.
Quite a lot of your default master page is in ContentPlaceHolder controls. Those ContentPlaceHolder controls have default content – but your page layout can define Content controls which place content into those placeholders, overriding them. Of course, you still need to have all of the appropriate controls on a page – just removing the ‘Site Actions’ menu for everyone isn’t a good idea – but you can do a lot.
This sort of came up at the last SharePoint User Group meeting – Colin Byrne was demonstrating Silverlight in SharePoint (which apparently doesn’t work all that well yet, but shows promise). One of the demos he has showed replacing the left navigation with a Silverlight control, but used a neww Master Page do to that. I thought of a demo I’d done recently where I’d done similar – but with a Page Layout. I used this to replace the left navigation menu with a Web Part Zone:
Normal View
Edit View
Believe it or not, this is actually the default master with a particular Page Layout that I made, and the ‘Simple’ theme applied. Actually, there are lots of bits of the page modified by the Page Layout. The ‘Site Actions’ menu and Top Navigation Bar have been moved up, for example. The Left navigation has been replaced by a Web Part Zone, and I’ve dropped a Content Query Web Part in there for a giggle. And the Search box has been moved down the page too.
You could do all of this with a Master Page of course – and in real life, you’d probably want to for most of those modifications. For some things, though, like replacing certain navigation controls (which is what some of the out-of-box page layouts do with title breadcrumbs) then I think that a page layout might be exactly what you want – so that you can have different forms of navigation for different pages using the same Master Page.
Anyway, I was surprised by how easy it was to do this. Given that the Master Page defines default content, much of what I did was just copy that default content into the Content control for the location that I wanted to put the control into – and voila!
Pimp my SharePoint Part II – Beyond Just Colours
Previously I’ve written about branding in SharePoint and the technologies involved. However, there is more to branding than just the technologies used and the colours you want, which was what that post focussed on. Really, it’s more a question of style and content than just colour and pictures. This makes it all a good deal more complicated though, which emphasises the need for proper management of the work and for it to be treated as a proper project.
To recap on the technologies used in MOSS branding, briefly:
- Master Pages – can change everything
- Themes – can change the colour of elements and the background images.
- Web Parts – can change the layouts of pages and some of the appearance.
- Combination thereof.
The two main technologies discussed in branding are Master Pages and Themes, and a good description is:
[Themes are] Akin to painting a house new colors and changing the pictures on the walls. [Master Pages are] Akin to remodelling the whole house
Heather Solomon
Well, recent experience of branding and some interesting slides by Heather Solomon have driven home some other points. Note that these apply to MOSS but not WSS (which only has ‘basic’ pages). The ultra high level view of what I’ve learnt is:
- Just saying ‘X days to do branding’ is not a good idea.
- Branding encompasses more than I’d previously really thought about, both in a business and technology senses.
- It’s more of a ‘Pick and Mix’ affair than ‘small, medium or large’
- Specification and scope is vitally important.
- Therefore, branding should be treated as a proper project in its own right, with requirements, specification, design and testing phases.
Continue reading “Pimp my SharePoint Part II – Beyond Just Colours”
Restrict or Permit formatting changes in Word Documents
Word 2007 lets you restrict the styles and formatting people can use in documents based on a particular template. I suspect that this will be useful for me in restricting the styles used in SharePoint’s Rich Client Authoring (aka Smart Client Authoring – I wish they’d pick a terminology).
Just as a quick example, though, you get do this through the manage styles dialog. To open this, open the styles menu from the ribbon, and select the manage styles option: Continue reading “Restrict or Permit formatting changes in Word Documents”
RSS Aggregator Web Part
Folks are really keen on RSS feeds in SharePoint, but the RSS web part only receives feed from 1 location. Well, good news, as Eric Shupps created (a while ago, actually) a feed aggregator web part. That’s a useful thing to know – but it’s interesting that he hit the problem I have with RSS feeds – too many formats of them…
Take care when adding or removing columns from Site Content Types
As mentioned before the content types on a list are actually children of the site content types. I’ve also looked at adding columns to list content types, which naturally enough doesn’t affect their parent site content types. Anyway, there are issues to consider when dealing with adding and removing list content types – I suggest you refer to this post for more information.
So what about adding and removing columns from Site Content Types – are there issues with this? Well, yes, there are (unsurprisingly). If you add a new column to a Site Content Type, you have the option to ‘Update all content types inheriting from this type’

If you select ‘no’, then the change only applies to that Site Content Type. The next time you add that site content type to a list, the new List Content Type that is created will have the new column, but pre-existing list content types that inherit from the site content type will be unchanged.
If you select ‘yes’, then the List Content Types (or other Site Content Types) that inherit from this content type will have the new column. For the List content types, this means that there will be a new column on the list. Carrying on from an earlier example, here I’ve added a new column (‘Job Title’) to the Example Travel Expenses site content type, and updated all content types inheriting from that. If we then go an look at the List Settings page, we can see our List Content Type has a new column:
Great! Now what happens if I remove that column from our Site Content Type? Well, again, I get the option to ‘Update all content types inheriting from this type’. If I choose no, then the existing List Content Types derived from this Site Content Type remain as they are. If I choose yes, though, I get a fairly large warning saying:
This column will be removed from all content types that are based on this type. If you are sure you want to remove this column from all content types based on this type, click OK. To remove this column from this content type only, click Cancel to close this dialog box, click No in the Update Lists and Columns section, and then click Remove.
Snappy message that:
Anyway, if you click OK, that column is removed from child content types. H0wever, the column is not deleted from lists that were using those child content types. I removed the ‘Job Title’ column from my ‘Example Travel Expenses’ site content type. If we return to our list settings page, we can see that the column still exists, although it isn’t used in any content types:
This makes sense, as the column could actually contain data, and it could be used in multiple places throughout our sites (potentially hundreds!) However, maybe you do want to remove that column from that list, or potentially those hundreds of lists. In that case (and this is why this is important) you have to delete the ‘orphan’ column on a list by list basis. Therefore, if your content type was used in hundreds of lists, you will have to delete this extra column hundreds of times, once for each list.
Therefore, be very careful when adding or removing columns from a Site Content Type – make sure that you really want to add it (as removing it might be hard), and be aware that removing the column is not the same as deleting it in the lists that use it already.


