<?xml version="1.0" encoding="utf-8"?>
<rss xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:pingback="http://madskills.com/public/xml/rss/module/pingback/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0">
  <channel>
    <title>Rich Finn - Navigation</title>
    <link>http://blog.richfinn.net/blog/</link>
    <description>sharepointer</description>
    <language>en-us</language>
    <copyright>Rich Finn</copyright>
    <lastBuildDate>Wed, 15 Aug 2007 12:24:05 GMT</lastBuildDate>
    <generator>newtelligence dasBlog 2.3.9074.18820</generator>
    <managingEditor>blog.richfinn.net@gmail.com</managingEditor>
    <webMaster>blog.richfinn.net@gmail.com</webMaster>
    <item>
      <trackback:ping>http://blog.richfinn.net/blog/Trackback.aspx?guid=efa1ea9a-037f-4978-b827-cb7dd3e0ad1c</trackback:ping>
      <pingback:server>http://blog.richfinn.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://blog.richfinn.net/blog/PermaLink,guid,efa1ea9a-037f-4978-b827-cb7dd3e0ad1c.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://blog.richfinn.net/blog/CommentView,guid,efa1ea9a-037f-4978-b827-cb7dd3e0ad1c.aspx</wfw:comment>
      <wfw:commentRss>http://blog.richfinn.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=efa1ea9a-037f-4978-b827-cb7dd3e0ad1c</wfw:commentRss>
      <slash:comments>3</slash:comments>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
So, <a href="http://www.sharepointblogs.com/mossman">The Mossman</a> commented on
my <a href="http://blog.richfinn.net/blog/2007/08/14/CustomCMOSSNavigationUsingPortalSiteMapProvider.aspx">post
yesterday</a> saying that a little source around the PSMP would be nice, so
just for him, here it is.  I figured it would be good to build on <a href="http://www.telerik.com/products/sharepoint/integration-guide.aspx">Andrew
Connell's Telerik MOSS Integration Guide</a>, so this example shows how to create
your own top-level menu in a custom server-control using the <a href="http://www.telerik.com/products/aspnet/controls/menu/overview.aspx">Telerik
RadMenu</a> and the <a href="http://msdn2.microsoft.com/en-us/library/ms582344.aspx">PortalSiteMapProvider</a>. 
I know not everybody will have the license for the Telerik RadMenu, so if you don't,
hopefully you'll be able to take this example and pull out of it what
you need.
</p>
        <p>
Also, I posted this post on top of the one yesterday, whoops. 
There's a good lesson on locally saving your postings. Sorry if it's shown up new
a couple of times for some of you. Wish I could figure out why...
</p>
        <p>
This solution shows how you could add custom attributes on each RadMenuItem from SPField
values in the PublishingPage along with a custom client-side script event
handler. 
</p>
        <p>
          <a href="http://blog.richfinn.net/blog/downloads/RadMenu_PSMP_Source.txt" target="_blank">Download
the source for the complete control</a> in a text file, if you'd like it.
</p>
        <p>
The menu created will look like the following and will pop a JavaScript alert with
the relevant PublishingPage and SPWeb GUIDs when clicked:<br /><br />
 <a href="http://blog.richfinn.net/blog/content/binary/WindowsLiveWriter/SampleCodeforCustomCMOSSNavigationUsingP_8BCC/PSMP_Menu.jpg" atomicselection="true"><img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height="117" alt="PSMP_Menu" src="http://blog.richfinn.net/blog/content/binary/WindowsLiveWriter/SampleCodeforCustomCMOSSNavigationUsingP_8BCC/PSMP_Menu_thumb.jpg" width="366" border="0" /></a></p>
        <div style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; HEIGHT: 750px; BACKGROUND-COLOR: #f4f4f4">
          <pre style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none">
            <p>
              <span style="COLOR: #0000ff">protected</span>
              <span style="COLOR: #0000ff">override</span>
              <span style="COLOR: #0000ff">void</span> CreateChildControls()
{ <span style="COLOR: #008000">//Get the root publishingweb web for the site</span> PublishingWeb
rootWeb = PublishingWeb.GetPublishingWeb(SPContext.Current.Site.RootWeb); <span style="COLOR: #008000">//Get
the URL of the default page in the web</span><span style="COLOR: #0000ff">string</span> defaultPageUrl
= rootWeb.DefaultPage.ServerRelativeUrl; <span style="COLOR: #008000">//find the item
in the PSMP</span> PortalListItemSiteMapNode smnHome = (PortalListItemSiteMapNode)PortalSiteMapProvider.
</p>
            <p>
CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(defaultPageUrl); <span style="COLOR: #008000">//initialize
the RadMenu</span> RadMenu menu = <span style="COLOR: #0000ff">new</span> RadMenu();
menu.ID = <span style="COLOR: #006080">"MainMenu"</span>; menu.RadControlsDir = <span style="COLOR: #006080">"/_wpresources/RadMenu.Net2/4.3.2.0__bbe59a8ad3533e68/RadControls"</span>;
menu.Skin = <span style="COLOR: #006080">"Outlook"</span>; <span style="COLOR: #008000">//Set
the client-side clicked event handler</span> menu.OnClientItemClicked = <span style="COLOR: #006080">"MainMenu_RadMenuItemClicked"</span>; <span style="COLOR: #008000">//create
the first menu item for the default (home) page</span> RadMenuItem rmiHome = createMenuItem(smnHome);
menu.Items.Add(rmiHome); <span style="COLOR: #008000">//iterate through each one of
the pages and subsites and create menu items for them</span><span style="COLOR: #0000ff">foreach</span> (SiteMapNode
smnTopLevelItem <span style="COLOR: #0000ff">in</span> smnHome.ParentNode.ChildNodes)
{ RadMenuItem rmiTopLevelItem = createMenuItem(smnTopLevelItem); <span style="COLOR: #008000">//if
the current sitemap has children, create a submenu for it</span><span style="COLOR: #0000ff">if</span> (smnTopLevelItem.HasChildNodes)
{ <span style="COLOR: #0000ff">foreach</span> (SiteMapNode smnChildItem <span style="COLOR: #0000ff">in</span> smnTopLevelItem.ChildNodes)
{ RadMenuItem rmiChildItem = createMenuItem(smnChildItem); rmiTopLevelItem.Items.Add(rmiChildItem);
} } menu.Items.Add(rmiTopLevelItem); } <span style="COLOR: #0000ff">this</span>.Controls.Add(menu); <span style="COLOR: #008000">//create
the client-side script for the RadMenuItemClicked event handler</span> StringBuilder
sbScript = <span style="COLOR: #0000ff">new</span> StringBuilder(); sbScript.Append(Environment.NewLine
+ <span style="COLOR: #006080">"&lt;script language=\"javascript\"&gt;"</span>); sbScript.Append(Environment.NewLine
+ <span style="COLOR: #006080">"function MainMenu_RadMenuItemClicked(sender, eventArgs)"</span>);
sbScript.Append(Environment.NewLine + <span style="COLOR: #006080">"{"</span>); sbScript.Append(Environment.NewLine
+ <span style="COLOR: #006080">"var pageGuid = eventArgs.Item.GetAttribute(\"PageGuid\");"</span>);
sbScript.Append(Environment.NewLine + <span style="COLOR: #006080">"var webGuid =
eventArgs.Item.GetAttribute(\"WebGuid\");"</span>); sbScript.Append(Environment.NewLine
+ <span style="COLOR: #006080">"alert(\"WebGuid:\" + webGuid + \" PageGuid:\" + pageGuid);"</span>);
sbScript.Append(Environment.NewLine + <span style="COLOR: #006080">"}"</span>); sbScript.Append(Environment.NewLine
+ <span style="COLOR: #006080">"&lt;/script&gt;"</span>); <span style="COLOR: #0000ff">this</span>.Page.ClientScript.RegisterStartupScript(<span style="COLOR: #0000ff">typeof</span>(<span style="COLOR: #0000ff">string</span>), <span style="COLOR: #006080">"RadMenu_MainMenu_RadMenuItemClicked"</span>,
sbScript.ToString()); } <span style="COLOR: #008000">/// &lt;summary&gt;</span><span style="COLOR: #008000">///
Create a RadMenuItem from a SiteMapNode</span><span style="COLOR: #008000">/// &lt;/summary&gt;</span><span style="COLOR: #008000">///
&lt;param name="siteMapNode"&gt;SiteMapNode used to create RadMenuItem &lt;/param&gt;</span><span style="COLOR: #008000">///
&lt;returns&gt;RadMenuItem&lt;/returns&gt;</span><span style="COLOR: #0000ff">private</span> RadMenuItem
createMenuItem(SiteMapNode siteMapNode) { RadMenuItem menuItem = <span style="COLOR: #0000ff">new</span> RadMenuItem();
menuItem.NavigateUrl = siteMapNode.Url; menuItem.Text = siteMapNode.Title; SPListItem
listItem = <span style="COLOR: #0000ff">null</span>; <span style="COLOR: #008000">//if
the SiteMapNode is the default page, it will be a PortalWebSiteMapNode</span><span style="COLOR: #0000ff">if</span> (siteMapNode <span style="COLOR: #0000ff">is</span> PortalWebSiteMapNode)
listItem = getListItemFromPortalSiteMapNode((PortalWebSiteMapNode)siteMapNode); <span style="COLOR: #0000ff">if</span> (siteMapNode <span style="COLOR: #0000ff">is</span> PortalListItemSiteMapNode)
listItem = getListItemFromPortalSiteMapNode((PortalListItemSiteMapNode)siteMapNode); <span style="COLOR: #008000">//create
the custom attributes on the list item</span><span style="COLOR: #0000ff">if</span> (listItem
!= <span style="COLOR: #0000ff">null</span>) { menuItem.Attributes.Add(<span style="COLOR: #006080">"PageGuid"</span>,
listItem.UniqueId.ToString(<span style="COLOR: #006080">"N"</span>)); menuItem.Attributes.Add(<span style="COLOR: #006080">"WebGuid"</span>,
listItem.Web.ID.ToString(<span style="COLOR: #006080">"N"</span>)); menuItem.ToolTip
= listItem.Fields[<span style="COLOR: #006080">"MenuItemToolTip"</span>].GetFieldValueAsText(listItem[<span style="COLOR: #006080">"MenuItemToolTip"</span>]);
} <span style="COLOR: #0000ff">else</span> { menuItem.Attributes.Add(<span style="COLOR: #006080">"PageGuid"</span>, <span style="COLOR: #0000ff">string</span>.Empty);
menuItem.Attributes.Add(<span style="COLOR: #006080">"WebGuid"</span>, <span style="COLOR: #0000ff">string</span>.Empty);
menuItem.ToolTip = siteMapNode.Title; } <span style="COLOR: #0000ff">return</span> menuItem;
} <span style="COLOR: #0000ff">private</span> SPListItem getListItemFromPortalSiteMapNode(PortalListItemSiteMapNode
siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb
pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = pubWeb.PagesList.Items[siteMapNode.UniqueId]; <span style="COLOR: #0000ff">return</span> pageItem;
} <span style="COLOR: #0000ff">private</span> SPListItem getListItemFromPortalSiteMapNode(PortalWebSiteMapNode
siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb
pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = <span style="COLOR: #0000ff">null</span>; <span style="COLOR: #0000ff">if</span>(pubWeb.DefaultPage
!= <span style="COLOR: #0000ff">null</span>) pageItem = pubWeb.PagesList.Items[pubWeb.DefaultPage.Item.UniqueId]; <span style="COLOR: #0000ff">return</span> pageItem;
}
</p>
          </pre>
        </div>
        <img width="0" height="0" src="http://blog.richfinn.net/blog/aggbug.ashx?id=efa1ea9a-037f-4978-b827-cb7dd3e0ad1c" />
      </body>
      <title>Sample Code for Custom C# MOSS Navigation Using PortalSiteMapProvider</title>
      <guid isPermaLink="false">http://blog.richfinn.net/blog/PermaLink,guid,efa1ea9a-037f-4978-b827-cb7dd3e0ad1c.aspx</guid>
      <link>http://blog.richfinn.net/blog/2007/08/15/SampleCodeForCustomCMOSSNavigationUsingPortalSiteMapProvider.aspx</link>
      <pubDate>Wed, 15 Aug 2007 12:24:05 GMT</pubDate>
      <description>&lt;p&gt;
So, &lt;a href="http://www.sharepointblogs.com/mossman"&gt;The Mossman&lt;/a&gt; commented on
my &lt;a href="http://blog.richfinn.net/blog/2007/08/14/CustomCMOSSNavigationUsingPortalSiteMapProvider.aspx"&gt;post
yesterday&lt;/a&gt; saying&amp;nbsp;that a little source around the PSMP would be nice,&amp;nbsp;so
just for him,&amp;nbsp;here it is.&amp;nbsp; I figured it would be good to build on &lt;a href="http://www.telerik.com/products/sharepoint/integration-guide.aspx"&gt;Andrew
Connell's Telerik MOSS Integration Guide&lt;/a&gt;, so this example&amp;nbsp;shows how to create
your own top-level menu in a custom server-control&amp;nbsp;using the &lt;a href="http://www.telerik.com/products/aspnet/controls/menu/overview.aspx"&gt;Telerik
RadMenu&lt;/a&gt; and the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms582344.aspx"&gt;PortalSiteMapProvider&lt;/a&gt;.&amp;nbsp;
I know not everybody will have the license for the Telerik RadMenu, so if you don't,
hopefully&amp;nbsp;you'll be able to&amp;nbsp;take this example and pull out&amp;nbsp;of it what
you need.
&lt;/p&gt;
&lt;p&gt;
Also, I&amp;nbsp;posted this post on top of the one&amp;nbsp;yesterday,&amp;nbsp;whoops.&amp;nbsp;
There's a good lesson on locally saving your postings. Sorry if it's shown up new
a couple of times for some of you. Wish I could figure out why...
&lt;/p&gt;
&lt;p&gt;
This solution shows how you could add custom attributes on each RadMenuItem from&amp;nbsp;SPField
values&amp;nbsp;in the PublishingPage&amp;nbsp;along with a custom client-side script event
handler. 
&lt;/p&gt;
&lt;p&gt;
&lt;a href="http://blog.richfinn.net/blog/downloads/RadMenu_PSMP_Source.txt" target=_blank&gt;Download
the source for the complete control&lt;/a&gt; in a text file, if you'd like it.
&lt;/p&gt;
&lt;p&gt;
The menu created will look like the following and will pop a JavaScript alert with
the relevant PublishingPage and SPWeb GUIDs when clicked:&lt;br&gt;
&lt;br&gt;
&amp;nbsp;&lt;a href="http://blog.richfinn.net/blog/content/binary/WindowsLiveWriter/SampleCodeforCustomCMOSSNavigationUsingP_8BCC/PSMP_Menu.jpg" atomicselection="true"&gt;&lt;img style="BORDER-TOP-WIDTH: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; BORDER-RIGHT-WIDTH: 0px" height=117 alt=PSMP_Menu src="http://blog.richfinn.net/blog/content/binary/WindowsLiveWriter/SampleCodeforCustomCMOSSNavigationUsingP_8BCC/PSMP_Menu_thumb.jpg" width=366 border=0&gt;&lt;/a&gt; 
&lt;/p&gt;
&lt;div style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; HEIGHT: 750px; BACKGROUND-COLOR: #f4f4f4"&gt;&lt;pre style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;
&lt;p&gt;
&lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;override&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;void&lt;/span&gt; CreateChildControls()
{ &lt;span style="COLOR: #008000"&gt;//Get the root publishingweb web for the site&lt;/span&gt; PublishingWeb
rootWeb = PublishingWeb.GetPublishingWeb(SPContext.Current.Site.RootWeb); &lt;span style="COLOR: #008000"&gt;//Get
the URL of the default page in the web&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; defaultPageUrl
= rootWeb.DefaultPage.ServerRelativeUrl; &lt;span style="COLOR: #008000"&gt;//find the item
in the PSMP&lt;/span&gt; PortalListItemSiteMapNode smnHome = (PortalListItemSiteMapNode)PortalSiteMapProvider.
&lt;/p&gt;
&lt;p&gt;
CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(defaultPageUrl); &lt;span style="COLOR: #008000"&gt;//initialize
the RadMenu&lt;/span&gt; RadMenu menu = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; RadMenu();
menu.ID = &lt;span style="COLOR: #006080"&gt;"MainMenu"&lt;/span&gt;; menu.RadControlsDir = &lt;span style="COLOR: #006080"&gt;"/_wpresources/RadMenu.Net2/4.3.2.0__bbe59a8ad3533e68/RadControls"&lt;/span&gt;;
menu.Skin = &lt;span style="COLOR: #006080"&gt;"Outlook"&lt;/span&gt;; &lt;span style="COLOR: #008000"&gt;//Set
the client-side clicked event handler&lt;/span&gt; menu.OnClientItemClicked = &lt;span style="COLOR: #006080"&gt;"MainMenu_RadMenuItemClicked"&lt;/span&gt;; &lt;span style="COLOR: #008000"&gt;//create
the first menu item for the default (home) page&lt;/span&gt; RadMenuItem rmiHome = createMenuItem(smnHome);
menu.Items.Add(rmiHome); &lt;span style="COLOR: #008000"&gt;//iterate through each one of
the pages and subsites and create menu items for them&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;foreach&lt;/span&gt; (SiteMapNode
smnTopLevelItem &lt;span style="COLOR: #0000ff"&gt;in&lt;/span&gt; smnHome.ParentNode.ChildNodes)
{ RadMenuItem rmiTopLevelItem = createMenuItem(smnTopLevelItem); &lt;span style="COLOR: #008000"&gt;//if
the current sitemap has children, create a submenu for it&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; (smnTopLevelItem.HasChildNodes)
{ &lt;span style="COLOR: #0000ff"&gt;foreach&lt;/span&gt; (SiteMapNode smnChildItem &lt;span style="COLOR: #0000ff"&gt;in&lt;/span&gt; smnTopLevelItem.ChildNodes)
{ RadMenuItem rmiChildItem = createMenuItem(smnChildItem); rmiTopLevelItem.Items.Add(rmiChildItem);
} } menu.Items.Add(rmiTopLevelItem); } &lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;.Controls.Add(menu); &lt;span style="COLOR: #008000"&gt;//create
the client-side script for the RadMenuItemClicked event handler&lt;/span&gt; StringBuilder
sbScript = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; StringBuilder(); sbScript.Append(Environment.NewLine
+ &lt;span style="COLOR: #006080"&gt;"&amp;lt;script language=\"javascript\"&amp;gt;"&lt;/span&gt;); sbScript.Append(Environment.NewLine
+ &lt;span style="COLOR: #006080"&gt;"function MainMenu_RadMenuItemClicked(sender, eventArgs)"&lt;/span&gt;);
sbScript.Append(Environment.NewLine + &lt;span style="COLOR: #006080"&gt;"{"&lt;/span&gt;); sbScript.Append(Environment.NewLine
+ &lt;span style="COLOR: #006080"&gt;"var pageGuid = eventArgs.Item.GetAttribute(\"PageGuid\");"&lt;/span&gt;);
sbScript.Append(Environment.NewLine + &lt;span style="COLOR: #006080"&gt;"var webGuid =
eventArgs.Item.GetAttribute(\"WebGuid\");"&lt;/span&gt;); sbScript.Append(Environment.NewLine
+ &lt;span style="COLOR: #006080"&gt;"alert(\"WebGuid:\" + webGuid + \" PageGuid:\" + pageGuid);"&lt;/span&gt;);
sbScript.Append(Environment.NewLine + &lt;span style="COLOR: #006080"&gt;"}"&lt;/span&gt;); sbScript.Append(Environment.NewLine
+ &lt;span style="COLOR: #006080"&gt;"&amp;lt;/script&amp;gt;"&lt;/span&gt;); &lt;span style="COLOR: #0000ff"&gt;this&lt;/span&gt;.Page.ClientScript.RegisterStartupScript(&lt;span style="COLOR: #0000ff"&gt;typeof&lt;/span&gt;(&lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;), &lt;span style="COLOR: #006080"&gt;"RadMenu_MainMenu_RadMenuItemClicked"&lt;/span&gt;,
sbScript.ToString()); } &lt;span style="COLOR: #008000"&gt;/// &amp;lt;summary&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;///
Create a RadMenuItem from a SiteMapNode&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;///
&amp;lt;param name="siteMapNode"&amp;gt;SiteMapNode used to create RadMenuItem &amp;lt;/param&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #008000"&gt;///
&amp;lt;returns&amp;gt;RadMenuItem&amp;lt;/returns&amp;gt;&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; RadMenuItem
createMenuItem(SiteMapNode siteMapNode) { RadMenuItem menuItem = &lt;span style="COLOR: #0000ff"&gt;new&lt;/span&gt; RadMenuItem();
menuItem.NavigateUrl = siteMapNode.Url; menuItem.Text = siteMapNode.Title; SPListItem
listItem = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="COLOR: #008000"&gt;//if
the SiteMapNode is the default page, it will be a PortalWebSiteMapNode&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; (siteMapNode &lt;span style="COLOR: #0000ff"&gt;is&lt;/span&gt; PortalWebSiteMapNode)
listItem = getListItemFromPortalSiteMapNode((PortalWebSiteMapNode)siteMapNode); &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; (siteMapNode &lt;span style="COLOR: #0000ff"&gt;is&lt;/span&gt; PortalListItemSiteMapNode)
listItem = getListItemFromPortalSiteMapNode((PortalListItemSiteMapNode)siteMapNode); &lt;span style="COLOR: #008000"&gt;//create
the custom attributes on the list item&lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt; (listItem
!= &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;) { menuItem.Attributes.Add(&lt;span style="COLOR: #006080"&gt;"PageGuid"&lt;/span&gt;,
listItem.UniqueId.ToString(&lt;span style="COLOR: #006080"&gt;"N"&lt;/span&gt;)); menuItem.Attributes.Add(&lt;span style="COLOR: #006080"&gt;"WebGuid"&lt;/span&gt;,
listItem.Web.ID.ToString(&lt;span style="COLOR: #006080"&gt;"N"&lt;/span&gt;)); menuItem.ToolTip
= listItem.Fields[&lt;span style="COLOR: #006080"&gt;"MenuItemToolTip"&lt;/span&gt;].GetFieldValueAsText(listItem[&lt;span style="COLOR: #006080"&gt;"MenuItemToolTip"&lt;/span&gt;]);
} &lt;span style="COLOR: #0000ff"&gt;else&lt;/span&gt; { menuItem.Attributes.Add(&lt;span style="COLOR: #006080"&gt;"PageGuid"&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;.Empty);
menuItem.Attributes.Add(&lt;span style="COLOR: #006080"&gt;"WebGuid"&lt;/span&gt;, &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt;.Empty);
menuItem.ToolTip = siteMapNode.Title; } &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; menuItem;
} &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; SPListItem getListItemFromPortalSiteMapNode(PortalListItemSiteMapNode
siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb
pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = pubWeb.PagesList.Items[siteMapNode.UniqueId]; &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; pageItem;
} &lt;span style="COLOR: #0000ff"&gt;private&lt;/span&gt; SPListItem getListItemFromPortalSiteMapNode(PortalWebSiteMapNode
siteMapNode) { SPWeb web = SPContext.Current.Site.AllWebs[siteMapNode.WebId]; PublishingWeb
pubWeb = PublishingWeb.GetPublishingWeb(web); SPListItem pageItem = &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;; &lt;span style="COLOR: #0000ff"&gt;if&lt;/span&gt;(pubWeb.DefaultPage
!= &lt;span style="COLOR: #0000ff"&gt;null&lt;/span&gt;) pageItem = pubWeb.PagesList.Items[pubWeb.DefaultPage.Item.UniqueId]; &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; pageItem;
}
&lt;/p&gt;
&lt;/pre&gt;
&lt;/div&gt;
&lt;img width="0" height="0" src="http://blog.richfinn.net/blog/aggbug.ashx?id=efa1ea9a-037f-4978-b827-cb7dd3e0ad1c" /&gt;</description>
      <comments>http://blog.richfinn.net/blog/CommentView,guid,efa1ea9a-037f-4978-b827-cb7dd3e0ad1c.aspx</comments>
      <category>Microsoft Office SharePoint Server</category>
      <category>Navigation</category>
      <category>Telerik</category>
    </item>
    <item>
      <trackback:ping>http://blog.richfinn.net/blog/Trackback.aspx?guid=f969269a-751e-47b9-bb6e-6bb95cc19908</trackback:ping>
      <pingback:server>http://blog.richfinn.net/blog/pingback.aspx</pingback:server>
      <pingback:target>http://blog.richfinn.net/blog/PermaLink,guid,f969269a-751e-47b9-bb6e-6bb95cc19908.aspx</pingback:target>
      <dc:creator />
      <wfw:comment>http://blog.richfinn.net/blog/CommentView,guid,f969269a-751e-47b9-bb6e-6bb95cc19908.aspx</wfw:comment>
      <wfw:commentRss>http://blog.richfinn.net/blog/SyndicationService.asmx/GetEntryCommentsRss?guid=f969269a-751e-47b9-bb6e-6bb95cc19908</wfw:commentRss>
      <body xmlns="http://www.w3.org/1999/xhtml">
        <p>
I was talking to a client who was having difficulty developing a navigation control
using the methods described in most of the documentation out there, which explains
creating a custom Site Map Provider which inherits from the <a href="http://msdn2.microsoft.com/en-us/library/ms582344.aspx">PortalSiteMapProvider</a> (PSMP)object. 
There was just no way they were going to get exactly what they were looking for in
relation to what their high-priced 3rd-party designer delivered. 
</p>
        <p>
 
</p>
        <p>
After taking some time to do some exploration, and being a big proponent of web server
controls in the MOSS context, I knew this was the way they needed to go.  I found
a great post by Chris Richard on the MS ECM Team Blog that explained <a href="http://blogs.msdn.com/ecm/archive/2007/05/23/increased-performance-for-moss-apps-using-the-portalsitemapprovider.aspx">how
the PortalSiteMapProvider deals with performance issues</a> found often in costly
navigation rendering routines.  This post also explained how to use the PSMP
object in custom code - something that caught my eye. 
</p>
        <p>
There are a few instances of the PSMP that are defined in the MOSS web.config that
can be accessed through the PSM object:<br /><a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.combinednavsitemapprovider.aspx">PortalSiteMapProvider.CombinedNavSiteMapProvider</a>:
attached to the global or top nav menus<br /><a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.currentnavsitemapprovider.aspx">PortalSiteMapProvider.CurrentNavSiteMapProvider</a>:
attached to the current, or "Quick Launch" nav menu<br /><a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.currentnavsitemapprovidernoencode.aspx">PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode</a>:
attached to the breadcrumb nav<br /><a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.globalnavsitemapprovider.aspx">PortalSiteMapProvider.GlobalNavSiteMapProvider</a>:
Get the map for the global nav<br /><a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.websitemapprovider.aspx">PortalSiteMapProvider.WebSiteMapProvider</a>:
enumerates Web sites (SPWebs) in the site collection 
</p>
        <p>
Essentially, all of these object are set with the current SPContext, so they are already
security-trimmed and ready to use as-is for the user currently browsing the site. 
The special one for me here is the CurrentNavSiteMapProviderNoEncode, which includes
the pages, not just the webs. There is a limitation which Chris mentions in that this
provider doesn't return the default page in a web, rather just a reference to the
web itself, but that's ok - he explains a workaround to this if you're interested... 
</p>
        <p>
Essentially, my client's problem is that they have a left-side tree navigation, kind
of.  There's some interesting display logic that, like I said earlier, just doesn't
work with the out-of-box implementation. Without going into what they really
needed to accomplish, I figure it would be good to explain how to use the object to
answer some of the common questions in a custom navigation scenario. 
</p>
        <p>
1) Where Am I Now?<br />
2) Where's That Page? 
</p>
        <p>
        </p>
        <p>
Luckily, the CurrentNavSiteMapProviderNoEncode has a method that makes finding stuff
pretty easy.  <i>FindSiteMapNode()</i>. This method has three overloads,
all which return a <a href="http://msdn2.microsoft.com/en-us/library/system.web.sitemapnode.aspx">SiteMapNode</a> object. 
</p>
        <p>
The first overload takes an HttpContext as a parameter and is great for finding
where you're at now.  The second overload takes a URL and can be used for
finding any SiteMapNode given the URL provided.  The third takes both a
URL and an SPWeb object as context. 
</p>
        <p>
Here's some examples on how you use this along with the Publishing object model: 
</p>
        <p>
        </p>
        <div style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4">
          <pre style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none">
            <span style="COLOR: #008000">//In
a server control, find the SiteMapNode for the current HttpContext </span> SiteMapNode
siteNode = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(Context); <span style="COLOR: #008000">///
&lt;summary&gt; </span><span style="COLOR: #008000">/// Find SiteMapNode for PublishingWeb
object </span><span style="COLOR: #008000">/// &lt;/summary&gt; </span><span style="COLOR: #008000">///
&lt;param name="web"&gt;PublishingWeb object to retrieve in PortalSiteMapProvider&lt;/param&gt; </span><span style="COLOR: #008000">///
&lt;returns&gt;SiteMapNode object representing given PublishingWeb object&lt;/returns&gt; </span><span style="COLOR: #0000ff">protected</span> SiteMapNode
GetSiteNodeForPubWeb(PublishingWeb web) { <span style="COLOR: #0000ff">string</span> url
= web.Url + <span style="COLOR: #006080">"/"</span> + web.DefaultPage.Url; SiteMapNode
siteNode = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(url); <span style="COLOR: #0000ff">return</span> siteNode;
} </pre>
        </div>
        <p>
 
</p>
        <p>
The <a href="http://msdn2.microsoft.com/en-us/library/system.web.sitemapnode.aspx">SiteMapNode</a> object
contains everything needed to walk around in the hierarchy of the PSMP, and should
allow you conquer any custom display logic any tricky designer can throw at you...
</p>
        <p>
Update: I added a follow-up post to this one with some <a class="TitleLinkStyle" href="http://blog.richfinn.net/blog/2007/08/15/SampleCodeForCustomCMOSSNavigationUsingPortalSiteMapProvider.aspx" rel="bookmark">Sample
Code for a Custom C# MOSS Navigation Using PortalSiteMapProvider</a></p>
        <img width="0" height="0" src="http://blog.richfinn.net/blog/aggbug.ashx?id=f969269a-751e-47b9-bb6e-6bb95cc19908" />
      </body>
      <title>Custom C# MOSS Navigation Using PortalSiteMapProvider</title>
      <guid isPermaLink="false">http://blog.richfinn.net/blog/PermaLink,guid,f969269a-751e-47b9-bb6e-6bb95cc19908.aspx</guid>
      <link>http://blog.richfinn.net/blog/2007/08/14/CustomCMOSSNavigationUsingPortalSiteMapProvider.aspx</link>
      <pubDate>Tue, 14 Aug 2007 19:47:48 GMT</pubDate>
      <description>&lt;p&gt;
I was talking to a client who was having difficulty developing a navigation control
using the methods described in most of the documentation out there, which explains
creating a custom Site Map Provider which inherits from the &lt;a href="http://msdn2.microsoft.com/en-us/library/ms582344.aspx"&gt;PortalSiteMapProvider&lt;/a&gt; (PSMP)object.&amp;nbsp;
There was just no way they were going to get exactly what they were looking for in
relation to what their high-priced&amp;nbsp;3rd-party designer delivered. 
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
After taking some time to do some exploration, and being a big proponent of web server
controls in the MOSS context, I knew this was the way they needed to go.&amp;nbsp; I found
a great post by Chris Richard on the MS ECM Team Blog that explained &lt;a href="http://blogs.msdn.com/ecm/archive/2007/05/23/increased-performance-for-moss-apps-using-the-portalsitemapprovider.aspx"&gt;how
the PortalSiteMapProvider deals with performance issues&lt;/a&gt; found often in costly
navigation rendering routines.&amp;nbsp; This post also explained how to use the PSMP
object in custom code - something that caught my eye. 
&lt;/p&gt;
&lt;p&gt;
There are a few instances of the PSMP that are defined in the MOSS web.config that
can be accessed through the PSM object:&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.combinednavsitemapprovider.aspx"&gt;PortalSiteMapProvider.CombinedNavSiteMapProvider&lt;/a&gt;:
attached to the global or top nav menus&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.currentnavsitemapprovider.aspx"&gt;PortalSiteMapProvider.CurrentNavSiteMapProvider&lt;/a&gt;:
attached to the current, or "Quick Launch" nav menu&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.currentnavsitemapprovidernoencode.aspx"&gt;PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode&lt;/a&gt;:
attached to the breadcrumb nav&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.globalnavsitemapprovider.aspx"&gt;PortalSiteMapProvider.GlobalNavSiteMapProvider&lt;/a&gt;:
Get the map for the global nav&lt;br&gt;
&lt;a href="http://msdn2.microsoft.com/en-us/library/microsoft.sharepoint.publishing.navigation.portalsitemapprovider.websitemapprovider.aspx"&gt;PortalSiteMapProvider.WebSiteMapProvider&lt;/a&gt;:
enumerates Web sites (SPWebs) in the site collection 
&lt;/p&gt;
&lt;p&gt;
Essentially, all of these object are set with the current SPContext, so they are already
security-trimmed and ready to use as-is for the user currently browsing the site.&amp;nbsp;
The special one for me here is the CurrentNavSiteMapProviderNoEncode, which includes
the pages, not just the webs. There is a limitation which Chris mentions in that this
provider doesn't return the default page in a web, rather just a reference to the
web itself, but that's ok - he explains a workaround to this if you're interested... 
&lt;/p&gt;
&lt;p&gt;
Essentially, my client's problem is that they have a left-side tree navigation, kind
of.&amp;nbsp; There's some interesting display logic that, like I said earlier, just doesn't
work with the out-of-box implementation.&amp;nbsp;Without going into what they really
needed to accomplish, I figure it would be good to explain how to use the object to
answer some of the common questions in a custom navigation scenario. 
&lt;/p&gt;
&lt;p&gt;
1) Where Am I Now?&lt;br&gt;
2) Where's That Page? 
&lt;/p&gt;
&lt;p&gt;
&lt;p&gt;
Luckily, the CurrentNavSiteMapProviderNoEncode has a method that makes finding stuff
pretty easy.&amp;nbsp; &lt;i&gt;FindSiteMapNode()&lt;/i&gt;. This method&amp;nbsp;has three overloads,
all which return a &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.sitemapnode.aspx"&gt;SiteMapNode&lt;/a&gt; object. 
&lt;p&gt;
The first overload&amp;nbsp;takes an HttpContext as a parameter and is great for finding
where you're at now.&amp;nbsp; The second overload&amp;nbsp;takes a URL and can be used for
finding any SiteMapNode given the URL provided.&amp;nbsp; The third&amp;nbsp;takes both a
URL and an SPWeb object as context. 
&lt;p&gt;
Here's some examples on how you use this along with the Publishing object model: 
&lt;p&gt;
&lt;div style="BORDER-RIGHT: gray 1px solid; PADDING-RIGHT: 4px; BORDER-TOP: gray 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 8pt; PADDING-BOTTOM: 4px; MARGIN: 20px 0px 10px; OVERFLOW: auto; BORDER-LEFT: gray 1px solid; CURSOR: text; MAX-HEIGHT: 200px; LINE-HEIGHT: 12pt; PADDING-TOP: 4px; BORDER-BOTTOM: gray 1px solid; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BACKGROUND-COLOR: #f4f4f4"&gt;&lt;pre style="PADDING-RIGHT: 0px; PADDING-LEFT: 0px; FONT-SIZE: 8pt; PADDING-BOTTOM: 0px; MARGIN: 0em; OVERFLOW: visible; COLOR: black; BORDER-TOP-STYLE: none; LINE-HEIGHT: 12pt; PADDING-TOP: 0px; FONT-FAMILY: consolas, 'Courier New', courier, monospace; BORDER-RIGHT-STYLE: none; BORDER-LEFT-STYLE: none; BACKGROUND-COLOR: #f4f4f4; BORDER-BOTTOM-STYLE: none"&gt;&lt;span style="COLOR: #008000"&gt;//In
a server control, find the SiteMapNode for the current HttpContext &lt;/span&gt; SiteMapNode
siteNode = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(Context); &lt;span style="COLOR: #008000"&gt;///
&amp;lt;summary&amp;gt; &lt;/span&gt; &lt;span style="COLOR: #008000"&gt;/// Find SiteMapNode for PublishingWeb
object &lt;/span&gt; &lt;span style="COLOR: #008000"&gt;/// &amp;lt;/summary&amp;gt; &lt;/span&gt; &lt;span style="COLOR: #008000"&gt;///
&amp;lt;param name="web"&amp;gt;PublishingWeb object to retrieve in PortalSiteMapProvider&amp;lt;/param&amp;gt; &lt;/span&gt; &lt;span style="COLOR: #008000"&gt;///
&amp;lt;returns&amp;gt;SiteMapNode object representing given PublishingWeb object&amp;lt;/returns&amp;gt; &lt;/span&gt; &lt;span style="COLOR: #0000ff"&gt;protected&lt;/span&gt; SiteMapNode
GetSiteNodeForPubWeb(PublishingWeb web) { &lt;span style="COLOR: #0000ff"&gt;string&lt;/span&gt; url
= web.Url + &lt;span style="COLOR: #006080"&gt;"/"&lt;/span&gt; + web.DefaultPage.Url; SiteMapNode
siteNode = PortalSiteMapProvider.CurrentNavSiteMapProviderNoEncode.FindSiteMapNode(url); &lt;span style="COLOR: #0000ff"&gt;return&lt;/span&gt; siteNode;
} &lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;
&amp;nbsp;
&lt;/p&gt;
&lt;p&gt;
The &lt;a href="http://msdn2.microsoft.com/en-us/library/system.web.sitemapnode.aspx"&gt;SiteMapNode&lt;/a&gt; object
contains everything needed to walk around in the hierarchy of the PSMP, and should
allow you conquer any custom display logic any tricky designer can throw at you...
&lt;/p&gt;
&lt;p&gt;
Update: I added a follow-up post to this one with some &lt;a class=TitleLinkStyle href="http://blog.richfinn.net/blog/2007/08/15/SampleCodeForCustomCMOSSNavigationUsingPortalSiteMapProvider.aspx" rel=bookmark&gt;Sample
Code for a Custom C# MOSS Navigation Using PortalSiteMapProvider&lt;/a&gt;
&lt;/p&gt;
&lt;img width="0" height="0" src="http://blog.richfinn.net/blog/aggbug.ashx?id=f969269a-751e-47b9-bb6e-6bb95cc19908" /&gt;</description>
      <comments>http://blog.richfinn.net/blog/CommentView,guid,f969269a-751e-47b9-bb6e-6bb95cc19908.aspx</comments>
      <category>Microsoft Office SharePoint Server</category>
      <category>Navigation</category>
    </item>
  </channel>
</rss>