Aidan Garnish

Collaboration Not Competition

MOSS 2007 site definitions vs site templates

There are two confusing terms in MOSS 2007, site templates and site definitions. A site template is a .stp file which contains only the difference of changes from the original site definition. A user who wants to install a custom .stp file must have a site definition installed from which the .stp file was saved.

A site definition on the other hand is a complete definition with a directory structure containing .aspx files and a Onet.xml file.

For more on creating site definitions see Madhur Ahuja's post

Using SharePoint web services to get list items

A colleague has just been wrestling with the syntax to get the list items out of the XML returned by the SharePoint web services. These two blog postings helped hugely:

UPDATE - I have posted a code snippet for retrieving items from a list using web services here

Custom SiteMapPath to handle variations in MOSS 2007

Whilst developing a MOSS 2007 Internet site I came across an issue with the SiteMapPath control when using variations. Variations use the root site to direct the user to the correct variation for their settings. A user with settings of en-GB, for example, will be directed towards the relevant variation by variationroot.aspx.

This is great except when using the SiteMapPath breadcrumb navigation control which displays the variation root site as well as the relevant variation site by default.

By default the following is displayed:

Variation Root > English Site > Some Page

What I want to display is:

English Site > Some Page

To achieve this I have created a server control that inherits from SiteMapPath and has an additional property called IgnoreNode. I have overridden the RenderContents event so that the HyperLink that has the same text as IgnoreNode is no longer rendered. In my case I set IgnoreNode to "Variation Root" so that it is not displayed in the breadcumb but you could choose any node that you don't want to display.

The code:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace CustomBreadcrumb
    [ToolboxData("<{0}:CustomBreadcrumb runat=server></{0}:CustomBreadcrumb>")]
    public class CustomBreadcrumb : SiteMapPath
        public string IgnoreNode
                object o = ViewState["IgnoreNode"];
                if (o != null)
                    return (string)o;
                    return String.Empty;

                ViewState["IgnoreNode"] = value;
       protected override void RenderContents(HtmlTextWriter output)
          bool blnNodeWasIgnored = false;
          HyperLink hlLink;

          foreach (Control oControl in this.Controls)
              SiteMapNodeItem oSiteMapNodeItem = (SiteMapNodeItem)oControl;

              foreach (Control aControl in oSiteMapNodeItem.Controls)
                  if(aControl.GetType().ToString() == "System.Web.UI.WebControls.HyperLink")
                      hlLink = (HyperLink)aControl;

                      if (hlLink.Text == IgnoreNode)
                         //don't call render
                          blnNodeWasIgnored = true;
                          blnNodeWasIgnored = false;

                  if (aControl.GetType().ToString() == "System.Web.UI.WebControls.Literal")
                      if (blnNodeWasIgnored == true)
                          //don't render the seperator

To deploy this control it needs to be strongly named and installed to the GAC using gacutil.exe

An entry in the web.config of your web application needs to be added:

<SafeControl Assembly="CustomBreadcrumb, Version=, Culture=neutral, PublicKeyToken=91e52569228df0da" Namespace="CustomBreadcrumb" TypeName="*" Safe="True" />

(Use reflector to find out the public key token of your dll.)

Restart IIS or even better recycle the relevant application pool.

You will need to register the control by adding the following line in the master page:

<%@ Register TagPrefix="adg" Namespace="CustomBreadcrumb" Assembly="CustomBreadcrumb, Version=, Culture=neutral, PublicKeyToken=91e52569228df0da" %>

Finally add the control to your master page, publish and approve the page.

Book review - Microsoft SharePoint Building Office 2007 Solutions in C# 2005 - Scott Hillier

Microsoft SharePoint Building Office 2007 Solutions in C# 2005 is an ideal book for people who are entirely new to SharePoint and also for those who are familiar with SharePoint 2003 and want to get up to speed quickly with the new functionality and features of MOSS 2007. Scott Hillier starts right from the beginning and addresses many of the common issues faced by people looking to utilise MOSS 2007 within their organisation.

He begins by looking at the none technical aspects of adopting MOSS and has some great advice on how to go about getting people to buy in to the relatively new concept of using business configurable IT tools to facilitate collaborative working. Once that is done he moves straight on to a step by step guide to installing MOSS 2007 which gets you up and running with a useable system very quickly. The remainder of the book is devoted to the many and varied features of MOSS 2007. This is a huge product that now includes the Web Content Management that was previously found in CMS 2002. Add to this the ability to use Windows Workflow Foundation to incorporate workflows into your sites and the new concept of packaging functionality up as features and you can appreciate that it must have been a real challenge to fit all of this into one book.

Whilst no one area is covered in a massive amount of detail the book gives enough information to get started looking at almost all aspects of what MOSS 2007 has to offer. Having already had experience of SharePoint 2003 I was looking for a book that would quickly bring me up to speed with the new functionality on offer and this book really delivers that. It is written with a clear and concise style that is very easy to read and understand. Step by step guides are provided along with plenty of screenshots making the workshop sections of the book easy to follow and complete.

If you are looking for a way to get a good working overview of what is available in MOSS 2007, packaged in a way that will take you right from start to finish then this is the book for you.

SharePoint 2007 Features on CodePlex

Features project on CodePlex:

Project Description
This is a project for SharePoint 2007 Features. Features add new functionality to a SharePoint 2007 farm, site collection, or site. This project will create Features to address deficiencies in SharePoint 2007 or add new capabilities. You should understand a little about Features before trying these out. The packages here use batch files or WSP files to install the Features. After installation, be sure to activate the Features to see them in SharePoint.

MOSS 2007 governance

It isn't enough to have a thorough technical understanding of MOSS 2007 to achieve a successful implementation. To be truly successful the implementation needs to be carefully managed. Microsoft have produced a useful checklist to make sure you have considered the issues surrounding governance and control of your MOSS 2007 server farms.

SPGridView sorting when using a datasource

The few examples of sorting an SPGridView I have found use a DataSet which then allows you to use a DataView to sort the contents of the SPGridView.

I am using a CAML query as my data source so this is not possible, instead I pass the sort expression and sort direction to the query and handle the sorting that way.

First of all I create a sorting event and add this to the SPGridView - credit for this code goes to ElPowlo :

void _gvProducts_Sorting(object sender, GridViewSortEventArgs e)
            string lastExpression = "";
            if (ViewState["SortExpression"] != null)
                lastExpression = ViewState["SortExpression"].ToString();

            string lastDirection = "asc";
            if (ViewState["SortDirection"] != null)
                lastDirection = ViewState["SortDirection"].ToString();

            string newDirection = "asc";
            if (e.SortExpression == lastExpression)
                newDirection = (lastDirection == "asc") ? "desc" : "asc";

            ViewState["SortExpression"] = e.SortExpression;
            ViewState["SortDirection"] = newDirection;

            PopulateSPGridView(e.SortExpression, newDirection);

I then populate my SPGridView using the sort criteria - in my real world project I also pass some values to filter the SPGridView but these have been left out here:

      void PopulateSPGridView(string strSortExpression, string strSortDirection)
            sdsProducts = new SPDataSource();
            SPList oList = site.Lists["Pages"];
            sdsProducts.List = oList;
            sdsProducts.DataSourceMode = SPDataSourceMode.List;                     
            string strSortDirectionBool = "";

            //Convert asc and desc to True and False for use in the CAML query

            if(strSortDirection == "asc")
                strSortDirectionBool = "True";
                strSortDirectionBool = "False";

                        sdsProducts.SelectCommand = "<ViewFields><FieldRef Name='Product_x0020_ID' /><FieldRef Name='Title' />"
               + "<FieldRef Name='Brand' /><FieldRef Name='Chemistry' />"
               + "</ViewFields><Query><OrderBy><FieldRef Name='" + strSortExpression + "' Ascending='" + strSortDirectionBool + "' /></OrderBy></Query>";
            _gvProducts.DataSource = sdsProducts;

For more information on CAML queries and a useful CAML Query Builder have a look at Patrick Tissegham's U2U site

Deploying a WebPart solution in MOSS 2007 the easy way

My colleague Andrew Westgarth has just sent me a link to the following blog post that shows you how to deploy webpart solutions without having to mess about with individual web.config files. Takes a little bit of time to setup but worth it in the long run!

Alternatively Andrew Connell suggests this way to create your WSP file