Skip to main content

This site requires you to update your browser. Your browsing experience maybe affected by not having the most up to date version.

General Questions /

General questions about getting started with SilverStripe that don't fit in any of the categories above.

Moderators: martimiz, Sean, biapar, Willr, Ingo, swaiba, simon_w

Main Navigation With Different Tab Classes


Reply


8 Posts   1620 Views

Avatar
ckd

Community Member, 18 Posts

20 August 2009 at 9:22pm

Hi,

I am new to SilverStripe and am currently integrating my first website into the CMS. Can anyone suggest how I would integrate the existing website navigation menu to work with SS? It would not be a problem except in this case each tab needs its own id for separate styling. Any help would be greatly appreciated.

<div id="nav_main"><!-- Begin Nav Main -->
<ul id="nav">
<li id="nav01"><a href="index.html" title="home">home</a></li>
<li id="nav02"><a href="offer.html" title="we offer">we offer</a></li>
<li id="nav03"><a href="pricing.html" title="pricing">pricing</a></li>
<li id="nav04"><a href="articles.html" title="articles">articles</a></li>
<li id="nav05"><a href="contact.html" title="contact us">contact us</a></li>
</ul>
</div><!-- /End Nav Main -->

Avatar
Pigeon

Community Member, 243 Posts

20 August 2009 at 10:32pm

Edited: 20/08/2009 10:35pm

Hi ckd and welcome to SS,

When you echo the menu you do something like this on your template:

<% control Menu(1) %>
<li><a href="#">$MenuTitle</a></li>
<% end_control %>

see: http://doc.silverstripe.com/doku.php?id=tutorial:1-building-a-basic-site#making_a_navigation_system

I believe that all controls have an in-built function called 'Pos', which is basically a counting function that tells you the position of the item you are currently in the control of. (There is also First and Last)

This means, that you could feasibly do this:

<% control Menu(1) %>
<li id="nav{$Pos}"><a href="#">$MenuTitle</a></li>
<% end_control %>

(i can't remember off the top of my head if you need the curly brackets or not)

NB: This number won't have a leading 0. so you would get nav1, nav2, etc.

Hope that sorts out your problem.

Avatar
ckd

Community Member, 18 Posts

20 August 2009 at 11:38pm

That's great, thank you. I used the following code and navigation now functions correctly:

<div id="nav_main"><!-- Begin Nav Main -->
<ul id="Menu1">
<% control Menu(1) %>
<li id="nav0{$Pos}" class="$LinkingMode"><a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a></li>
<% end_control %>
</ul>
</div><!-- /End Nav Main -->

The only small issue left to resolve is with the styling. Currently my CSS for the list items looks like this:

li#nav01 a {background-position: 0 0px; width: 148px; left: 0px;}
li#nav01 a:hover {background-position: 0 -32px;}
li#nav02 a {background-position: -296px 0; width: 148px; left: 296px;}
li#nav02 a:hover {background-position: -296px -32px;}
li#nav03 a {background-position: -444px 0; width: 148px; left: 444px;}
li#nav03 a:hover {background-position: -444px -32px;}
li#nav04 a {background-position: -444px 0; width: 148px; left: 444px;}
li#nav04 a:hover {background-position: -444px -32px;}
li#nav05 a {background-position: -592px 0; width: 148px; left: 592px;}
li#nav05 a:hover {background-position: -592px -32px;}

The navigation works fine in all major browsers with the current CSS, however when put into SS the far left tab is indented 32px even though I have it set at 0px. I checked the code with FireBug and it shows that the background position for nav01 is being overridden by SS for some reason.

Avatar
ckd

Community Member, 18 Posts

20 August 2009 at 11:56pm

Resolved the styling issue by adding padding 0px to ul#Menu1.

Avatar
Pigeon

Community Member, 243 Posts

21 August 2009 at 12:02am

Edited: 21/08/2009 12:03am

Glad it worked,

One thing i would say is that the leading 0 is not very 'future proof'. Probably best to do:

<div id="nav_main"><!-- Begin Nav Main -->
<ul id="Menu1">
<% control Menu(1) %>
<li id="nav<% if Pos < 10 %>0<% end_if %>{$Pos}" class="$LinkingMode"><a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a></li>
<% end_control %>
</ul>
</div><!-- /End Nav Main -->

Unless, of course, you want nav010, etc to be IDs...

Anyway, just a thought as i like to make sure that little things like that are perfect :P

Avatar
ckd

Community Member, 18 Posts

21 August 2009 at 2:48am

Thank you for the information. The top horizontal navigation is limited to only 5 tabs due to the site design, each tab has to be individually styled as it has its own icon and also I am using the CSS Sprite method for styling to minimize image flicker hence the use of id's for each 'li'.

Based on the above should I adopt the method you suggest? The '0's' dont have to be there really, just can be nav1, nav2 etc. If I do that and then use the code you suggest as below, would that be better?

<li id="nav<% if Pos < 5 %>0<% end_if %>{$Pos}" class="$LinkingMode"><a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a></li>

In addition I have split the top level navigation into two parts, I have hard coded this second nav section into the sidebar. It uses a similar sprite method, however the id's for the individual tabs are assigned to the links instead of the 'li'. These tabs are styled differently from the tabs on the horizontal menu. As I am wanting these all to be part of the top level navigation, is there a better more straight forward way of splitting the top level navigation, instead of hard coding it as I have done within the sidebar?

Avatar
Pigeon

Community Member, 243 Posts

21 August 2009 at 3:44am

Edited: 21/08/2009 3:52am

If there can't be more than 5 (or even if there could be) i personally wouldn't use a leading 0 in the IDs, there is no need.

But if you want leading 0s then your original method (not including the if statement) would be most efficient in terms of processing time.

If there is no possibility in having over 5 items, there is no need what-so-ever to have an if statement like you suggested in your last post. What i would suggest is wrapping the whole control in an if:

<div id="nav_main"><!-- Begin Nav Main -->
<ul id="Menu1">
<% control Menu(1) %>
<% if Pos < 6 %>
<li id="nav{$Pos}" class="$LinkingMode"><a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a></li>
<% end_if %>
<% end_control %>
</ul>
</div><!-- /End Nav Main -->

Which means no matter how many top-level pages the user adds, only the first five would be echoed on site. This is best if someone other than you is going to manage the site to stop them accidentally adding menu items and breaking the site.

If you were using CSS3 (which doubt you are - because it isnt supported by IE6) you can use nth items which would mean no need to give each an individual ID (thus reducing mark-up) [http://www.smashingmagazine.com/2009/08/17/taming-advanced-css-selectors/ - section 6].

Hard coding your navigation is a very bad idea, it means it is not flexable and the user can't edit it through the CMS. You aren't seperating content and layout (which is the whole point!).

If i understand what you are trying to do correctly (split the top level navigation into two areas), I would personally do the above method i specified for the first 5 links, and then for the 'side nav' (as i will call it) do:

<div id="nav_main"><!-- Begin Nav Main -->
<ul id="Menu1">
<% control Menu(1) %>
<% if Pos > 5 %>
<li id="nav{$Pos}" class="$LinkingMode"><a href="$Link" title="Go to the &quot;{$Title}&quot; page">$MenuTitle</a></li>
<% end_if %>
<% end_control %>
</ul>
</div><!-- /End Nav Main -->

It is probably best to keep the IDs on the li elements so that if anyone ever needs to maintain your site (or even if you come back to it after some time), it is as straight forward and consistent as possible.

It would also be possible to create your own page control HorizontalMenu and SideMenu which could just return the first 5 and all others (respectively) which would be more efficient than just running through all the menu items and ignoring the ones outside of the if statement. I would do it something like this:

Class Page_Controller extends ... {
function HorizontalMenu() {
$result = DataObject::get("SiteTree", "\"ShowInMenus\" = 1 AND \"ParentID\" = 0", '','','5');
$visible = array();

      // Remove all entries the can not be viewed by the current user
      // We might need to create a show in menu permission
      if(isset($result)) {
         foreach($result as $page) {
            if($page->can('view')) {
               $visible[] = $page;
            }
         }
      }

      return new DataObjectSet($visible);
}
}


That function gets up to 5 of the menu items, then you could run through the control as <% control HorizontalMenu %> with no need for an if < 6 condition. Much more efficient.

For the other menu i would modify it to return all but the first 5 items, can't think exactly how i would do it right now, but it wouldnt be impossible.

Now, i think that is enough help for now! Once you get some working code, post it back here so everyone can benefit! :D

PS: You need to think about how your site/design is going to cope if the user changes the order of the items in the menu... Will this badly effect the design impact?

Avatar
ckd

Community Member, 18 Posts

21 August 2009 at 4:50pm

Thank you for all of the helpful information. Have bookmarked, as I know I will need to refer to this again in the near future.

The site is just for practice and probably not the ideal site to start learning SS with, but good to know that SS can adapt to all kinds of websites and not the other way around. Have been trying quite a few and am more used to WP as a CMS but finding SS is more in line to what I have been looking for.

I tried the methods that you mentioned below, however I ended up getting parse errors for some reason. I also tried it without the 'if' statements but the second nav tabs kept appearing on the horizontal menu. I have left it hard coded in the interim until I familiarize myself a little more with the way everything functions and then I will try again.