Monday 31 March 2008

This blog is changing URL..

..but I'm hoping you won't notice! The new URL is the somewhat simpler, and if everything goes to plan everything will be redirected from old to new, so any bookmarks should continue to work. Or that's the theory promised to me by my blog host, but I thought I should say something just in case :-) Certainly all subscribers to the feed won't need to do anything - the Feedburner URL will stay the same.

Changeover will be later this week - if anybody notices a problem I'm keen to hear, please drop me a comment to let me know!

P.S. I'm likely to switch over to using the CKS : EBE framework at some point soon. A few people have commented that since we moved into 2008, they found it harder to find articles since the navigation on the right buries them under the '2007' node. I've tried to mitigate this by adding the 'Most popular articles' list (as indicated by Feedburner), but I know navigation isn't ideal. Rest assured I'll improve it when I have more control over the site!

Sunday 16 March 2008

Great controls to be aware of when building SharePoint sites

Something I've been meaning to do for a while is discuss some of the controls I've found useful when putting together SharePoint sites. Obviously before building a custom control for a specific behaviour, it's a good idea to check if SharePoint comes with anything that will do the job. It sometimes surprising what you find! Certainly those from a Content Management Server background will be familiar with the idea of having lots of reusable controls (which used the CMS API) within the team, but in MOSS some of the equivalent controls come for free. The most obvious is the Content by Query web part (though we won't mention that the output HTML isn't accessible [WCAG AA-compliant] without extra work), but some of the smaller controls deserve some attention too. So here's a rundown of some handy items for the toolbox:


This control can be used to selectively display content or controls depending on the current user's SharePoint permissions. Whatever is the inner content of the control will therefore not be shown if the user doesn't have the specified permissions. An example would be:

   1: <SharepointWebControls:SPSecurityTrimmedControl runat="server" Permissions="ManageWeb">
   2:     This is only visible to users who can manage current web..    
   3: </SharepointWebControls:SPSecurityTrimmedControl> 

In addition to the Permissions property shown above (enum), the PermissionsString property can be used to specify a comma-separated list of required permissions. This can be used in conjunction with the PermissionsMode property which takes 'All' or 'Any', and also the PermissionContext property which specifies what SharePoint object (e.g. 'CurrentList', 'CurrentFolder', 'CurrentItem', 'CurrentSite', 'RootSite') the specified permission applies to, so it's flexible. Examples of the permissions which can be specified include 'ManageLists', 'AddListItems', 'ViewPages', 'ManagePermissions' and so on. These are members of the SPBasePermission enum and Zac Smith has a full list. Notably many of these permissions are probably more useful in a collab scenario rather than WCM. [UPDATE: Text in this section updated following comment below/further testing:] For WCM folks the control does look like it does something useful in being able to filter on authentication type - unfortunately this doesn't work as advertised. For reference (in case MS fix it), the usage is:

   1: <SharepointWebControls:SPSecurityTrimmedControl runat="server" AuthenticationRestrictions="AnonymousUsersOnly">
   2:     This *should* be visible only to anonymous users but it doesn't work..    
   3: </SharepointWebControls:SPSecurityTrimmedControl> 

As you'd expect, valid values here are 'AnonymousUsersOnly', 'AuthenticatedUsersOnly' and 'AllUsers' - however as noted in the comments below 'AuthenticatedUsersOnly' is the only flag which seems to work properly.

There are some other interesting properties too:

  • PagesMode - valid options are 'Design', 'All' and 'Normal'

  • QueryStringParametersToInclude

  • RequiredFeatures

These look like extra properties to filter on, but alas I couldn't get these to work either. My investigative powers let me down here as firing up Reflector onto both SPSecurityTrimmedControl and the related RightsSensitiveVisibilityHelper class didn't give anything away in terms of usage, nor did Google or searching the 12 hive. Certainly it looks like specifying values is all that would be needed for latter two parameters, but I had no joy. A final consideration for SPSecurityTrimmedControl however, is the idea of further possibilities opened by deriving from this control in the same way SPLinkButton does.


Where the previous control examined the user's permissions to establish whether content should be shown, the EditModePanel looks at whether the current page is in display or edit mode. This can be incredibly useful in the WCM world for displaying help messages or other content to users as they edit a page. However there are other uses - hiding navigation, adding inline CSS override classes to use different formatting (particularly useful) and emitting debug information in the HTML output are all examples. The declaration for this control would look like:

   1: <PublishingWebControls:EditModePanel SuppressTag="false" GroupingText="Title help" 
   2:         PageDisplayMode="Edit" runat="server" id="EditModePanel1">
   3:     Page titles should be concise
   4: </PublishingWebControls:EditModePanel>

At run time in edit mode, this would look like:


A prettier usage might be to include the field controls within each respective EditModelPanel, meaning the input control is shown within the borders of the box. To do this we'd also need an extra EditModePanel set to PageDisplayMode="Display" which also contained the field control, since the original will display in edit mode only. Note this control will output a surrounding <div> unless the SuppressTag property is set to 'True'.


One control you might use in conjunction with the previous control is the ListItemProperty control. This simple little fella allows you to write out a particular field's value for a list item. The field which is rendered is specified with the Property attribute, where we specify the field's internal name. By default, the current list item (i.e. for the page we're viewing) is used, but this can be overridden by specifying the List property - to do this we specify the list GUID with braces:

   1: <SharePointWebControls:ListItemProperty runat="server" id="ListItemProperty1" 
   2:     List="{C110296D-2BE9-4818-80EE-A06BD018DE2F}" ListItemID="1" Property="Title"/>

I think of this control as doing a .ToString() on the contents of the chosen field. This can sometimes be useful in WCM where you want the value to appear in a different location onthe page to where it is edited - for example within a <title> tag. Note we can also specify the version of the list item we want to retrieve the value for with the ListItemVersion property.


Much the same as ListItemProperty except on a list itself. These two may well be used together as the code in a list's DispForm.aspx does:

   1: <SharePoint:ListProperty Property="LinkTitle" runat="server" id="ID_LinkTitle"/>
   2: : 
   3: <SharePoint:ListItemProperty id="ID_ItemProperty" MaxLength="40" runat="server"/>

This will show the current list's title, followed by a colon, followed by the current list item's title.


Slightly confusing name, but this control allows us to write out some properties of the current site/web. The MSDN documentation shows the valid list to be:

  • BlogCategoryTitle - Category of the current post item

  • BlogPostTitle - Title of the current post item

  • Description - Description of the current Web site

  • RecycleBinEnabled - 1 if the recycle bin is enabled; otherwise, 0

  • SiteOwnerName - User name of the owner for the current site collection

  • SiteUrl - Full URL of the current site collection

  • Title - Title of the current Web site

  • Url - Full URL of the current Web site
So the following would write out the title of the current web:

   1: <SharePointWebControls:ProjectProperty runat="server" id="ProjectProperty1" 
   2:     Property="Title" />


This control provides an architecture where an 'outer' control is added to the page layout/master page, but the 'inner' control is determined by a Feature, thus allowing the control to be swapped out without having to modify the original template. This is used widely in Microsoft's master pages. This is a great control, I discuss it more fully in my Using the DelegateControl post.


To finish on something slightly different, this control can be invaluable when developing custom web parts and field controls. It provides the 'file picker' experience authors are used to when working with SharePoint, and fits well when you have a control which requires a file to be selected. So in several of my controls I allow the user to override the XSL file used for formatting, and the AssetUrlSelector is added to the user control I use for the edit view of the control. This provides me with the 'browse' button which will launch the picker when clicked:

Clicking the button then shows:

The AssetUrlSelector provides a fairly good user experience, including opening the picker in the location of the currently-selected file if one exists, or defaulting to a specified default location if not. Along similar lines if you need to provide a slick experience to select an image is the RichImageSelector - this is the picker used by the RichImageField control.


So that's some of the controls I've found useful. Obviously there are stacks more and the ones I did highlight can be used in lots of interesting ways which aren't discussed here. But hopefully this does serve to remind you to check what's in the box before spending time writing your own!