Integration Points

Extending Corporate Data …

#40 Taking Control of the Sharepoint 2010 Breadcrumb

leave a comment »

cf. Linking This BreadCrumb control to a SPList in Post #41

Working with the default breadcrumb in SP2010 I found the following issues: If you have site pages and want to navigate from one to the other you may want to show a hierarchy that does not physically exist in SP (i.e. pages all in site pages).  In addition, certain directories in the path used by SP may lead the user to nowhere useful. Below I have code for a user control that I have added to the v4.masterpage. It is deployed as a feature to ControlTemplates (C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\CONTROLTEMPLATES). In VS2010 add blank Sharepoint 2010 project and add new item: Usercontrol.

First the User Control.  This is based on an older project  http://www.codeproject.com/KB/aspnet/breadcrumbs.aspx. I use a simple switch statement to match URL and decide on how to present the node and target URL but hope to read a SPList or a SiteMap for a more manageable solution going forward.

The result of this is a breadcrumb looking like (& linked to) whatever you want. You can ignore a virtual directory, define the label & link or even define multiple ‘nodes’ on your breadcrumb for each directory in the path.

using System;
using System.Collections.Specialized;
using System.IO;
using System.Text;
using System.Web.UI;

namespace SPBreadCrumb.ControlTemplates.SPBreadCrumb
{
 public partial class Breadcrumb : UserControl
 {
 StringBuilder sbResult = new StringBuilder();                // Holds the Breadcrumb HTML.
 StringBuilder sbBcUrl = new StringBuilder();                // Holds the URL of the breadcrumb.
 // Dir are appended in succession to the root.
 private HybridDictionary labels = new HybridDictionary();    // Holds the "friendly" directory names.
 private bool ShowFileName = true;
 private string Separator = ">";
 private string RootUrl = @"/";
 private string RootName = "Home ";

 protected void Page_Load(object sender, EventArgs e)
 {

 // Create the root breadcrumb (corresponds to the root directory).
 //
 sbResult.Append("<a href=\"" + RootUrl + "\">" + RootName + "</a>");

 //
 // Get the site URL.  Use a StringBuilder to hold the URL so that we can append
 // directory names in succession.
 //
 string strHostUrl = "http://" + Page.Request.ServerVariables["HTTP_HOST"] + "/";
 sbBcUrl.Append(strHostUrl);

 //
 // Break up the path parts into an array (directory name(s) and/or file name).
 //
 string scriptName = Page.Request.ServerVariables["SCRIPT_NAME"];
 string strScriptDir = Path.GetDirectoryName(scriptName);
 bool bHasExtension = Path.HasExtension(scriptName);

 //
 // Create breadcrumb HTML for the directory name(s).
 // ***     Note: Remove the first "\"; otherwise, when you split the string, the first item in the
 //         array is an empty string.
 //
 strScriptDir = strScriptDir.Substring(1);
 string[] strDirs = strScriptDir.Split('\\');
 int nNumDirs = strDirs.Length;

 //
 // Splitting the string "\" (root directory) produces an array with an empty string as its only element.  If there is
 // only one element and it is the empty string, then we are in the root directory.  If the user has chosen
 // to display the file name, then the separator and the file name will be appended to the Web site root
 // Name/URL.
 //
 // If, however, there is one element and it is NOT the empty string, then we are one directory deep.
 // The else statement is executed and the separator character is inserted.
 //
 string strSeparator = "";
 if (1 == nNumDirs && (strDirs[0] == ""))
 {
 strSeparator = "";
 }
 else
 {
 strSeparator = String.Format(" {0} ", Separator);
 }

 // Node setup on Breadcrumb
 foreach (string strDirName in strDirs)
 {
 sbBcUrl.Append(strDirName + "/");  // URL SETUP
 // LABELD BC LINK SETUP
 sbResult.Append(buildLinkNode(sbBcUrl.ToString(), strDirName));
 }

 //
 // If the user wants to display file names, do it now.
 //
 if (false != ShowFileName)
 {
 sbResult.Append(String.Format(" {0} {1}", Separator, Path.GetFileName(scriptName)));
 }

 lblBC.Text = sbResult.ToString();
 }

 /// <summary>
 /// comes back with "> <a href='TranslatedURL'>NodeName</a>"
 /// </summary>
 /// <param name="URL"></param>
 /// <param name="DirName"></param>
 /// <returns></returns>
 private string buildLinkNode(string URL, string DirName)
 {

 string sReturn = "";

 // http://serverName/teamtest/SitePages/Home.aspx

 switch (URL.ToLower().Trim())
 {
case @"http://serverName/teamtest/sitepages/":
sReturn += setupDoubleNode(@"http://www.google.com", "Node A", @"http://www.cnn.com", "Node B");
 break;
 case @"http://localhost:49169/intranet30/":
 sReturn += setupSingleNode(@"http://www.bing.com", "Node (Intranet)");
 break;
 case @"http://serverName/teamtest/":
 sReturn += setupSingleNode(@"http://intranet", "Node (Root)");
 break;
 default:
 sReturn += setupSingleNode(@"http://intranet", "Node (" + URL.ToLower().Trim() + ")");
 break;
 }

 return (sReturn);
 }

 private string setupSingleNode(string URL, string LINK)
 {
 return (Separator + " <a href='" + URL + @"' > " + LINK + @"</a> ");
 }

 private string setupDoubleNode(string URL1, string LINK1, string URL2, string LINK2)
 {
 string s = Separator + " <a href='" + URL1 + @"' > " + LINK1 + @"</a> ";
 s += Separator + " <a href='" + URL2 + @"' > " + LINK2 + @"</a> ";
 return (s);
 }

 }
}


9/21/10 Note: By changing the visible=false attribute you can run into an odd error
You must specify a value for this required field” See this link for details for a css workaround.

The Masterpage requires a User Control reference, placement of the actual control and visible=’false’ on existing breadcrumbs.

<%@ Register TagPrefix="wssuc" TagName="Breadcrumb" src="~/_controltemplates/SPBreadcrumb/BWBreadcrumb.ascx" %>

Place the control in the banner – use SPD in split mode to navigate and turn off visibility on standard controls until you see what you like.

<td class="s4-titletext"><wssuc:BreadCrumb ID="Test1" runat="server" />
...
<SharePoint:SPLinkButton  Visible="false"  ...
<SharePoint:ClusteredDirectionalSeparatorArrow   Visible="false"  runat="server"/>

Advertisement

Written by dmgorman

July 21, 2010 at 3:48 pm

Posted in Sharepoint

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.