Saturday, August 14, 2004

Modify Shared Page

Ok, just before I go off on holiday for a week, here is a quick post on something I've been using for a while.

If anyone out there has been wanting to edit the drop-down that decends when the "Modify Shared Page" box is clicked, here is one quick and easy method.

The structure and options of the menu are actually a small xml fragment embedded in the html source of each page. Simply by editing the xml you can edit the menu. Microsoft use this technique on many of their web sites.
Here is an example javascript function that will add the create link to the bottom of the drop-down.

function updateMenu()
{
//get a reference to the XML fragment
//team workspace menu
var oNode = document.getElementById('MSOMenu_SettingsMenu');
if(oNode==null){
//meeting workspace menu
oNode = document.getElementById('MtgMenu_SettingsMenu');
}
//check it exists
if(oNode!=null){
//append an additional node to the xml
oNode.innerHTML = oNode.innerHTML + '<ie:menuitem type="option" onmenuclick="javascript:window.location=\'_layouts/1033/create.aspx\';">Create</ie:menuitem>';
}
}

You can write any javascript functions you like, and have them executed by the onMenuClick property of the menuitem node.

If you want to get ambitious, you can define sub-sections, icons, in fact pretty much re-write the whole menu. Have a look at the xml fragment to understand it's structure and properties. If you have difficulty finding it, search on the text 'MtgMenu_SettingsMenu'.

Now, how do you run this javascript on the page? You can either create your own update.js file, and then edit every .aspx list and web part page template to include a reference to the js file. Or, add your function to the file ows.js as it is already referenced by every page.

Additionally, you have to ensure the updateMenu function does not execute before the xml fragment has been written out in the html. You can either:-


  • Use the onload event to fire the command. Alas, some sharepoint pages already use onload, and you risk damaging native functionality with this method.
  • Use setTimeout('updateMenu()',500); Here, you are dependant on the end user having downloaded the page completely within your specified time delay.
  • Edit each .aspx template and ensure the updateMenu() command is the last processing instruction on the page. Low risk, but a significant amount of work, and vunerable to Microsoft updates to SharePoint.


Considerations

  • In either method, you are changing pages that will potentially get over-written by a SharePoint patch or update from Microsoft. Bear this in mind when choosing in which files to place new javascript functions.
  • If you do declare a path similar to the one "_layouts/1033/create.aspx", be aware that that it will not always be valid with respect to the page the user is on, particulary in the case of web part pages. I believe I have a solution for this, but I haven't investigated it yet.
  • If you edit ows.js, it will effect every site on the server, you may need additional logic in the javascript to ensure additions are only made for certain sites, for example testing the domain name.

I'm sure others out there can think of ways to minimise the risks of running client-side javascript in this way, and perhaps increase the functionality of the updateMenu() command.

Saturday, August 07, 2004

Make more posts

A couple of weeks ago I dropped a comment on Maurice Prathers blog about using http compression on sharepoint. This is something I consider almost essential for any sharepoint site, regardless of your connection speed to the server.

It looks like he took it up, and and has written a great post on how to implement it. Which of course made me feel very lazy in not making an effort to post the info myself *note to self, post info*.

He has also published very detailed info on the resulting performance.

my only comment is that he may have set the compression level a bit too high..

UPDATE: Maurice has updated his article showing the performance benefits of using level 9 compression.

great post Maurice.