Oct
6
2008

How to use SharePoint Delegate Control to change the navigate URL of Manage Links (My Links)

Microsoft Office Online -

By using the My Links menu, you can easily add new links, reorganize your links, access sites where you are a member, and click links to save them to you My Links list.

You can use this feature when you have "My Site" setup and running in your SharePoint Shared Services.

James Tsai .NET SharePoint Blog - My Links Manage Links menu control

Problem

Let's say you have following two site collections setup for your SharePoint intranet site and My Site.

Intranet - http://intranet/

My Site - http://mysite/

When user is accessing manage links page by clicking on My Links, Manage Links menu on Intranet site, the menu control redirects user to

http://mysite/_layouts/MyQuickLinks.aspx

And you probably don't want this to happen, because of following reasons

  • You want to hide My Site from user, but you still want to use My Links feature.
  • You don't want user to navigate away from current site collection when they clicked on the Manage Links menu.
  • You want MyQuickLinks.aspx page to inherit and use current site theme.
  • You are experiencing the MOSS SP1 bug I described in last post.
  • OR you just want to customize it to navigate to the any URL

Goal

The goal here is obvious. To customize the navigate URL of Manage Links. In the example above, user should be redirected to

http://intranet/_layout/MyQuickLinks.aspx

Solution

You'll need following three things to achieve the goal

  • Customized version of MyLinksMenuControl class (MossSampleExtendedMyLinksMenuControl.cs)
  • SharePoint Delegate Control with control template (ExtendedMyLinks.ascx)
  • SharePoint feature to register Delegate Control

The solution structure

James Tsai .Net SharePoint Blog - My Links Delegate Control Solution Structure

SharePoint Delegate control plays the key role in this solution, it allows you to easily override OOTB Manage Links control with minimum coding and customization.

If you want to know more about SharePoint Delegate Control, you can go and read MSDN - Delegate Control

Step 1. Create a new class from MyLinksMenuControl

The OOTB My Links menu control is Microsoft.Office.Server.WebControls.MyLinksMenuControl. You'll have to create a new control which inherit from the OOTB one. And override the navigate URL of Manage Links with custom URL.

using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Portal.WebControls;

namespace MossSample
{
    public class MossSampleExtendedMyLinksMenuControl : MyLinksMenuControl
    {
        protected override ArrayList LoadMenuItems()
        {
            ArrayList ar = base.LoadMenuItems();

            MenuItemTemplate mtp = (MenuItemTemplate)(ar[ar.Count - 1]);

            mtp.ClientOnClickNavigateUrl = SPContext.Current.Site.Url + "/_layouts/MyQuickLinks.aspx";
            mtp.ClientOnClickScript = "window.location='" + SPContext.Current.Site.Url + "/_layouts/MyQuickLinks.aspx'";

            ar.RemoveAt(ar.Count - 1);
            ar.Add(mtp);

            return ar;
        }
    }
}

LoadMenuItems() method loads menu items when user clicked on My Link menu and it returns an ArrayList of menu items to its caller. Inside this method you can intercept original menu items and change their default properties.

MenuItemTemplate mtp = (MenuItemTemplate)(ar[ar.Count - 1]);

Because Manage Links is always last menu item in ArrayList, the code above creates a new MenuItemTemplate from original Manage Links MenuItemTemplate.

MenuItemTemplate has two properties for setting its navigate URL, ClientOnClickNavigateUrl and ClientOnClickScript.  Replace these two properties with any URL you want it to navigate to. In this example, we want it to display MyQuickLinks.aspx under same site collection.

SPContext.Current.Site.Url + "/_layouts/MyQuickLinks.aspx";

It means if user clicked on Manage Links from http://intranet/ , it navigates user to http://intranet/_layouts/MyQuickLinks.aspx.

After all above changes, you have to remove the original Manage Links menu item from menu items ArrayList loaded by base.LoadMenuItems(). And add the new one you just created to ArrayList and return this changed ArrayList.

ar.RemoveAt(ar.Count - 1);
ar.Add(mtp);

return ar;

Step 2. Create SharePoint Delegate Control Template

To use the control you created in Step 1. You have to create a new delegate control template to host this control. The OOTB one can be found in 12\TEMPLATE\CONTROLTEMPLATES\MyLinks.ascx

You can create a new .ascx file inside same or new directory and name it ExtendedMyLinks.ascx. In this example ExtendedMyLinks.ascx is created inside \CONTROLTEMPLATES\MossSample\.

Copy everything in MyLinks.ascx to ExtendedMyLinks.ascx.

Replace


<%@ Register Tagprefix="SPSWC" Namespace="Microsoft.SharePoint.Portal.WebControls" Assembly="Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>

with


<%@ Register Tagprefix="SPSWC" Namespace="YourControlClassNamespace" Assembly="YourControlClassAssemblyName, Version=<version>, Culture=neutral, PublicKeyToken=<keyToken>" %>

and replace


<SPSWC:MyLinksMenuControl id="MyLinksMenu" runat="server" />

with


<SPSWC:YourControlClassName id="MyLinksMenu" runat="server" />

In our example, the control class name is MossSampleExtendedMyLinksMenuControl and the name space is MossSample

The assembly info is "MossSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0bee755dfbe63ba5"

The final look ExtendedMyLinks.ascx is like this.


<%@ Control className="MyLinksUserControl" Language="C#" Inherits="Microsoft.SharePoint.Portal.WebControls.MyLinksUserControl&#44;Microsoft.SharePoint.Portal, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="OSRVWC" Namespace="Microsoft.Office.Server.WebControls" Assembly="Microsoft.Office.Server, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Register Tagprefix="SPSWC" Namespace="MossSample" Assembly="MossSample, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0bee755dfbe63ba5" %>
<%@ Register Tagprefix="SharePoint" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<table><tr>
<td class="ms-globallinks"><SPSWC:MossSampleExtendedMyLinksMenuControl id="MyLinksMenu" runat="server" /></td>
<td class="ms-globallinks"><asp:Literal id="hlMySiteSpacer" runat="server" /></td>
</tr></table>

Step 3. Create a SharePoint Feature to Register Delegate Control

You are a almost done. This last step is the most important step to get your control to override OOTB My Links control.

You need to create a SharePoint feature with following feature metadata

feature.xml


<?xml version="1.0" encoding="utf-8"?>

<Feature Id="{CF2BB280-D59B-45b9-8A0C-B7F19E42C6FE}"

        Title="Moss Sample Extened GlobalLink2"

        Description="Extended OOTB MyLinks Control from MySite Feature"

        Version="1.0.0.0"

        Hidden="FALSE"

        Scope="Site"

        xmlns="http://schemas.microsoft.com/sharepoint/"

        ImageUrl ="">

  <ElementManifests>

    <ElementManifest Location="elements.xml"/>

  </ElementManifests>

</Feature>

elements.xml


<Elements xmlns="http://schemas.microsoft.com/sharepoint/">

  <Control Id="GlobalSiteLink2" Sequence="99" Controlsrc="~/_controltemplates/mosssample/extendedmylinks.ascx"/>

</Elements>

It is very important to give this control with id GlobalSiteLinks2 and sequence less than 100. Because this is the same id used by OOTB MySite feature when it register the original My Links menu delegate control.

MSDN SharePoint DelegateControl class -

By declaring a control as an element in a Feature and giving it a priority through the Sequence attribute of the Control element, Windows SharePoint Services selects the declared control candidate and instantiates it as a child of the delegate control. At run time, this delegate control accepts the union of control elements declared at the server farm, Web application, site collection, and Web site levels. The control that has the lowest sequence number is added to the control tree through the DelegateControl

That means your new My Links delegate control will override the original one, because the sequence number of your control is 99 and original control sequence number is 100.

The OOTB control id and sequence number can be found in 12\TEMPLATE\FEATURES\MySite\MySiteFeatureElements.xml

Note: You can give your control the different ID. But if you do that, you also need to change master page's DelegateControl with the new control ID. The default.master has this DelegateControl declaration for My Links menu


<SharePoint:DelegateControl ControlId="GlobalSiteLink2"  runat="server"/></td>

Name it with "GlobalSIteLinks2" saves you the trouble of modify master page.

Now, install and activate the feautre.

you can now test the navigate URL of Mange Links by clicking on My Link menu on your site.

blog comments powered by Disqus