Nov8
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
Categories: Best Practice, Development, SharePointThere 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
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.
Sep16
Categories: Tools, SharePoint
A workmate just put me onto a great resource that Zac showed during the Tech-Ed session on Tools and techniques which he presented with Matt.
These are a great set of bookmarks that work relative to your current page and let you quickly access various application pages, check out the SharePoint developer bookmarklets from Waldek Mastykarz.
Sep5
Categories: I've just seen the awesome power of delegates, I can't believe that I've never used them all that much before, mostly because I've been able to take advantage of using SQL or CAML to do my ordering, hey adding an ORDER BY or <OrderBy> clause is dead easy ;).
Last night I was in the situation where I was composing a List<T> over n calls to the database and need to order my objects. Now in this case my business object have a few properties, actually they are WCF message objects, and I need to use a flexible ordering scheme as I know of at least two types of sort that are required at this stage. Enter delegate based sorting.
A quick look at the MSDN docs and I'm away.
Business Object:
1: [DataContract]
2: public class StudentSubmissionActivity
3: {
4: private string _courseCode;
5: private string _description;
6: private DateTime _dueDate;
7:
8: [DataMember]
9: public DateTime DueDate
10: {
11: get { return _dueDate; }
12: set { _dueDate = value; }
13: }
14:
15:
16: [DataMember]
17: public string Description
18: {
19: get { return _description; }
20: set { _description = value; }
21: }
22:
23: [DataMember]
24: public string CourseCode
25: {
26: get { return _courseCode; }
27: set { _courseCode = value; }
28: }
29: }
CompareByDescription:
1: public static int CompareByDescription(StudentSubmissionActivity x, StudentSubmissionActivity y)
2: {
3: if (null == x.Description)
4: {
5: if (null == y.Description)
6: {
7: // Both the same so return 0
8: return 0;
9: }
10: //y.Description is non null therefore greater, return -1
11: return -1;
12: }
13: else
14: {
15: if (null == y.Description)
16: {
17: // x.Description is non-null, therefore greater, return 1
18: return 1;
19: }
20: // both are non-null do the comparison
21: return x.Description.CompareTo(y.Description);
22: }
23: }
As strings are nullable we need to do a bunch of null checking before we can call the native string.Compare method.
CompareByDueDate:
1: public static int CompareByDueDate(StudentSubmissionActivity x,
2: StudentSubmissionActivity y)
3: {
4: return x.DueDate.CompareTo(y.DueDate);
5: }
Here due to the fact that I've used standard DateTime objects I can skip the null checking and just use the native DateTime.Compare method straight off, however if I'd used the nullable DateTime? type then the null checking pattern used in the CompareByDescription method would be necessary.
Now using these comparison methods is dead easy!
Sample Usage:
1: public List<StudentSubmissionActivity> LoadSortedSubmissionActivities(List<string> courseCodes,
2: StudentSubmissionActivitySorting sortOption)
3: {
4: List<StudentSubmissionActivity> results = new List<StudentSubmissionActivity>();
5: foreach (string courseCode in courseCodes)
6: {
7: DataAccess.StudentSubmissionActivity.LoadIntoListForCourse(results, courseCode);
8: }
9:
10: if (StudentSubmissionActivitySorting.DateSort == sortOption)
11: {
12: results.Sort(CompareByDueDate);
13: }
14: else if (StudentSubmissionActivitySorting.DescriptionSort == sortOption)
15: {
16: results.Sort(CompareByDescription);
17: }
18:
19: return results;
20: }
Happy delegation!
Aug15
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
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.
Aug12
Categories: ToolsAlright, I've just had to edit an existing wsp :o|
I won't go into the why and wherefores, suffice to say that I decided that the easiest way to achieve my end was to extract the contents, edit the necessary XML file and repack the cab.
Now I didn't feel like writing a ddf and using MAKECAB.EXE for this quick hack, so I had a quick Google Live Search ;o) and found CabPack 1.4 sure it was last written in 1999 but it works, it's free and the UI is dead easy to use.
That is the total extent of the UI, there is easy to follow documentation provided too.
Jul31
Categories: Best Practice, SharePoint
Firstly thanks to everyone who came along, it was great to meet so many people either using SharePoint out there in the "Real World"™ and others who were just keen to learn more.
Further thanks to:
And as promised here are the slide decks and a link to the code that I used on the tour.
Get on out there and get SharePointing :o)
Jul15
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.
Next >>