Nov8

Introducing the Cross Site Collection Search Configurator

 Categories: Development, SharePoint, Tools

While I was working at Intergen I was alerted to a small issue with configuring search keywords, best bets and synonyms. This simply being that they are set on a per site collection basis and there is no OOTB solution to share them. This has previously meant either using manual steps to ensure that your search settings are consistent across many site collections or the use of a product from Bamboo Solutions, sorry the name of the product escapes me at present, which is designed to do a whole lot more than just share search config.

Enter the Cross Site Collection Search Configurator a.k.a. CS2C. This solution is designed to allow you to share your site collection based search configuration between site collections in the same web application.

Currently the solution shares Keywords, Best Bets and Synonyms in a master and slave manner, that is using a new page in the Central Administration tool you set the Master Site Collection and then choose which site collections are to be slaves. This is coupled with a timer job which when activated against the web application runs hourly to synchronise all the Keywords, Best Bets and Synonym settings from the Master Site Collection to each of the Slave Site Collections.

Note: that currently if you manually set any Keywords etc. on a Slave Site Collection they will be lost when the timer job next runs.

This is definitely alpha software at this stage and although I've not found any bugs I'm sure they are lurking in there.

You can find the both the source code and a wsp over on CodePlex. Please be advised that this solution is built using Visual Studio 2008 and VSeWSS 1.2

At this stage my plans for future versions is to ensure that manual settings in Slave Site Collections are preserved, add support for sharing scopes across site collections and to improve the management screen.

Please do contact me if you have any feature requests, questions or comments.

 
 
Sep21

Turn off custom error pages in SharePoint.

 Categories: Best Practice, Development, SharePoint

There are a number of good posts out there that will tell you how to get useful, for a developer, error messages out of SharePoint.

In addition to these great tips also ensure that you edit the web.config in your _layouts directory to disable custom error messages.

 
 
Sep16

SharePoint and Agile

 Categories: Best Practice, Development

Go together like a horse and carriage.

Well, that's my take anyway. I've been involved on a few SharePoint projects now that have taken a tradition approach, i.e. waterfall style, to the development of the customers desired end product. While we did deliver a good solution to the customer I feel that had we taken an agile approach then the end product delivered could have been an absolute killer!

So, why does SharePoint lend itself to an agile approach?

Users don't get stuff until they see it. This holds true for all software, we've all drawn wire-frames and had whiteboard sessions to explain what this new application will look like. Then in the traditional space, the developer disappears into his darkened corner for days/weeks/months returning with something that resembles what was discussed. Oh sure it meets the requirements as they were stated in the requirements docs but does it work for the user? 

Rapid prototyping. When looking at SharePoint for document management or other intranet style usages it is simple to create a rough working model of what the client is after. This helps to ensure that the we can deliver what the client really wants, not just what we think they are asking for.

On the fly tweaks and changes. I was sitting in a demo session the other day with a client who was explaining how they would expect to interact with some data in a particular scenario. Now the views that I had over that calendar list didn't help them to see what they needed to. Thanks to the ability to create custom views across lists and libraries I was able to whip up and fine tune a custom view. This view will help the users achieve their goals. I know that this view it right as it was essentially built by the user just with me manipulating the tools.

Users can build stuff themselves. Just taking the prototyping another step, users who have had some training can take on some of the prototyping themselves. Admittedly there's not going to be huge numbers of users that will be able to or want to do this, however those that are this way inclined will love being able to get and involved.

Of course the usual arguments in favour of an agile methodology over a more traditional waterfall approach still hold. I refer you to the Agile Manifesto, Where is the Proof Agile Methods Work and Why Agile Software Development Techniques Work. Sure there are arguments against agile, but it is my firm belief that in the software services industry agile approaches will deliver the customer a solution that fits their needs better and reduce the cost of doing so.

 
 
Aug15

Difference Disks = Win

 Categories: Development, General, Tools

Huge thanks to Reza Alirezaei for his series of posts on creating your own time bombed VM.

After reading that I thought to myself, 'hey, I could use that technique to keep a set of different VMs across multiple projects with the same base set up'.

After a couple of hours of installing, configuring and tinkering with a base MOSS Dev VM followed by 20 minutes of setting up difference disks I now have a shiny new set of VMs running off a common base.

If you're anything like me and love working with virtual machines I strongly suggest that you look at this technique, it's saved me a good deal of disk space and lowered the time to set up a new development environment to but a few minutes.

 
 
Aug13

Pre-Populate a SharePoint List Instance

 Categories: CAML, Development, SharePoint

So, you want to provide a look-up in a SharePoint Site Definition and you'd quite like to provide your users with some options? (i.e. items in the source list)

Firstly you're probably interested in this post from Josh Gaffy about adding a lookup column declaratively using CAML.

Next you'll be wanting to use this snippet to declare your source list and the data it will contain.

   1: <?xml version="1.0" encoding="utf-8" ?>
   2: <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
   3:       <ListInstance FeatureId="89CA0ED1-8E9B-48fa-8C4D-CB406544D662"
   4:                 TemplateType="100"
   5:                 Title="Option List"
   6:                         OnQuickLaunch="TRUE"
   7:                 Description="Choices"
   8:                 Url="Options" >
   9:             <Data>
  10:                   <Rows>
  11:                         <Row>
  12:                               <Field Name="Title">Foo</Field>
  13:                         </Row>
  14:                         <Row>
  15:                               <Field Name="Title">Bar</Field>
  16:                         </Row>
  17:                         <Row>
  18:                               <Field Name="Title">Fred</Field>
  19:                         </Row>
  20:                         <Row>
  21:                               <Field Name="Title">Mildred</Field>
  22:                         </Row>
  23:                         <Row>
  24:                               <Field Name="Title">Karl</Field>
  25:                         </Row>
  26:                         <Row>
  27:                               <Field Name="Title">Lenny</Field>
  28:                         </Row>
  29:                   </Rows>
  30:             </Data>
  31:       </ListInstance>
  32: </Elements>

Hope that someone finds this useful.

 
 
Jul15

National SPUG Tour

 Categories: Deployment, Development, General, SharePoint, Tools, Visual Studio, VSeWSS

So Matt Smith of the Christchurch SharePoint User Group has organised a national tour for the various SPUGs that are active here in New Zealand.

I'll be talking in Auckland, Tauranga and Christchurch over the space of a week. The fine people in Tauranga are either doubly blessed or cursed as I'll be talking to both the SPUG and DNUG there.

The low down on the SPUG presentation:

Collaborative construction of custom SharePoint artifacts
See how business users, business analysts, developers and IT Pros can all come together to create new SharePoint artifacts for your business. In this session Gavin Barron will show how users from differing disciplines can all work together. Ensuring that an emerging business need is addressed quickly while following a number of SharePoint best practices. During this session Gavin will also discuss the development lifecycle as it exists in this context.

Presented by: Gavin Barron, Intergen Wellington

Intended Audience:

  • Business Users
  • Business Analysts
  • Developers
  • IT Professionals

The tour details:

Auckland: Wednesday, 23 July
Time: Drinks + Snacks from 5:15PM, Talk from 5:30PM to 6:30PM
Location: Level 7 Fronde House, 131 Queen Street

Tauranga: Thursday, 24 July
Time: Drinks + Snacks from 5:30PM, Talk from 6:00PM to 7:00PM
Location: EnvisionIT, Level 5 Westpac Building, 2 Devonport Road, Tauranga

Christchurch: Monday, 28 July
Time: Drinks + Snacks from 5:30PM, Talk from 6:00PM to 7:00PM
Location: Canterbury Innovation Incubator (CII), 200 Armagh Street (opposite Centennial Leisure Centre)

I'll post more on the Tauranga DNUG session later.

 
 
Jul14

/dev/gav

 Categories: Development, General, Intergen

I have been memed.

How old were you when you started programming?

10

How did you get started in programming?

I was a fresh faced young thing of 9 when my sister and I received a Commodore64 for Christmas. Incredibly after a few months I got tired of the assortment of games that we had. As luck would have it the amazing machine came bundled with the Commodore 64 MicroComputer User Manual which included more than the average User Manual will these days. That book taught me how to make my C64 do things! Soon I was making the most awful noises and random series of images flashing across the screen. It was possibly the best Christmas present ever.

What was your first language?

C64 BASIC

What was the first real program you wrote?

I'd have to say my synthesiser would be it, I had worked out how to program the SID chip built into the C64 and wired up some code to read what key was being pressed and then played a corresponding note.

What languages have you used since you started programming?

Visual Basic, Classic ASP, SQL, PL/SQL, JavaScript, C#, Java including J2EE, HUGS, PROLOG, Modula2, C, and pile of frameworks that have their own languages or XML vocabularies.

What was your first professional programming gig?

Writing VBA to connect an Access based contact database to some Excel documents, saving the office lady at least 20 minutes every time the client got a new work request, not to mention reducing data errors due to the removal of the Alt+Tab integration layer. 

If you knew then what you know now, would you have started programming?

Absolutely, I probably would have pursued it as a career option sooner too!

If there is one thing you learned along the way that you would tell new developers, what would it be?

Don't look for the 'perfect answer' to a given question. Look for the answer that best suits the needs of the client because at the end of the day our job is ultimately about how well can we make life better for them.

What’s the most fun you’ve ever had… programming?

For me the the best thing about this job is the people, it's one of the reasons I love working at Intergen. The people make it a place that I want to be. Sure the challenges of solving tough technical issues are great and highly rewarding but for me the people make it really worthwhile. Be it knowing the shared pain of a hellish project or the healthy debate of Guids v.s. auto incrementing integers as keys the people make this industry what it is.

I choose

 
 
Jun30

Method Names of Excellence!

 Categories: WTF, Development, Intergen

Just had a great giggle and a shudder after my workmate Henrik showed me some code that is the latest check-in for a project, and I assume running on a site out there.

   1: protected void Page_Load(object sender, EventArgs e)
   2: {
   3:     if (Request.QueryString["QueryStringKeyOfAwesomeness"] != null)
   4:     {
   5:         ThisWillBeEmbarrassingOneDay();
   6:     }
   7: }

Inside the same class we have methods with such glorious names as:

  • DoSomeMoreTrippyStuffOggaOgga()
  • DoSomeCrazyAssDataUpdatesV2Awesome()
  • DoJDMagicalSuperUpgradeWOotWOt()

Somewhat disturbing that the ThisWillBeEmbarrassingOneDay() can still be run on the live site if you know the magical key, but those method names, wow!

What is the craziest method name that you have encountered?

 
 
Jun20

Paul Andrew from the SharePoint Team in Wellington New Zealand

 Categories: Development, VSeWSS, SharePoint

Chan has just announced that Paul Andrew is going to be visiting us here in Wellington, New Zealand and presenting to the SharePoint Users Group :o)

This special event will be held in Xero offices 5pm Friday 27 June 2008. Yes, it's a Friday, but as usual there will be pizza and drinks plus the chance to grill one of the Product Manager for the SharePoint team ;o)

I've worked with for Paul on a couple of projects that Intergen have done for Microsoft now. I'd say that the session that he is going to present will be focused on VSeWSS 1.2, this being the Visual Studio 2008 compatible version of VSeWSS 1.1.

Please register your interest by RSVP to kirkj@paradise.net.nz and wlgspug@sharepointservices.net.nz

Hope to see plenty of you there :o)

 
 
May27

SharePoint Navigation Elements: How to Code with them.

 Categories: Development, SharePoint

I'm a pretty regular poster over on the MSDN SharePoint dev forum and one of the things that I see pop up every so often is questions about how to interact with the Navigation components that are built into SharePoint.

Now you can fiddle with these through the web UI, but really, where is the fun in that? No to mention the fact that I want software to alter my navigation elements as necessary.

I've been working on a large piece of work, part of which includes the automated provisioning of Sites and Site Collections, so I got to spend a little time writing code to alter the navigational elements within my SharePoint instances.

One thing that I've found a little annoying was that I couldn't find a way to ensure that one of the lists in my site definition appeared in the Quick Launch bar, it would appear if I created the site through the UI, but not when I created the new site in code. :o|

The solution:

   1: SPList submissionsList = newWeb.Lists["Submissions"];
   2: submissionsList.OnQuickLaunch = true;
   3: submissionsList.Update();

Simply set the OnQuickLaunch property of the list, oh and make sure you call Update() ;o)

Ok, so what about inserting other links into the Quick Launch and Top Navigation? Luckily it's pretty easy. The SharePoint object model provides us with the SPNavigationNode and SPNavigationNodeCollection classes.

   1: //get the quicklaunch and top nav for the target Web.
   2: SPNavigationNodeCollection quickLaunchNodes = targetWeb.Navigation.QuickLaunch;
   3: SPNavigationNodeCollection localTopNav = targetWeb.Navigation.TopNavigationBar;

Now SharePoint has a few smarts when it comes to navigation nodes, it contains the ability to create navigation nodes that will automatically update their target URL if the that URL maps to a location within the current site collection, this is acheived by passing false as the isExternal parameter in the constructor for the SPNavigationNode.

   1: //create the new node but have WSS maintain this link automagically
   2: SPNavigationNode newNode = new SPNavigationNode(newWeb.Title, newWeb.ServerRelativeUrl, false);

Note that if the URL supplied in the constructor is for a location outside the Site Collection where this SPNavigationNode is to be held the you must pass true for the isExternal parameter, otherwise your code will throw an exception.

Now that you have a new node you can add it directly to the SPNavigationNodeCollection that you wish to using either the AddAsFirst or AddAsLast methods but that's not going to be all that useful if you want to maintain some form of order.... The SPNavigationNode class contains a Children property, which as you might guess is a SPNavigationNode collection! This notion of nested node collections is how the Quick Launch Bar maintains its orgainisation. So quite often you'll actually want to find a particular node in the QuickLaunch or TopNavigationBar collections of nodes and add the new node as a child to the desired node.

I created this helper method for this purpose and just made a couple of calls to add the new SPNavigationNode that I created earlier:

   1: //Add the new Navigation node to the QuickLaunch and the TopNav
   2: InsertNavigationNodeToCollectionAsChild(targetWeb, newNode, localTopNav, COURSES_NODE_TITLE);
   3: InsertNavigationNodeToCollectionAsChild(targetWeb, newNode, quickLaunchNodes, "Sites");
   1: private void InsertNavigationNodeToCollectionAsChild(SPWeb rootWeb, 
   2:                                                         SPNavigationNode nodeToInsert, 
   3:                                                         SPNavigationNodeCollection targetNodeCollection, 
   4:                                                         string parentNodeTitle)
   5: {
   6:     bool hasParentNode = false;
   7:     foreach (SPNavigationNode node in targetNodeCollection)
   8:     {
   9:         if (parentNodeTitle == node.Title)
  10:         {
  11:             //Found the required parent node, add to it, 
  12:             //set up our test variable, update and break from the loop
  13:             hasParentNode = true;
  14:             node.Children.AddAsFirst(nodeToInsert);
  15:             node.Update();
  16:             break;
  17:         }
  18:     }
  19:     if (!hasParentNode)
  20:     {
  21:         //the desired parent node doesn't exist so create it ;o)
  22:         //create as external so that no attempt to maintain is made by WSS
  23:         SPNavigationNode coursesNode = new SPNavigationNode(parentNodeTitle, "", true);
  24:  
  25:         //add the parent at the end of the targetNodeCollection 
  26:         targetNodeCollection.AddAsLast(coursesNode);
  27:         coursesNode.Update();
  28:         //Add our new site collection node to it's parent
  29:         coursesNode.Children.AddAsFirst(nodeToInsert);
  30:         nodeToInsert.Update();
  31:     }
  32:     //call update to make everything 'stick'
  33:     rootWeb.Update();
  34: }

Hope that someone out there finds this useful

kick it on DotNetKicks.com

 
 
 Next >>