Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

How can I create a two-tier horizontal menu like Mashable.com? WordPress

  • SOLVED

I want it to include posts, pages, tags, categories as link options.

I don't mind if it's a manual solution external to Wordpress itself, as long as it behaves with it.

Answers (1)

2010-03-08

Nathan Parikh answers:

Just for clarity, are you saying that you want your main navigation to consist of (for example):
"Posts | Pages | Tags | Categories" or do you want those items/links on the second tier?

Once I get the complete picture I should be able to give you the code you need.


salamiparty comments:

sorry, i wasn't very clear.
as on mashable site, main nav to consist of categories, with subnav to consist of subcatgories:
Home | Social Media | *Mobile* | Web Video | Entertainment
Mobile News | iPhone | Android | Blackberry | Windows Mobile | Palm


it would also be handy to have the flexibility to add custom links to the second tier so that i can add filter by tag and so forth.


Nathan Parikh comments:

OK thanks for the clarification.

This will give you a very nice navbar that contains the categories in the top section with the subcategories in the second tier.
(Note for this to work, you will have to download the Superfish script from [[LINK href="http://users.tpg.com.au/j_birch/plugins/superfish/superfish-1.4.8.zip"]]http://users.tpg.com.au/j_birch/plugins/superfish/superfish-1.4.8.zip[[/LINK]])

I would recommend creating a subfolder called "nav" in your theme folder and uploading all of the downloaded files from the above ZIP into that folder.

Put the following before the <?php wp_head(); ?> in your header.php file:

//link to the CSS files for this menu type
<link rel="stylesheet" type="text/css" media="screen" href="<?php bloginfo('template_directory'); ?>/nav/superfish.css" />
<link rel="stylesheet" type="text/css" media="screen" href="<?php bloginfo('template_directory'); ?>/nav/superfish-navbar.css" />

// link to the JavaScript files (hoverIntent is optional)
<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/nav/hoverIntent.js"></script>
<script type="text/javascript" src="<?php bloginfo('template_directory'); ?>/nav/superfish.js"></script>

// initialise Superfish
<script type="text/javascript">

$(document).ready(function(){
$("ul.sf-menu").superfish({
pathClass: 'current'
});
});

</script>


Next, in your header.php file, replace the current nav menu code with the following:
<ul id="nav" class="sf-menu sf-navbar">
<li><a href="<?php echo get_option('home'); ?>/">Home</a></li>
<?php wp_list_categories('orderby=name&exlude=181&title_li=');
$this_category = get_category($cat);
if (get_category_children($this_category->cat_ID) != "") {
echo "<ul>";
wp_list_categories('orderby=id&show_count=0&title_li=&use_desc_for_title=1&child_of='.$this_category->cat_ID);
echo "</ul>";
}
?>
</ul>


That should be it. Let me know if you need any more help!


salamiparty comments:

Thank you for the guidance so far.

What is integral to this is that like the Mashable navigation, it is contextual, so that if i am reading something from the parent or its sub categories, on the menu the parent is highlighted and the corresponding sub categories are displayed underneath.

i am more concerned with this aspect than anything else.

Any ideas?


Nathan Parikh comments:

OK I figured out the solution.
This does NOT use the previous jQuery powered menu I gave before, so just delete all that code. Everything here is all you need:

Replace your current nav code with this:
<ul id="nav">
<li <?php if(is_home()) {echo 'class="current_page_item"';}?>><a href="<?php bloginfo('url'); ?>">Home</a></li>
<?php wp_list_categories('orderby=name&depth=1&title_li='); ?>
</ul>
<?php
$cat = get_query_var('cat');
$category = get_category ($cat);

if ($category->cat_ID) {
if($category->category_parent)
$children = wp_list_categories("orderby=id&hide_empty=0&title_li=&child_of=".$category->category_parent."&echo=0");
else
$children = wp_list_categories("orderby=id&hide_empty=0&title_li=&child_of=".$category->cat_ID."&echo=0");
if ($children) { ?>
<ul id="subnav">
<?php echo $children; ?>
</ul>
<?php }}?>


Place this code in your style.css file:
#nav {
background:#577da2;
height:32px;
margin: 0px;
padding: 0px;
}

#nav li {
margin-right:5px;
height: 100%;
}

#nav li, #subnav li {
float:left;
list-style:none;
}

#nav a, #nav a:visited {
color:#FFF;
text-decoration:none;
font-weight:bold;
float: left;
height: 21px;
padding: 10px 10px 0px 10px;
}

#nav a:hover, #nav a:active,
li.current_page_parent a,
li.current_page_parent a:visited,
#nav li.current_page_item a,
#nav li.current_page_item a:visited,
#nav li.current-cat,
#nav li.current-cat-parent
{
background:#295887;
}

#subnav {
background:#e6eef7;
height:25px;
margin: 0px;
padding: 0px 0px 0px 0px;
}

#subnav li {
border-right:1px solid #295887;
padding: 6px 7px;
height: 13px;
}
#subnav li.current-cat {
background: #BFDEFF;
}

#subnav a, #subnav a:visited {
color:#295887;
text-decoration:none;
font-weight:bold;
}

#subnav a:hover, #subnav a:active,
#subnav li.current_page_item a,
#subnav li.current_page_item a:visited {
text-decoration:underline;
}


Again, you do not need the javascript or CSS I gave you in the last solution.
That should do it!


salamiparty comments:

OK, looking good so far, and we're nearly there.

At the moment, the menu is persistent, and the subnav behaves correctly...

Except that we need to make the parent category and it's matching subnav choices highlighted to match the category of whatever post we're currently on.

So if i've just wandered from google to a post, its parent category will be highlighted, and the subcategories will be visible underneath.

Like on Mashable ;-)

Thanks, great work so far!


Nathan Parikh comments:

This should work just like you need it to:

Here's the new nav code:
<ul id="nav">
<li <?php if(is_home()) {echo 'class="current_page_item"';}?>><a href="<?php bloginfo('url'); ?>">Home</a></li>
<?php wp_list_categories('orderby=name&depth=1&title_li='); ?>
</ul>
<?php
$cat = get_query_var('cat');
$category = get_category ($cat);
$categories = get_the_category();

$subcat = get_the_category();
$parentCatName = get_cat_name($subcat[0]->parent);
$category_id = get_cat_ID( "$parentCatName" );

function post_is_in_descendant_category( $cats, $_post = null )
{
foreach ( (array) $cats as $cat ) {
// get_term_children() accepts integer ID only
$descendants = get_term_children( (int) $cat, 'category');
if ( $descendants && in_category( $descendants, $_post ) )
return true;
}
return false;
}

if ($category->cat_ID) {
if($category->category_parent) {
//Displays subcategories on subcategory index
$children = wp_list_categories("orderby=id&hide_empty=0&title_li=&child_of=".$category->category_parent."&echo=0");
}
else {
//Display subcategories on parent category index
$children = wp_list_categories("orderby=id&hide_empty=0&title_li=&child_of=".$category->cat_ID."&echo=0");
}
if ($children) { ?>
<ul id="subnav">
<?php echo $children; ?>
</ul>
<?php }
}
elseif (is_single() && (post_is_in_descendant_category($category_id)) && $categories[0]->category_parent == $category_id ) { ?>
<ul id="subnav">
<?php
$category = get_the_category();
$cat_term_id = $category[0]->term_id;
$cat_category_parent = $category[0]->category_parent;
$listcat = wp_list_categories('echo=0&child_of='.$cat_category_parent.'&title_li=');
$listcat = str_replace("cat-item-".$cat_term_id, "cat-item-".$cat_term_id." current-cat", $listcat);
if ( in_category( $cat_term_id ) || post_is_in_descendant_category( $cat_category_parent )) {
echo $listcat;
}
?>
</ul>
<?php } ?>



And here's the CSS:
#nav
{
background:#577da2;
height:32px;
margin: 0px;
padding: 0px;
}
#nav li
{
margin-right:5px;
height: 100%;
}
#nav li, #subnav li
{
float:left;
list-style:none;
}
#nav a, #nav a:visited
{
color:#FFF;
text-decoration:none;
font-weight:bold;
float: left;
height: 21px;
padding: 10px 10px 0px 10px;
}
#nav a:hover, #nav a:active, li.current_page_parent a, li.current_page_parent a:visited, #nav li.current_page_item a, #nav li.current_page_item a:visited, #nav li.current-cat, #nav li.current-cat-parent, #nav li a.active_category { background:#295887; }
#subnav
{
background:#e6eef7;
height:25px;
margin: 0px;
padding: 0px 0px 0px 0px;
}
#subnav li
{
border-right:1px solid #295887;
padding: 6px 7px;
height: 13px;
}
#subnav li.current-cat { background: #BFDEFF; }
#subnav a, #subnav a:visited
{
color:#295887;
text-decoration:none;
font-weight:bold;
}
#subnav a:hover, #subnav a:active, #subnav li.current_page_item a, #subnav li.current_page_item a:visited { text-decoration:underline; }


That should do it! :-)


Nathan Parikh comments:

Oh I forgot to mention you will need this plugin to help with the highlighting:
http://www.screenshine.net/blog/1474_wordpress-plugin-show-active-category

Just activate the plugin and everything should be set!