Tag Archives: MOSS 2007

SAS (SharePoint Accessibility Solution) – WCAG 2.0 AAA reusable framework for SharePoint

I am proud to finally announce the official release of SAS (SharePoint Accessibility Solution) by Content and Code.
 
The release of an accessible framework for SharePoint is a massive step for both SharePoint, Content and Code any organisations looking for an accessible SharePoint platform.
 
This framework was used (and developed) for the RNIB Website (which I posted about a few weeks back: RNIB – World’s first AAA website launched in SharePoint).

"Accessibility is mandatory for many organisations, allowing access to the web for all. Our SharePoint 2007 Accessibility Framework allows sites to be built rapidly without sacrificing SharePoint functionality."

– Tim Wallis, CEO, Content and Code

By all means check it out and tell me what you think 🙂

https://www.contentandcode.com/solutions/Pages/accessibility.aspx

Performance Optimisation in SharePoint

Performance has always been a bit of a black art in SharePoint, with so many core files being dropped onto landing pages it’s not uncommon to have a 500kb payload taking over 10 seconds to load.. of course for most corporate websites this is simply not good enough.
 
When building the RNIB website we spent a lot of time getting the page payload lower, and the caching model tweaked so that the pages were loading more responsively. We were mostly successful but there were plenty of challenges.
 
First off was the ScripResource files (used by Ajax). They were only really used for editing (the rich text editor we used from Telerik). Putting those references into a SharePoint "EditPanel" seemed to sort that one out (so the files were only ever being loaded if the page was in Edit Mode  .. which was never the case for anonymous users.
 
The caching profiles were also a big boon, enabling BLOB caching for the script files and static images, and also tuning the SharePoint site collection cache profiles so that they worked best for anonymous users.
 
We also used a bunch of other 3rd party tools, including the awesome Fiddler2 and YSlow for FireFox.
 
There has also been a very good article recently from the Microsoft SharePoint Team Blog describing how they went about optimising the sharepoint.microsoft.com website. Its a good read and brings up some lesser known optimisation techniques.
 
If you have any tips on performance optimisation I’d love to hear it.

RNIB – World’s first AAA website launched in SharePoint

It’s official, I am extremely proud to announce the launch of the world’s first ever AAA accessible SharePoint website…
 
RNIB – supporting blind and partially sighted people
 
I am the SharePoint Solution Architect on this project, and I am pleased to present the key features as:
 
The difference is that ALL functionality on this website is presented accessibly (including backend editing and administration!)
 
Feature Set:
  • Full WCAG 2.0 AAA XHTML rendering
  • Accessible feature-set
    • WYSIWYG Page editing and publishing
    • Full list item editing
    • Accessible Web Part editing {Add | Remove | Update properties}
    • Full list views and list editing (including document libraries, Check-in Check-out and content approval)
    • Site Administration (Permissions | Navigation | Basic site settings | features | Recycle Bin | View Site Content}
All of this is built on our unique and totally re-usable SharePoint Accessibility Solution (SAS).
 
If you would like to know more, or have any feedback then please get in touch!

Turning off Audience Targeting on Page Libraries – Operation is not valid due to the current state of the object

Well .. this took a while to crack.
 
"Operation is not valid due to the current state of the object"
 
Anyone who has seen this will know it’s a pain to track down. This particular one was even more painful that usual, because it was being thrown from the "Modify Audience Targeting" page of a Pages Library in MOSS 2007!
 
Do I did some rooting around and found a great post from Gary Lapointe (https://stsadm.blogspot.com/2008/08/enabling-audience-targeting-on-list.html) showing how to enable (or disable) audience targeting on a list through code.
 
However, there was a bug so it gave me the same error message!
The problem is that the field that we are trying to delete (Audience Targeting) is Sealed. So you need to set "Sealed=False" .. (I also set "AllowDeletion=True" as well to be on the safe side!)
 
The working code (modified from Gary Lapointe’s original code) is as follows:
 
public static void SetTargeting(SPList list, bool enabled) 
        {  
                if (list == null) 
                    throw new SPException("List was not found."); 
               
                SPField targetingField = GetTargetingField(list); 
                if (enabled && (targetingField == null)) 
                { 
                    string createFieldAsXml = CreateFieldAsXml();
                    list.Fields.AddFieldAsXml(createFieldAsXml); 
                    list.Update(); 
                } 
                else if (!enabled && (targetingField != null))
                {
                    // make sure the field can be deleted!
                    targetingField.AllowDeletion = true;
                    targetingField.Sealed = false;
                    targetingField.Update();
                    list.Fields.Delete(targetingField.InternalName);
                    list.Update();
                } 
        }
You can see the highlighted section that I added to Garys code.
 
Cheers!
 
Martin

The call to SearchServiceInstance.Provision failed … resolved!

This was a very annoying one. I had previously configured my development virtual machine to disable Search, Indexing, Document Conversion .. all those pesky services that sap RAM and CPU which aren’t always needed for development work.

The problem came when I wanted to turn them back on again. I was creating a new SSP and got the rather spurious error "no indexers".
This was a little odd, but I quickly realised that it meant the Index service was disabled. (annoying, because I only wanted an SSP for user profile development, but c’est la vie).

So I went to start the Windows SharePoint Services Search and *wham*… "Error"
I had a bit of a poke around the log files and found a reference to:

The call to SearchServiceInstance.Provision ("<name of server>") failed.

Well .. it took me a while to work this out but I did finally crack it. You see, I was doing this on a local virtual machine, so I rarely if ever use the full domain name. I found that I could only start the Search Service using the fully qualified "Domain\UserName" designation.
If you use just the "Username" then it didn’t work and you got the odd error above!

Very strange, another one for the archives I guess.

Resource files in SharePoint done properly ..

The message I really want to get across … Don’t use Properties/Resources.resx

 

SharePoint resource files should be stored in one of 2 places (there are other places, but they are not commonly used):

 

·         12

o   Config

§  Resources ß Location 1 – use this for all Pages, Controls and Web Parts

o   Resources ß Location 2 – use this for all Features, Site Definitions, List Definition, Content Types (i.e. all CAML)

 

If you need to access those resources from code, then use the following:

 

C# (programmatically)

String strValue = System.Web.HttpContext.GetGlobalResourceObject(“NameOfResourceFile”, “NameOfProperty”).ToString();

 

ASPX  Markup

<%$Resources: NameOfResourceFile, NameOfProperty%>

 

XML (CAML)

$Resources: NameOfResourceFile, NameOfProperty;

Adding FAVICONS to SharePoint

Ok .. I admit it .. this isn’t really just a SharePoint thing, it’s a "web" thing, but quite frankly I am astounded that this isn’t something provided out of the box.

So what are these favicon things anyway?

Favicons are the icons that appear in your web browser when you are surfing. They usually appear in the address bar (depending on your browser) and were originally created for older IE environments to help identify web sites in the Favourites folder (hence the name "favicon" = "favourites icon").

example favicons

Ok, thats great, so how do I get them in SharePoint?

Well, it’s really quite simple. Favicons are represented by small "link" tags in your HTML. In SharePoint the most sensible place to put them is in the Master Page. The reason for this is that (generally) your Master Page is rendered for pretty much every page .. therefore you don’t have to add favicon links all over the place.

All you need to do is put a "link" tag into your Master Page, within the "<head>" tags (i.e. it needs to be in the page header!)

<link rel="shortcut icon" href="/Portal Images/favicon.jpg" />

How to "SharePoint’ise" it!

I know, that’s not a real word, but the best approach you can take is to place your icon image (either an icon or image file) into an Image Library. You can then place a relative URL to a specific image in that image library, and it allows the content editors to upload a new favicon whenever they want 🙂 (with the same version control and content approval you would normally have).

Thats exactly what I did with the sample line of code above, with a file called "favicon.jpg" which is located in an Image Library called "Portal Images" at the top level of the site collection.

Now, if you want to get REALLY fancy, then you could change it to be relative to the Site Collection (so each site collection could potentially have a different favicon). Do you that, just follow my earlier post on creating "Site Collection Relative URLs in MOSS 2007".

Neat eh?

Quick Tip – Site Collection Relative URLs in MOSS 2007

This is a nice quick one…

 

If you try to use normal relative URL paths, then you may run into a spot of bother when trying to call a URL path that is relative to the Site Collection, especially when you have multiple Site Collections in your web application:

 

https://RootSite/sites/ThisSite/

 

How do you make an URL that is relative to the "ThisSite" site collection?

 

Well, you could hard-code the URL prefix, but that doesn’t really sit very well for most implementations, especially when using multiple-access mappings, you might have multiple URLs for the same site collection!

 

Alternatively, you can use the SPUrl function:

 

Code Sample:

This example code will take you to the Site Settings page for the current Site Collection.

 

<a runat="server" href="<% SPUrl:~SiteCollection\_layouts\settings.aspx %>">Go to Top Level Site Settings</a>

 

Note – You must use the runat="server" attribute, otherwise it will send the literal text of <% SPUrl …%> instead of the desired relative URL!

Also, you will need to add a reference to the Microsoft Publishing Assembly in the header tags; for that, see this blog

 

Publishing Header Tags

Thanks go to Hannah Scott (and her subsequent source) for this blog post.

 

<%@ Register Tagprefix="PublishingWebControls" Namespace="Microsoft.SharePoint.Publishing.WebControls" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="PublishingNavigation" Namespace="Microsoft.SharePoint.Publishing.Navigation" Assembly="Microsoft.SharePoint.Publishing, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register TagPrefix="PublishingVariations" TagName="VariationsLabelMenu" src="~/_controltemplates/VariationsLabelMenu.ascx" %>
<%@ Register Tagprefix="PublishingConsole" TagName="Console" src="~/_controltemplates/PublishingConsole.ascx" %>
<%@ Register TagPrefix="PublishingSiteAction" TagName="SiteActionMenu" src="~/_controltemplates/PublishingActionMenu.ascx" %>

How to handle document retention and expiry in MOSS 2007 – Disposition Workflow and Expiration Policy

This is rapidly becoming a hot topic in Records Management with SharePoint, as organisations put increasing amounts of information into their SharePoint environments serious thought needs to be put into how that information should expire and (more importantly) what happens when it expires.

SharePoint has several solutions to these issues which, if configured correctly, can help pave the way to successful document expiration management.

The Expiration Management Policy
Information Management Policies are a new framework introduced in MOSS 2007, and allow specific "policies" to be applied system wide using Content Types, or to individual document libraries and lists.

One of the most popular policies in information management is the Audit Policy (which is vastly superior to version history, as it can track who has viewed, downloaded or deleted a document, as well as who has made changes), but another equally important policy is the Expiration Policy.

The Expiration Policy effectively allows you to specify the retention period for content. This is generally calculated from the created or modified date, although you can specify any formula (i.e. calculated fields) based on any date/time column value.

When a document "expires" you can then select from a number of actions: delete the item, perform another custom action (extensible through development) or start a workflow, and it is the latter that we will focus on here.

As mentioned, you can develop additional "custom actions" for the expiry Information Policy, which you can deploy as a Feature (there is a good article here and also a forum post discussing the options for this).

The Disposition Approval Workflow
The disposition approval workflow is designed specifically for document expiry, and has been designed with a very simple user interface.

When started the workflow creates a task, which is linked to the document. The task presents the user with the options of deleting the item, or keeping it, and the ability to add some comments. Completing the task will perform the appropriate actions on the server.

This basically gives you "out of the box" capability to have items which expire and then get (optionally) deleted upon expiry.

..

Now, I put my developer hat on and delved behind the scenes.

The Disposition Approval Workflow consists of a custom Task Content Type which is used for the task, and an InfoPath form which is used for the task edit form (via Form Services).

This gives us 2 options for replacing / extending the Workflow.

1) Create our own custom content type for the tasks. This allows us to attach event handlers and perform any custom operations when the tasks are created / edited / completed.

2) Create a replacement InfoPath form and use that for the task completion, perhaps with additional options (such as "archive" ?).

Either way, the out of the box options are quite extensive, and the Workflow / Content Type structure gives enough extensibility to provide almost any functionality for document retention.