SiteMenu
Argh, I am going to tear my hair out.
I have a simple main menu (you can view it here: www.brightdigital.co.uk). It simply comprises of <a> tags with a | as a seperator. Really really simple.
Now, I decided that when creating this in SiteFinity, I should use the SiteMenu control which I believe is the TabSrip control. So far I have (after a couple of hours) managed to get the style right by using the Telerik Visual Style Builder (The only useful thing it gave me was the css classes. I had to remove all the generated CSS because it was just wrong and that was nothing to do with the way I designed it).
So now I am at the point of adding the seperator items. Now this is the pain. How the hell do you add a seperator item? I don't want to write any code (I shouldn't have to) and I can't see a property stating "SeperatorItemText" (why not?). So is there some other way of adding this?
Thanks,
Jaymie
Hi Jaymie,
If you want to use some special custom separator you need to create a custom template. I have created a replica of your navigation (see the attached image). The simple solution in your case is to add a right gray border to every <a> element. Below is the CSS code that I wrote:
.RadTabStripTop_bright
font-family
:
Arial
;
font-size
:
14px
;
font-weight
:
bold
;
.RadTabStripTop_bright a
color
:
#C8C8C8
;
text-decoration
:
none
;
border-right
:
1px
solid
#ccc
;
padding-right
:
5px
;
padding-left
:
5px
!important
;
.RadTabStripTop_bright .rtsLevel
1
span.rtsIn,
.RadTabStripTop_bright .rtsLevel
1
span.rtsOut,
.RadTabStripTop_bright .rtsLevel
1
span.rtsTxt
padding
:
0
!important
.RadTabStripTop_bright a:hover
color
:
#11b2f0
;
.RadTabStripTop_bright a.rtsSelected
color
:
#b7d432
I have manged to set a custom template (I thought I said that in my original post :)).
The problem is my seperator is | as a character. Not as an image or border, I just want to use text.
Can this be achieved?
If not, it might be an idea to add a property to the control because I see it as rather a needed function.
Hello Jaymie,
I got your point and I said in my previous post that this is the easiest solution. If you want to use character for separator you need to create custom ascx template for RadTabStrip - the custom template path property.
To add a property "separator character" is not appropriate solution for RadTabStrip because the users can use it both in vertical and horizontal mode. Also instead of "|" what other kinds of character separators can be used?
Can you give me an example of how I would go about replacing the RadTabStrip with my own custom control?
Also, for Seperator Items, you could use " ", "/" or even put in some html for an image seperation. Surely people have that need?
Hello Jaymie,
Here is a simple way to create the menu with custom template.
1. In your root folder add a file called customnavigation.ascx
2. In the file add following lines:
<%@ Control Language="C#" AutoEventWireup="true" %>
<
telerik:RadTabStrip
ID
=
"RadPanelbarNav"
runat
=
"server"
Visible
=
"false"
/>
<
asp:Repeater
ID
=
"Repeater1"
runat
=
"server"
DataSourceID
=
"SiteMapDataSource"
>
<
HeaderTemplate
>
<
div
class
=
"mobilemenu"
>
</
HeaderTemplate
>
<
ItemTemplate
>
<
asp:HyperLink
ID
=
"HyperLink1"
runat
=
"server"
NavigateUrl='<%# Eval("Url") %>'><%#Eval ("Title") %></
asp:HyperLink
> |
</
ItemTemplate
>
<
FooterTemplate
>
</
div
>
</
FooterTemplate
>
</
asp:Repeater
>
<
asp:SiteMapDataSource
runat
=
"server"
ID
=
"SiteMapDataSource"
ShowStartingNode
=
"false"
/>
3. When you drop the navigation control in the Design settings section add ~/customnavigation.ascx as a value of the Custom template path property.
This will output very simple html similar to that one on your site
Kind regards,
Jordan
the Telerik team
That's great, thanks.
How do I record the selected item? It doesn't seem to get passed back with that.
Anyone got an answer to Robs question?
Hi Jaymie,
You have to manually bind the repeater control and populate it with datasource of pages. Inside the ItemTemplate of the repeater you can set the CssClass for the HyperLink control depending on the current page.
here is a sample code
<script runat=
"server"
>
protected
void
Page_Load(
object
sender, EventArgs e)
this
.Repeater1.DataSource = GetPageNodes();
this
.Repeater1.ItemDataBound +=
new
RepeaterItemEventHandler(Repeater1_ItemDataBound);
this
.Repeater1.DataBind();
void
Repeater1_ItemDataBound(
object
sender, RepeaterItemEventArgs e)
if
(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
var link = e.Item.FindControl(
"HyperLink1"
)
as
HyperLink;
var data = (Telerik.Sitefinity.Pages.Model.PageNode)e.Item.DataItem;
var current = Telerik.Sitefinity.Web.SiteMapBase.GetActualCurrentNode();
if
(current.Title == data.Title)
link.CssClass =
"red"
;
link.Text = current.Title;
else
link.Text = data.Title;
public
List<Telerik.Sitefinity.Pages.Model.PageNode> GetPageNodes()
var list =
new
List<Telerik.Sitefinity.Web.PageSiteNode>();
var manager = Telerik.Sitefinity.Modules.Pages.PageManager.GetManager();
// HERE GET ONLY THE FORONTEND PAGES. BELOW I get all pages just for the sample.
return
manager.GetPageNodes().ToList();
</script>
<asp:Repeater ID=
"Repeater1"
runat=
"server"
>
<HeaderTemplate>
<div
class
=
"mobilemenu"
>
</HeaderTemplate>
<ItemTemplate>
<asp:HyperLink ID=
"HyperLink1"
runat=
"server"
></asp:HyperLink> |
</ItemTemplate>
<FooterTemplate>
</div>
</FooterTemplate>
</asp:Repeater>
Hi Ivan,
Thanks for your reply.
I added your code to my template and the initial error I got was that you can't set the DataSourceID and the DataSource of the repeater, so I added
this.Repeater1.DataSourceID = "";
that fixed the first issue. Then when I did that and refreshed my page, I found that it only showed the name of the pages. There were no links. When I tried to add the Url property to the NavigateURL of the Hyperlink, it complained that Url doesn't exist.
Also, How do I get it to show the top level pages (Home, Contact, Etc). Your code has a comment to get the pages I need, but I don't know how to do it :)
Cheers,
Jaymie
Hello Jaymie,
If this control
var link = e.Item.FindControl(
"HyperLink1"
)
as
HyperLink;
is a HyperLink and it is not null you should not have problems setting the ASP.NET HyperLink properties.
You can use the fluent API to get the TOP level pages.
var pages11 = App.WorkWith().Pages().LocatedIn(PageLocation.Frontend).Get();
foreach
(PageNode p
in
pages11)
p.Page.Id = SiteInitializer.FrontendRootNodeId;
Hi Ivan :)
Thanks for the swift reply.
I can access the HyperLink properties, that isn't the issue. The issue is that it tells me that Url doesn't exist for the collection. Title does, but Url doesn't.
I realise now that I didn't explain that properly.
So once again, it is the collection that I am binding that is the issue. For some reason it doesn't seem to have a value called Url, so I can't bind it to the HyperLink.
Also, how do I go about binding just the root nodes?
Hello Jaymie,
Your menu looks pretty good. There are still some small visual glitches but you are on the right way. You should use the skin file only if you want fine adjusting of the animations, etc. In other case you can use only the Wrapper CSS class (skin) property.
Greetings,
Jordan
the Telerik team
Hi Jorden.
The last post was not me, it was someone hijacking the thread :) I have no issues with the Skin.
My issue is still to do with trying to set the active link.
This is the code I have at the moment:
public
List<Telerik.Sitefinity.Pages.Model.PageNode> GetPageNodes()
var manager = Telerik.Sitefinity.Modules.Pages.PageManager.GetManager();
var pageNodes = manager.GetPageNodes().Where(pN => pN.Page.Title ==
"Home"
);
return
pageNodes.ToList();
Anymore help on this issue?
Hello Roberto,
PageNode has a property Parent which returns the parent PageNode. So you can use an while or if loop to get the top level parent.
Kind regards,
Ivan Dimitrov
the Telerik team
For anyone else experiencing the issue I had here, here is the solution :)
First of all, leave the binding to the control, this will allow you to select the Top level pages (by editing the control properties in your admin site), then just latch onto the ItemDataBound method of the repeater and just get the current page.
<%@ Control Language="C#" AutoEventWireup="true" %>
<
telerik:RadTabStrip
ID
=
"RadPanelbarNav"
runat
=
"server"
Visible
=
"false"
/>
<
script
runat
=
"server"
>
void Repeater1_ItemDataBound(object sender, RepeaterItemEventArgs e)
if (e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)
SiteMapNode currentNode = Telerik.Sitefinity.Web.SiteMapBase.GetCurrentProvider().CurrentNode;
var link = e.Item.FindControl("HyperLink1") as HyperLink;
if (currentNode != null)
if (currentNode.Url.ToLower().Contains(link.NavigateUrl.ToLower()))
link.CssClass = "activeBlue";
</
script
>
<
asp:Repeater
ID
=
"Repeater1"
runat
=
"server"
DataSourceID
=
"SiteMapDataSource"
OnItemDataBound
=
"Repeater1_ItemDataBound"
>
<
HeaderTemplate
>
<
div
class
=
"SiteMenu"
>
</
HeaderTemplate
>
<
ItemTemplate
>
<
asp:HyperLink
ID
=
"HyperLink1"
NavigateUrl='<%# Eval("Url") %>' runat="server"><%# Eval("Title") %></
asp:HyperLink
> |
</
ItemTemplate
>
<
FooterTemplate
>
</
div
>
</
FooterTemplate
>
</
asp:Repeater
>
<
asp:SiteMapDataSource
runat
=
"server"
ID
=
"SiteMapDataSource"
ShowStartingNode
=
"false"
/>