Showing posts with label WSS. Show all posts
Showing posts with label WSS. Show all posts

Tuesday, January 19, 2010

SendEmailNotification not sending emails

This is a tough one. There could be a whole bunch of reasons why your workflow tasks are not sending the OOB emails when a task is assigned. Here are just a few symptoms and their solutions

1) No emails are being sent, not receiving alerts
-Check your SMTP settings in Central Administration. Under Operations you will find Outgoing Email Settings. Make sure that a valid SMTP server is entered there. Either your local machine is running the smtp service which means the local machine name should be there or you are using an external smtp server to send your emails

-Try to connect to the smtp server using telnet on port 25.
a) open up a command prompt
b) type in: telnet smtp.yourserver.com 25
c) If you can connect, type in EHLO or HELO. If any of those give you back useful message your SharePoint Server is able to communicate with your smtp server.
Try sending a test message via telnet:
EHLO
MAIL FROM:someemail@domain.com
RCPT TO:validemail@domain.com
DATA email body
Test email message
.

Done. Make sure to do the CRLF.CRLF bit to send of the message. If it arrives, then you can rest assured that no smtp server config or firewall is blocking your SharePoint server.

Still no emails?
Make sure that the Windows SharePoint Timer Service is set to automatic and is currently in a running state. If that service crashed, or if someone stops it, no jobs will run, including the task emails and alerts.

Still plum out of luck? (been flying too much Air New Zealand lately) Make sure that the user has an email address defined!!! This sounds simple but can be a bitch when using MOSS.
When using WSS, simply click the header where it says Welcome Dude and select Edit my Settings from the dropdown. Add the missing email.
If using MOSS, you will need to update your profile either using your MySite, but if that is not available, go to the SSP Admin site and edit the profile manually there. But beware! Those changes might take some time to trickle down to your different site collections. To speed up the process open a command on the server and type stsadm -o sync
That will kick start the profile sync bewteen the profile store in SSP and the UserInfo Lists in the different SharePoint Sites.

Problem: You still can not see your changes on the userdisp.aspx pages of your site collections. even after executing the sync command and waiting a few moments paitently.
Reason: the user you are looking at is in the system, but not set as active in SharePoint. The only way to activate a user in SP is for that user to log in and do stuff. like adding, editing or deleting list items or documents. So do some stuff and execute the sync command again. That should do the trick.


So now you can see the email address on the user profile page (userdisp.aspx) but still not receiving task emails for your custom workflow tasks...
Maybe you're just impatient. the timer job is set to run every 5 minutes. to speed this up you can change the frequency using stsadm -o setproperty
the property you're looking for is job-immediate-alerts
the value is "Every 1 minute between 0 and 59"
But set that property at your own risk. It will also affect alerts on the farm.



EMail is set, user is active, smtp is behaving and the Timer Service is running, but no emails from your custom workflow.

Solution: First test if you get emails for any OOB workflows like approval and Feedback. If so, then there is an issue with multiple applicaitons using the same task list. I found assigning a new Task list for my custom workflow resolved this issue and SharePoint would send out mails for new tasks as expected. This behaviour is often caused when sites are exported and imported using stsadm. Not all settings are correctly migrated causing this behaviour to crop up. Another reason to be wary of using the export and import functionality in SharePoint to migrate solutions...

Tuesday, October 6, 2009

Multiple Templates per Document Library

I recently got a typical FAQ in my inbox:
"I have set up a sharepoint document library which has a template associated with it, whereby when you create a new document by selecting "new" from the menu bar, the document opens using the associated template.
What I would like to know is, is it possible to associate multiple templates to a document library so that when creating a new document by selection "new", you are offered a choice of templates to use? I'm hoping this is possible!!!"

Nothing simpler than that. The magic word is called Content Types. Okay. Two words then.
You can associate one template with a document library and associate one template with a content type(CT). As soon as a document library(DL) has more than one content type associated with it you will get more than one option when hitting the little arrow next to the new button. Careful, hitting the "New" on the New button will always start up the default CT, which is the first in the list.
So what to do next? Go to the site where you want to use multiple templates and under Site Settings go to the Content Type Gallery. There you create a new CT based of the existing CT called "Document". Now under Advanced Settings of that CT you can upload a new template to use when the New action is chosen. Finally go to Settings page of the DL in quesiton and enable multiple CTs under Advanced Settings of that DL. That will bring up a new section on the Settings page called... "Content Types" where there is a link to add from existing CTs. using that link add your new CT to the list and you're done. You can add as many as you like, but beware, the list should not get too long or you will get usability problems.
One last tip. You can create new CTs at the root of your site collection or within an individual site. CTs are visible only to the site you created it in and all its sub sites. So creating it at the root makes it visible across the whole site collection, but creating it in a specific site will make sure it does not appear further up in the hierarchy or in any of the sibling sites. This can be handy when certain CTs only make sense for specific DLs or specific sites. It is a good idea though to sit down and have a good think about where these CTs could be used and plan ahead where to create them.

Thursday, September 24, 2009

Busted: Customising the application.master

There are numerous articles out there about how to change the system master page. The one that all pages in the _layouts aka LAYOUTS folder use. In most cases they want to do this to enable a different datasource for the top navigation aka global navigation. The average rookie who is in charge of creating a site in MOSS using the publishing feature will stumble across this problem and start hacking away at either the original application.master, or even go and implement a custom http handler to exchange the application.master with a custom one on the fly. None of these approaches are best practice nor are they supported by MS. So is it impossible to fix without breaking the system? Not at all.
I've published a solution to www.sharepointmythbuster.com! It will allow you to replace the top navigation on the fly for all pages in the site collection, including those horrid system pages and application pages.

Wednesday, September 16, 2009

Gettting Started with SharePoint development

Microsoft put together ten labs for Developing on SharePoint and also provided a fully functional VPC for you to get started. Time for the image is running out, as it will expire on 30/09/09. So if you don't have your own SharePoint development environment and wish to have a look at what all the hype is about go and download the image quick

VPC Image:
http://www.microsoft.com/downloads/details.aspx?FamilyID=1beeac6f-2ea1-4769-9948-74a74bd604fa&DisplayLang=en

WSS Hands on Labs:
http://www.microsoft.com/downloads/details.aspx?familyid=B885DCE8-C93F-48AA-B798-4422FEBCC200&displaylang=en

Loads of Resources, Demos, and online Walkthroughs
http://www.microsoft.com/click/SharePointDeveloper/

Thursday, September 10, 2009

SharePoint Event Troubleshooting Tips

Gary from Combined-Knowledge pointed out this useful post in the WSS SDK today.
http://msdn.microsoft.com/en-us/library/aa979520.aspx
It is a great little list of issues you will come across when working with Event Receivers in SharePoint. You're bound to have come across the one or other weird behaviour when implementing events. You're not alone. The above list mentions a dozen common issues to be careful of.

How to Pre populate Form Fields in SharePoint

Can't do it better than the boys over at Endusersharepoint. A great JQuery script which works universally with all kinds of Field types including lookups and date time fields.
Just plonk this onto your EditForm or the page with your Dataview and off you go.
Sadly there are no delegate controls on the built in EditForm.aspx for you to override automatically so you will have to either customise the editforms or build your own for your cusotm content type or cusotm lists definition.

http://www.endusersharepoint.com/2009/04/20/jquery-for-everyone-pre-populate-form-fields/

Tuesday, June 9, 2009

SQL Server Autogrowth for SharePoint

I was aksed today what Autogrowth setting would be best for a SharePoint Content Database. The simple answer? None! Autogrowth is one of the biggest resource eaters on badly designed SharePoint SQL Farms and can cause serious performance and stability issues (plus wreck havoc with your Hard Disks). The best option is to start big enough for your initial load and plan growth ahead.

Example: You are starting a new SharePoint ECM project and are planning on migrating 5 GB worth of files into the SharePoint Sites at go live. You also realise that you have never used versioning before and your staff will be quite active on about 10% of those files. Expecting to create on average one new version every week. i.e 500MB worth of new data being added every week. Thus scheduling a db file growth of 500MB during every weekend would deal with versioning. Add 100MB for new content to total it up to 600MB for week 1, 610 for week 2, 620 for week 3 and so forth, taking into account the growth of the files and the increase on versioning.

Having a sound versioning strategy with a cap for Major and Minor versions will help reign in this excessive growth!!!!

Obviously you will not always get it right and thus a combination of large Autogrowth (for example in 100MB increments) and weekly scheduled growth will give you the best combination for maximum performance and stability.

The final statement? Try to minimise the amount of times the dbs autogrow as much as you can by planning ahead, and when they do auto grow mak sure the increments are large enough to keep you going withminimal disruption until the next scheduled growth. Don't make them too large either as fetching hard disk space for the db files can put a strain on the Disks at the most impractical times like during peak hours and impair the stability of the system

Wednesday, June 3, 2009

Integrating AJAX Control Toolkit into SharePoint

Hey folks, sorry it took me a week to get round to this blog post, but I needed to make sure I could upload all the stuff somehow. This is going to be a big one, so sit back, relax and enjoy the show:

Ajax Control Toolkit

A compilation of dynamic controls
—With and without Server Side interaction
—Built on the System.Web.Extensions Components
—Samples at http://www.asp.net/ajax/
—Source at http://www.codeplex.com/

Prerequisites

Minimum
—ASP.NET 2.0 AJAX Extensions v1.0
—Ajax Control Toolkit 20229 (.net 2.0)
—Windows SharePoint Services 3.0 SP1
Recommended
—NET Framework 3.5 SP1
—Ajax Control Toolkit 30512 (.net 3.5sp1)
—Windows SharePoint Services 3.0 SP2

How to get it running? a combination of tweaking the web.config, and clever web part design

Configure the web.config

<configSections>
<sectionGroup name="system.web.extensions" type="System.Web.Configuration.SystemWebExtensionsSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<sectionGroup name="scripting" type="System.Web.Configuration.ScriptingSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="scriptResourceHandler" type="System.Web.Configuration.ScriptingScriptResourceHandlerSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication"/>
<sectionGroup name="webServices" type="System.Web.Configuration.ScriptingWebServicesSectionGroup, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35">
<section name="jsonSerialization" type="System.Web.Configuration.ScriptingJsonSerializationSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="Everywhere" />
<section name="profileService" type="System.Web.Configuration.ScriptingProfileServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
<section name="authenticationService" type="System.Web.Configuration.ScriptingAuthenticationServiceSection, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="false" allowDefinition="MachineToApplication" />
</sectionGroup>
</sectionGroup>
</sectionGroup>
</configSections>

Allow Ajax controls on the pages

<pages>
<controls>
<add tagPrefix="asp" namespace="System.Web.UI" assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</controls>
</pages>

Add Extensions Assembly

 <assemblies>
<add assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</assemblies>

Add Ajax Http handlers

<httpHandlers>
<add verb="*" path="*.asmx" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="*" path="*_AppService.axd" validate="false" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" validate="false"/>
</httpHandlers>

Add Http Module

<httpModules>
<add name="ScriptModule" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</httpModules>

Add WebServer config section (IIS7.0 only)

<system.webServer>
<validation validateIntegratedModeConfiguration="false"/>
<modules>
<add name="ScriptModule" preCondition="integratedMode" type="System.Web.Handlers.ScriptModule, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
</modules>
<handlers>
<remove name="WebServiceHandlerFactory-Integrated" />
<add name="ScriptHandlerFactory" verb="*" path="*.asmx" preCondition="integratedMode“
type="
System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptHandlerFactoryAppServices" verb="*" path="*_AppService.axd" preCondition="integratedMode" type="System.Web.Script.Services.ScriptHandlerFactory, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"/>
<add name="ScriptResource" preCondition="integratedMode" verb="GET,HEAD" path="ScriptResource.axd" type="System.Web.Handlers.ScriptResourceHandler, System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</handlers>
</system.webServer>

Optional, add profile config

<system.web.extensions>
<scripting>
<webServices>
<authenticationService enabled="true" requireSSL = "truefalse"/>
<profileService enabled="true” readAccessProperties=“First,Last"
writeAccessProperties=“First,Last" />
</webServices>
<scriptResourceHandler enableCompression="true" enableCaching="true" />
</scripting>
</system.web.extensions>

IMPORTANT: Mark Ajax controls as Safe

<SafeControls>
<SafeControl Assembly="System.Web.Extensions, Version=3.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" Namespace="System.Web.UI" TypeName="*" Safe="True" />
</SafeControls>

Add Script Manager to Page

To the master page right at the top
<asp:ScriptManager runat="server" ID="ScriptManager1"></asp:ScriptManager>
Or programatically in a baseclass for your AJAX enabled Webparts
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (ScriptManager.GetCurrent(this.Page) == null)
{
ScriptManager scmanager = new ScriptManager();
scmanager.ID = "scriptManager";
Page.Form.Controls.AddAt(0,scmanager);
}
}

Next up: a sample WebPart that uses the AutoComplete control from the toolbox . Before you can use the toolkit you will need to download and compile the project though. Then add the reference to the toolkit in your WebPart Project.

using System;
using System.Runtime.InteropServices;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Xml.Serialization;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.WebPartPages;
using AjaxControlToolkit;

namespace KnowledgeCue.WSS.AjaxWebParts
{
[Guid("6ef07bde-99b3-45d0-8dd4-33ce7ae25572")]
public class AutoCompleteTextBox : KnowledgeCue.WSS.BaseWebPart
{
Literal textBoxLabel = new Literal();
TextBox textBox = new TextBox();
AutoCompleteExtender autoComplete = new AutoCompleteExtender();

public AutoCompleteTextBox()
{
}

protected override void CreateChildControls()
{
base.CreateChildControls();
string webServicePath = "http://wss-1:90/_layouts/AutoCompleteService.asmx";

textBoxLabel.Text = "Type the name of a cool dude";
this.Controls.Add(textBoxLabel);
textBox.Attributes.Add("id", "SelectCoolDudeTextBox");
textBox.ID = "SelectCoolDudeTextBox";
this.Controls.Add(textBox); ;

autoComplete.MinimumPrefixLength = 1;
autoComplete.ServicePath = webServicePath;
autoComplete.ServiceMethod = "GetCoolDudes";
autoComplete.TargetControlID = "SelectCoolDudeTextBox";
this.Controls.Add(autoComplete);
}
//Script Manager Fix
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
if (ScriptManager.GetCurrent(this.Page) == null)
{
ScriptManager child = new ScriptManager();
child.ID = "scriptManager";
if (this.Page.IsPostBack)
{
this.Page.ClientScript.RegisterStartupScript(typeof(AutoCompleteTextBox), this.ID, "_spOriginalFormAction = document.forms[0].action; _spSuppressFormOnSubmitWrapper=true;", true);
}
if (this.Page.Form != null)
{
string str = this.Page.Form.Attributes["onsubmit"];
if (!(string.IsNullOrEmpty(str) !(str == "return _spFormOnSubmitWrapper();")))
{
this.Page.Form.Attributes["onsubmit"] = "_spFormOnSubmitWrapper();";
}
this.Page.Form.Controls.AddAt(0, child);
}
}
}
}
}

Finally, the Webservice which the autocomplete textbox relies upon:
<%@ WebService Language="C#" Class="AutoCompleteService" %>

using System;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Web.Script.Services;
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[ScriptService]
public class AutoCompleteService : System.Web.Services.WebService {

[WebMethod]
[ScriptMethod]
public System.Collections.Generic.List<string> GetCoolDudes(string prefixText, int count) {
string[] dudes= new string[] { "Alex Dean", "Chandima Kulathilake", "Rachael Greene", "Dean Moor", "Duncan Hammond" };
System.Collections.Generic.List<string> dudeList = new System.Collections.Generic.List<string>();
int i = 0;
foreach (string dude in dudes)
{
if (i == count) break;
else
{
if (dude.ToLower().StartsWith(prefixText.ToLower()))
{
dudeList.Add(dude);
i++;
}
}
}
return dudeList;
}

}

SPVisualDev File exists in Template Error

I've stumbled across this one and it took me some time to figure it out. That error will crop up if you are deploying a file either via a feature or site template twice. In my case I had two Modules in an elements file to split up the Preview images from the actual files being deployed to the masterpage gallery. that's where SpVisualDev gets its knickers in the twist. Can't deal with multiple modules in one file and keeps on adding all files to the last module. also the ones that are already referenced in the first one.
Fix? put all files into one module or SPVisualDev will screw with the elements and it won't work.

Thursday, May 28, 2009

Exception handling Base WebPart

This piece of code will revolutionise the way you develop web parts in sharepoint. No more pages crapping out on you, no more crashes or unsolvable problems. All exception handling done for you automatically without the need to include a single try/catch block. I'm not saying you should not handle exceptions which you can forsee. But those are the easy ones. What about those unexpected ones?
Andreas Knudsen, a fellow SharePoint Programmer came up with a beautiful solution which takes full advantage of a combination between early and late binding to force the runtime to execute the exception handling version of the base routines before execuing your implementation code. As I'm not even going to try to take credit for this gem, get the code directly from the genius himself

http://andreascode.blogspot.com/2007/12/general-exception-handling-in-web-parts.html

How does it work? Playing with polymorphism is the answer.
The runtime always tries to find out the best version of a method on an object to call, no matter what type the pointer is.
When you put a line of code like

MyWebPart.CreateChildControls()

into your own code, the runtime will not have to look far, as you're calling it on the type of which the object is. But...

WebPart x = MyWebPart;
x.CreateChildControls();

Now the runtime will need to start at the base class WebPart and figure out which version is the best to call. Normally each new version overrides the old one and the runtime will end up at MyWebPart.CreateChildControls(). Unless you put a stop sign in between. Such a stop sign is the new keyword. When you have a class in between WebPart and MyWebPart (like MyBaseWebPart) and instead of writing public override CreateChildControls() but public new CreateChildControls() the runtime is forced to take a step back and execute the one a level up. To make it more visible you can seal off the exception handling method, just to be sure nobody tries to override it.

So now we've forced the runtime to execute the version of code that has exception handling. How do we get back to our implementation code? Through sidestepping the Stop sign. You need a new class which inherits from the exception handling class for this. the exception handling one calls a new function like CreateChildControlsX and the runtime will again try to figure out the best version and will end up in derived.CreateChildControlsX because you overrode it there. Here you simply call the original function name again (CreateChildControls) and the runtime will find the best version again. Now the runtime is not starting at the top (WebPart) but at the current location (derived) and thus the Stop sign is left behind and it can go all the way down to your implementation and execute that.

I know it sounds so geeky, But thise piece of code is seriously cooooooool.

Tuesday, May 26, 2009

SharePoint Explorer View in Windows 2008 and 2003

If anybody out there has been building demo machines on Windows Server 2008 or Windows Server 2003 you will have run into this issue at some point. Explorer View does not work on document libraries, nor can you map a network drive to a sharepoint site.
Following constellations come together:

a) the server platforms effectively don't like web folder views until you install the fix KB907306
That fix works for both Windows 2003 and 2008.
Now you can happily map a sharepoint site to your network places and use the Windows Explorer to browse the sharepoint sites.

b) your browser now complains that "This folder cannot be opened in Internet Explorer". This will happen when you have IE 7 or higher and protected mode is on. Simple. Disable protected mode via Tools>Internet Options>Security. Remember to add the site to the Intranet Zone

c) What? can't disable the protected mode on Windows Server 2008? No problem. Open the Server Manager. On the root node of the tool you should see Server Summary within there is a section for Security Information. Here you will find a link to Configure IE ESC (Enhanced Security Configuration). That's where you can disable the "microsoft parental controls for dummies" tick box.
d) now you can disable protected mode on the Intranet Zone.

You might ask, why not simply move the site to Trusted Sites. Well, Trusted sites actually have a higher security rating than Intranet zone. Plus you automatically get signed into the intranet zone and not to th trusted sites. Plus the sharepoint site is on the Intranet. So that is also the Zone it should live under!

PS. Running Windows Server 2008R2 or Windows Server 2008 SP1? Then try enabling the Feature called  "Desktop Experience" in the Roles and Features configuration of the Server

Happy Exploring!

Tuesday, April 14, 2009

Custom SQL Lookup Field in WSS 3.0

This is a question I get asked a lot! How to create your own version of the BDC Lookup for either WSS or MOSS. The answer is not simple. Nono. But not impossible either.
You need to create your own custom field that uses the Entity Picker to populate a list of records and allows you to pick one. There is a lot of CAML, XML, Classes, Events and Code to deal with.
Following is sample code to create just that based on another SharePoint list. Simply plug your own DAL instead of the SPQuery and you're up and running.
http://code.msdn.microsoft.com/WSS3EntityPicker

Step by step instructions:
http://msdn.microsoft.com/en-us/library/cc889345.aspx

Thursday, April 9, 2009

Best Practices for SharePoint - Blank Sites

If you ever plan on creating a new site, which starts off on a clean slate, especially with the WCM Publishing Features activated you must use stsadm to do that. Effectively three commands will get you started nice and simple with the most blank publishing site you can immagine:

a) create an absolute blank sitecolleciton with really nothing in it
stsadm -o createsite -url http://servername -ownerlogin domain\username -owneremail owner@domain.com

b) activate the publishing feature on the site collection level
stsadm -o activatefeature -name PublishingSite -url http://servername

c) activate the publishing feature on the web level
stsadm -o activatefeature -name PublishingWeb -url http://servername

That's it. go to your url and you will find the most minimalistic publishing site you will be able to get that has all the publishing features activated.
Now you can start building your own site template based on this and be sure that content deployment will give you less headaches should you ever decide to go down that route in future.

Upgrading WSS 3.0 to MOSS

Just came across a weird one. After doing an in place upgrade of a test installation the Publishing Feature would not activate. Keeps on coming up with an Access Denied message. Ok, so maybe I should have deinstalled WSS 3.0, installed MOSS clean and then reattached the content databases to be on the safe side. But hey, i did say it was a test machine.
The solution is not that obvious though. Looks like the Publishing Feature can't activate because the feature dependency Publishing Resources is not actice. Only solution is to activate the Resources manually via stsadm and then you can activate the publishing feature via the gui.

here's the magic command:
stsadm -o activatefeature -name PublishingResources -url http://YourSharepointSite
Happy upgrading!

Customising the SharePoint Calendar

A few days ago I came across a great post by syed.er's blog called Bending SharePoint without bending the rules. In November he talked about adding more items to the calendar view by adding MaxvisibleEvents to the Rendering Template for the Calendar. I decided to take that concept a level further.

Following problem scenario:
We need to be able to colour code calendar entries, add more than just the title to the item and break down the multi day events into separate blocks spanning across the whole day and not just a thin bar at the top which is easily skipped. All this without changing the insides of SharePoint. And the solution could not be simpler!

First of all you will need to create your own WebPart for the calendar. Sound daunting? not at all! you can easily implement the SPCalendarView control to do all the work for you.
Gunnar Peipmann has a great post on how to create a global calendar from multiple sources using the SPCalendarView.

The SpCalendarView control can also accept new Templates. So you copy the Rendering Templates for the Calendar Control from the C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\CONTROLTEMPLATES \defaulttemplates.ascx into a new ascx file, rename them and add the fields you want to the Item views. Then hook them up programatically with the SPCalendarView control and render the new output.

WARNING! Don't put the custom Rendering Templates into a subfolder. Although it might make perfect sense, they won't load properly programatically. Just use clear and concise naming conventions for your custom ascx page. Then use the SPControlTemplateManager.GetTemplateByName() function to get hold of the ITemplate programatically and plonk it into the Calendar View.
If you insist on having the custom template in a subfolder, check out Reverse Alchemy's post on loading templates programatically. He will show you how to use Page.LoadControl() as a workaround to SharePoint misbehaving.

You will need to populate the list of events manually though. I.e. use a SPQuery to get the events in a collection, iterate through the collection and create new Calendar Entries based on the list item. But Gunnar's blog will guide you through that. While you're recreating the calendar entries try changing the Backgroundcss attribute of the entry. :-) and voilla you have a colour coded calendar that has all the functionality of the normal calendar.
Ok. Maybe it is not quite as easy. I'll upload a step by step instruction sometime after easter if enough people pester me about it...

Monday, April 6, 2009

Adding Export To Spreadsheet to a Picture Library

Sometimes customers want to have all the functionality of a Picture Library but also that of a Document Library. Specifically the option to have a Excel Report on a bunch of images. Now that sounds simple. Just Expor to Spreadsheet. Well guess what. Some clever dude took that action out of the menu. Why? No idea. Because it does not work? Bollocks. Of course it works. below is how you can get it back again. Simply add a Custom Action to your feature elements and deploy. Happy Exporting.the trick is in dynamically creating the iqy string.

<CustomAction Id="UserInterfaceCustomActions.DocLibActionsToolbar"
RegistrationType="List"
RegistrationId="109"
GroupId="ActionsMenu"
Location="Microsoft.SharePoint.StandardMenu"
Sequence="1000"
Title="Export To Spreadsheet"
ImageUrl="/_layouts/images/MenuSpreadsheet.gif">
<UrlAction
Url="javascript:EnsureSSImporter();javaScript:ExportList('{SiteUrl}\u002f_vti_bin\u002fowssvr.dll?CS=65001\u0026Using=_layouts\u002fquery.iqy\u0026List={ListId}\u0026RootFolder=' + ctx.listUrlDir + '\u0026CacheControl=1')" />
</CustomAction>

Tuesday, March 31, 2009

SharePoint training from the best

Steve Smith and Ben Curry are coming to the SharePoint Conference and will be holding a five day hard core SharePoint Workshop. This is not for the faint hearted! Learn from the best in an interactive and engaging session where it is all about hands on and hats off.

When? The week after the conference 06/07 until 11/07
How? send a mail to chan@knowledgecue.co.nz to express your interest
Where? TBA

Course outline and registration will be online soon. Watch this space!

Cool SharePoint Themes

Microsoft has published a whole set of new and funky sharepoint themes
you can download them here




For those of you who have been playing with the SPG, you will notice that the Contoso theme is part of the update package for the Training Management Solution.

Finally, if you wish a faster and more comfortable way of using your themes, install the WSP file that Daniel Brown created and activate the themes on Farm level.
Daniel was so kind to installl the themes and make features out of them, packaged it all into a wsp and added a readme for instructions.

These themes make life a lot easier to customise the look and feel of your sharepoint installation. Either use them out of the box or pick the one you like best and adjust it with a few tweaks to your needs.