I want to ask something which I don't have any idea if its possible or not.
I will show you first as html to explain what I need.
<nav class="nav-categories">
<ul>
<li class="no-filter">
<strong>Category Name</strong> <span class="count">25</span>
</li>
<li class="no-filter">
<strong>Category Name</strong> <span class="count">25</span>
</li>
<li class="no-filter">
<strong>Category Name</strong> <span class="count">25</span>
</li>
<li class="no-filter">
<strong>Category Name</strong> <span class="count">25</span>
</li>
</ul>
<div class="hidden-content" id="hidden-categories">
<ul>
<li class="no-filter">
Category Name<span class="count">25</span>
</li>
<li class="no-filter">
Category Name<span class="count">25</span>
</li>
<li class="no-filter">
Category Name<span class="count">25</span>
</li>
<li class="no-filter">
Category Name<span class="count">25</span>
</li>
</ul>
</div>
<button class="category-toggle" data-action="content-toggle" data-target="#hidden-categories" data-more="Display More Categories" data-less="Display Less Categories">Display All Categories</button>
</nav>
As you see on the code above there are 2 <ul> elements two menus, but one is visible and one is hidden which I can display hidden-content by clicking on the button.
With the code below I can display all WordPress categories but would be nice to know if its possible to display the half of categories in the first div and the other half in hidden-content class.
<?php
$categories = get_categories();
echo '<nav class="nav-categories"><ul>';
foreach($categories as $category) {
echo '<li class="no-filter"><a href="' . get_category_link( $category->term_id ) . '">' . $category->name.'';
echo '<span class="count">' . $category->count . '</span>';
echo '</a></li>';
}
echo '</ul></nav>';
?>
Yes it is possible, and there are many ways to achieve this, probably the easiest and fastest is (this is extremely naive and I just added a few additions and modifications to your code, the concept is just find the index that is half the array length), this should work assuming your originally code works, if it doesn't then I'm sure you can understand the concept.
<?php
$categories = get_categories();
$firstNav = "";
$secondNav = "<div class="hidden-content" id="hidden-categories">";
echo '<nav class="nav-categories"><ul>';
$maxIndex = count($categories) - 1;
$half = floor($maxIndex / 2); //To get the middle of the array, or you can use ceil();
$curIndex = 0;
foreach($categories as $category) {
if ($curIndex <= $half) {
$firstHalf .= '<li class="no-filter"><a href="' . get_category_link( $category->term_id ) . '">' . $category->name.'';
$firstHalf .= '<span class="count">' . $category->count . '</span>';
$firstHalf .= '</a></li>';
}
else {
$secondHalf .= '<li class="no-filter"><a href="' . get_category_link( $category->term_id ) . '">' . $category->name.'';
$secondHalf .= '<span class="count">' . $category->count . '</span>';
$secondHalf .= '</a></li>';
}
$curIndex++;
}
$firstHalf .= "</ul>";
$secondHalf .= "</div>";
echo $firstHalf;
echo $secondHalf;
echo '</ul></nav>';
?>
Related
I am trying to create a hoverable mega menu, all works fine except the active one.
I checked in source codes and active class is added, but it doesn't show up the content until mouseenter on it.
see image please :
And this is when I go on it with mouse, it show up with no problem.
I gues I need to set main (FINANCE is main menu in pic) menu active, but dont know how to pass it to submenu.
Here is my full code :
$stmt_menu = $pdo->prepare("SELECT * FROM categories WHERE parentId = ? LIMIT 5");
$stmt_menu->execute([0]);
if ($stmt_menu->rowCount() > 0) {
$query = $stmt_menu->fetchAll();
foreach ($query as $row) {
if ($row['cat_type'] == 'mega') {
?>
<li class="dropdown megamenu-fw mega-li-<?php echo $row['catId']; ?>">
<?php echo $row['catName']; ?><span class="caret"></span>
<ul class="dropdown-menu megamenu-content dropdown-top" role="menu" aria-expanded="true" data-mega-ul="<?php echo $row['catId']; ?>">
<li>
<?php
$stmt_menu = $pdo->prepare("SELECT * FROM categories WHERE parentId = ? LIMIT 5");
$stmt_menu->execute([$row['catId']]);
if ($stmt_menu->rowCount() > 0) {
$subquery = $stmt_menu->fetchAll();
?>
<div class="sub-menu-left">
<ul class="nav-sub-categories">
<?php
$i = 0;
foreach ($subquery as $subq) {
$actives = '';
if($i == 0){
$actives = ' active';
}
?>
<li data-category-filter="<?php echo $subq['cat_seo_url']; ?>-<?php echo $subq['catId']; ?>" class="li-sub-category<?php echo $actives; ?>"><?php echo $subq['catName']; ?></li>
<?php
$i++;
}
?>
</ul>
</div>
<div class="sub-menu-right">
<?php
$i = 0;
foreach ($subquery as $subcats) {
$actives = '';
if($i == 0){
$actives = ' active';
}
?>
<div class="sub-menu-inner filter-<?php echo $subcats['cat_seo_url']; ?>-<?php echo $subcats['catId']; ?><?php echo $actives; ?>">
<div class="row row-menu-right">
<div class="col-sm-3 menu-post-item">
<div class="post-item-image">
<a href="is-allowance-instantly-strangers-applauded">
<img src="assets/img/img_bg_md.png" data-src="uploads/images/202203/image_380x226_624239afd7295.jpg" alt="Is allowance instantly strangers applauded" class="lazyload img-responsive img-post" width="1" height="1"/>
</a>
</div>
<h3 class="title"><?php echo $subcats['cat_seo_url']; ?> Is allowance instantly strangers applauded</h3>
<p class="post-meta">
admin
<span>Mar 28, 2022</span>
<span><i class="icon-comment"></i>2</span>
<span class="m-r-0"><i class="icon-eye"></i>894</span>
</p>
</div>
</div>
</div>
<?php
$i++;
}
?>
</div>
<?php
}
?>
</li>
</ul>
</li>
<?php
} elseif ($row['cat_type'] == 'dropdown') {
echo ' <li class="nav-item"><a class="nav-link" href="' . $row["cat_seo_url"] . '">test</a></li>';
} else {
echo ' <li class="nav-item"><a class="nav-link" href="' . $row["cat_seo_url"] . '">' . $row["catName"] . '</a></li>';
}
}
}
I have a HTML structure and I want to change those menu elements for a WordPress Menu maintaining the class and id's, and I want to change these elements for the ones I obtain using wp_get_nav_menu_items() and for each, but don't know how.
The thing is changing all Categories for parent and subitem WP menu category and so on, until 5 level of depth that has the menu. For example, replace Devices with first item depth 0, inside change Mobile Phones for second level, and go changing.
<!-- mp-menu -->
<nav id="mp-menu" class="mp-menu mp-overlap">
<div class="mp-level mp-level-open" data-level="1">
<h2 class="icon icon-world">All Categories</h2>
<ul>
<li class="icon icon-arrow-left">
<a class="icon icon-display" href="#">Devices</a>
<div class="mp-level" data-level="2">
<h2 class="icon icon-display">Devices</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li class="icon icon-arrow-left">
<a class="icon icon-phone" href="#">Mobile Phones</a>
<div class="mp-level">
<h2>Mobile Phones</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>Super Smart Phone</li>
<li>Thin Magic Mobile</li>
<li>Performance Crusher</li>
<li>Futuristic Experience</li>
</ul>
</div>
</li>
<li class="icon icon-arrow-left">
<a class="icon icon-tv" href="#">Televisions</a>
<div class="mp-level">
<h2>Televisions</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>Flat Superscreen</li>
<li>Gigantic LED</li>
<li>Power Eater</li>
<li>3D Experience</li>
<li>Classic Comfort</li>
</ul>
</div>
</li>
<li class="icon icon-arrow-left">
<a class="icon icon-camera" href="#">Cameras</a>
<div class="mp-level">
<h2>Cameras</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>Smart Shot</li>
<li>Power Shooter</li>
<li>Easy Photo Maker</li>
<li>Super Pixel</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li class="icon icon-arrow-left">
<a class="icon icon-news" href="#">Magazines</a>
<div class="mp-level">
<h2 class="icon icon-news">Magazines</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>National Geographic</li>
<li>Scientific American</li>
<li>The Spectator</li>
<li>The Rambler</li>
<li>Physics World</li>
<li>The New Scientist</li>
</ul>
</div>
</li>
<li class="icon icon-arrow-left">
<a class="icon icon-shop" href="#">Store</a>
<div class="mp-level">
<h2 class="icon icon-shop">Store</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li class="icon icon-arrow-left">
<a class="icon icon-t-shirt" href="#">Clothes</a>
<div class="mp-level">
<h2 class="icon icon-t-shirt">Clothes</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li class="icon icon-arrow-left">
<a class="icon icon-female" href="#">Women's Clothing</a>
<div class="mp-level">
<h2 class="icon icon-female">Women's Clothing</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>Tops</li>
<li>Dresses</li>
<li>Trousers</li>
<li>Shoes</li>
<li>Sale</li>
</ul>
</div>
</li>
<li class="icon icon-arrow-left">
<a class="icon icon-male" href="#">Men's Clothing</a>
<div class="mp-level">
<h2 class="icon icon-male">Men's Clothing</h2>
<a class="mp-back" href="#">back</a>
<ul>
<li>Shirts</li>
<li>Trousers</li>
<li>Shoes</li>
<li>Sale</li>
</ul>
</div>
</li>
</ul>
</div>
</li>
<li>
<a class="icon icon-diamond" href="#">Jewelry</a>
</li>
<li>
<a class="icon icon-music" href="#">Music</a>
</li>
<li>
<a class="icon icon-food" href="#">Grocery</a>
</li>
</ul>
</div>
</li>
<li><a class="icon icon-photo" href="#">Collections</a></li>
<li><a class="icon icon-wallet" href="#">Credits</a></li>
</ul>
</div>
</nav>
<!-- /mp-menu -->
you can customize nav menu walker class of wordpress to put your N level HTML menu structure. Hers is a example of bootstrap nav walker
if (!class_exists('BootstrapBasicMyWalkerNavMenu')) {
class BootstrapBasicMyWalkerNavMenu extends Walker_Nav_Menu
{
//Overwrite display_element function to add has_children attribute. Not needed in >= Wordpress 3.4
/**
* #link https://gist.github.com/duanecilliers/1817371 copy from this url
*/
function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output)
{
if (!$element)
return;
$id_field = $this->db_fields['id'];
//display this element
if (is_array($args[0]))
$args[0]['has_children'] = !empty($children_elements[$element->$id_field]);
else if (is_object($args[0]))
$args[0]->has_children = !empty($children_elements[$element->$id_field]);
$cb_args = array_merge(array(&$output, $element, $depth), $args);
call_user_func_array(array(&$this, 'start_el'), $cb_args);
$id = $element->$id_field;
// descend only when the depth is right and there are childrens for this element
if (($max_depth == 0 || $max_depth > $depth + 1) && isset($children_elements[$id])) {
foreach ($children_elements[$id] as $child) {
if (!isset($newlevel)) {
$newlevel = true;
//start the child delimiter
$cb_args = array_merge(array(&$output, $depth), $args);
call_user_func_array(array(&$this, 'start_lvl'), $cb_args);
}
$this->display_element($child, $children_elements, $max_depth, $depth + 1, $args, $output);
}
unset($children_elements[$id]);
}
if (isset($newlevel) && $newlevel) {
//end the child delimiter
$cb_args = array_merge(array(&$output, $depth), $args);
call_user_func_array(array(&$this, 'end_lvl'), $cb_args);
}
//end this element
$cb_args = array_merge(array(&$output, $element, $depth), $args);
call_user_func_array(array(&$this, 'end_el'), $cb_args);
}// display_element
/**
* #link https://gist.github.com/duanecilliers/1817371 copy from this url
*/
public function start_el(&$output, $item, $depth = 0, $args = array(), $id = 0)
{
if ((is_object($item) && $item->title == null) || (!is_object($item))) {
return ;
}
$indent = ($depth) ? str_repeat("\t", $depth) : '';
$li_attributes = '';
$class_names = $value = '';
$classes = empty($item->classes) ? array() : (array) $item->classes;
//Add class and attribute to LI element that contains a submenu UL.
if (is_object($args) && $args->has_children) {
//$classes[] = 'dropdown';
$li_attributes .= ' data-dropdown="dropdown"';
}
$classes[] = 'menu-item-' . $item->ID;
//If we are on the current page, add the active class to that menu item.
$classes[] = ($item->current) ? 'active' : '';
//Make sure you still add all of the WordPress classes.
$class_names = join(' ', apply_filters('nav_menu_css_class', array_filter($classes), $item, $args));
$class_names = ' class="' . esc_attr($class_names) . '"';
$id = apply_filters('nav_menu_item_id', 'menu-item-' . $item->ID, $item, $args);
$id = strlen($id) ? ' id="' . esc_attr($id) . '"' : '';
$output .= $indent . '<li' . $id . $value . $class_names . $li_attributes . '>';
//Add attributes to link element.
$attributes = !empty($item->attr_title) ? ' title="' . esc_attr($item->attr_title) . '"' : '';
$attributes .=!empty($item->target) ? ' target="' . esc_attr($item->target) . '"' : '';
$attributes .=!empty($item->xfn) ? ' rel="' . esc_attr($item->xfn) . '"' : '';
$attributes .=!empty($item->url) ? ' href="' . esc_attr($item->url) . '"' : '';
$attributes .= (is_object($args) && $args->has_children) ? ' class="dropdown-toggle" data-toggle="dropdown"' : '';
$item_output = (is_object($args)) ? $args->before : '';
$item_output .= '<a' . $attributes . '>';
$item_output .= (is_object($args) ? $args->link_before : '') . apply_filters('the_title', $item->title, $item->ID) . (is_object($args) ? $args->link_after : '');
$item_output .= (is_object($args) && $args->has_children) ? ' <span class="caret"></span> ' : '';
$item_output .= '</a>';
$item_output .= (is_object($args) ? $args->after : '');
$output .= apply_filters('walker_nav_menu_start_el', $item_output, $item, $depth, $args);
}// start_el
public function start_lvl(&$output, $depth = 0, $args = array())
{
$indent = str_repeat("\t", $depth);
$output .= "\n$indent<ul class=\"sub-menu dropdown-menu\">\n";
}
}
}
How to use this,
<?php wp_nav_menu(array('theme_location' => 'your-menu-location', 'container' => false, 'menu_class' => 'nav navbar-nav', 'walker' => new BootstrapBasicMyWalkerNavMenu())); ?>
Hope this will helps you.
For more information,
Understanding the Walker Class
WP Bootstrap Navwalker
Custom Nav Menu Walker Function
So I've been tackling this problem for a while now and I can't seem to get it to work. I have a category table and a link in my database. I'm trying to display the "category" title as the tab and the "link" as my tab content.
Let me share my code and I'll explain the problem:
<ul class="nav nav-tabs" id="lb-tabs">
<?php $sqlCat = $db->query('SELECT `tab_title` FROM `category`'); ?>
<?php
foreach ($sqlCat as $row):
echo '<li><a href="#' . $row['tab_title'] . '" data-toggle="tab">' .
$row['tab_title'] . ' </a></li>';
endforeach;
?>
</ul>
<div class="tab-content">
<?php foreach ($sqlCat as $row2):
$tab = $row2['tab_title'];?>
<div class="tab-pane active" id="<?php $row['tab_title']; ?>">
<div class="links">
<ul class="col">
<?php
$items = $db->prepare('SELECT u_links.title, u_links.link, u_links.tid, category.id, category.tab_title
FROM u_links, category
WHERE category.id = u_links.tid
ORDER BY category.id ');
$items->execute();
while ($r = $items->fetch(PDO::FETCH_ASSOC)) {
echo '<li>' . $r['title'] . '</li>';
}
?>
</ul>
</div>
</div><!-- /tab-pane -->
<?php endforeach; ?>
</div>
This current code is not displaying the content in the "tab-content" div. I've tried different ways like this for example:
$tab = '';
$content = '';
$link = '';
$tab_title = null;
while($row = $items->fetch(PDO::FETCH_ASSOC)) {
$link = '<li>' . $row['title'] . '</li>';
if ($tab_title != $row['tab_title']) {
$tab_title = $row['tab_title'];
$tab .= '<li><a href="#' . $row['tab_title'] . '" data-toggle="tab">' .
$row['tab_title'] . ' </a></li>';
$content .= '<div class="tab-pane active" id="' . $row['tab_title'] . '"><div
class="links"><ul class="col">' . $link . '</ul></div></div><!-- /tab-pane //
support -->';
}
}
With this code I either get as too many tabs(as many items within the category) which I only want one tab for many items(links). Or I'll only get one link per section and doesn't output that row from the database.
If anyone can help me out with this, it will be much appreciated! :) Thank you.
Ok, so I think the issue is how you set your .tab-pane id's. Right now there is but no "echo" so nothing is being output there.
I put together a working demo, I did change some part of your code, but very minor stuff which I tried to comment:
<!-- START OF YOUR CODE -->
<ul class="nav nav-tabs" id="lb-tabs">
<?php
// I just made an array with some data, since I don't have your data source
$sqlCat = array(
array('tab_title'=>'Home'),
array('tab_title'=>'Profile'),
array('tab_title'=>'Messages'),
array('tab_title'=>'Settings')
);
//set the current tab to be the first one in the list.... or whatever one you specify
$current_tab = $sqlCat[0]['tab_title'];
?>
<?php
foreach ($sqlCat as $row):
//set the class to "active" for the active tab.
$tab_class = ($row['tab_title']==$current_tab) ? 'active' : '' ;
echo '<li class="'.$tab_class.'"><a href="#' . urlencode($row['tab_title']) . '" data-toggle="tab">' .
$row['tab_title'] . ' </a></li>';
endforeach;
?>
</ul><!-- /nav-tabs -->
<div class="tab-content">
<?php foreach ($sqlCat as $row2):
$tab = $row2['tab_title'];
//set the class to "active" for the active content.
$content_class = ($tab==$current_tab) ? 'active' : '' ;
?>
<div class="tab-pane <?php echo $content_class;?>" id="<?php echo $tab; //-- this right here is from yoru code, but there was no "echo" ?>">
<div class="links">
<ul class="col">
<?php
// Again, I just made an array with some data, since I don't have your data source
$items = array(
array('title'=>'Home','tab_link'=>'http://home.com'),
array('title'=>'Profile','tab_link'=>'http://profile.com'),
array('title'=>'Messages','tab_link'=>'http://messages.com'),
array('title'=>'Settings','tab_link'=>'http://settings.com'),
array('title'=>'Profile','tab_link'=>'http://profile2.com'),
array('title'=>'Profile','tab_link'=>'http://profile3.com'),
);
// you have a while loop here, my array doesn't have a "fetch" method, so I use a foreach loop here
foreach($items as $item) {
//output the links with the title that matches this content's tab.
if($item['title'] == $tab){
echo '<li>' . $item['title'] . ' - '. $item['tab_link'] .'</li>';
}
}
?>
</ul>
</div>
</div><!-- /tab-pane -->
<?php endforeach; ?>
</div><!-- /tab-content -->
<!-- END OF YOUR CODE -->
This help me a lot. I have two static tabs for content creation which drive the dynamic tabs. It is definitely still a little rough but at least the concept is working.
<ul class="nav nav-tabs">
<li class="active">Clusters</li>
<li>Activities</li>
<?php
$sql = "<insert query here>";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
while( $rowtab = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$tab_class = ($rowtab['tab_title']==$current_tab) ? 'active' : '' ;
$nospaces = str_replace(' ', '', $rowtab['tab_title']);
echo '<li class="'.$tab_class.'"><a href="#' . urlencode($nospaces) . '" data-toggle="tab">' .
$rowtab['tab_title'] . '</a></li>';
}
?>
</ul>
<div class="tab-content">
<div class="tab-pane active" id="tab1">
Tab1 Content
</div>
<div class="tab-pane" id="tab2">
Tab2 Content
</div>
<?php
$sql = "<insert query here>";
$stmt = sqlsrv_query( $conn, $sql );
if( $stmt === false) {
die( print_r( sqlsrv_errors(), true) );
}
while( $rowtab = sqlsrv_fetch_array( $stmt, SQLSRV_FETCH_ASSOC) ) {
$tab = $rowtab['tab_title'];
$nospaces = str_replace(' ', '', $rowtab['tab_title']);
$content_class = ($tab==$current_tab) ? 'active' : '' ;
echo '<div class="tab-pane'. $content_class.'" id="'.$nospaces.'">';
echo 'You are looking at the '.$tab.' tab. Dynamic content will go here.';
echo '</div><!-- /.tab-pane -->';
}
?>
</div>
foreach ($files as $file):
$filename = preg_replace("/\.html$/i", "", $file);
$title = preg_replace("/\-/i", " ", $filename);
$documentation = 'usage/'.$type.'/'.$file;
$tab1 = 'usage/'.$type.'/'.$file;
echo '<div class="sg-markup sg-section">';
echo '<div class="sg-display">';
echo '<h2 class="sg-h2"><a id="sg-'.$filename.'" class="sg-anchor">'.$title.'</a></h2>';
//TAb Set up
echo '<div class="row"><div class="col-md-12">';
echo '<ul class="nav nav-tabs" role="tablist">';
echo '<li role="presentation" class="active">Visual</li>';
echo '<li role="presentation">Rules</li>';
echo '</ul>';
echo '</div>';
echo '</div>';
//Visual Tab Content
echo '<div class="row"><div class="col-md-12">';
echo '<div class="tab-content">';
echo '<div role="tabpanel" class="tab-pane active" id="Visual">';
echo '<h3 class="sg-h3">Visual</h3>';
include('markup/'.$type.'/'.$file);
//View Source
echo '<div class="sg-markup-controls"><a class="btn btn-primary sg-btn sg-btn--source" href="#">View Source</a> <a class="sg-btn--top" href="#top">Back to Top</a> </div>';
echo '<div class="sg-source sg-animated">';
echo '<a class="btn btn-default sg-btn sg-btn--select" href="#">Copy Source</a>';
echo '<pre class="prettyprint linenums"><code>';
echo htmlspecialchars(file_get_contents('markup/'.$type.'/'.$file));
echo '</code></pre>';
echo '</div><!--/.sg-source-->';
echo '</div>';
//Documentation Tab Content
if (file_exists($documentation)) {
echo '<div role="tabpanel" class="tab-pane" id="Rules">';
echo '<h3 class="sg-h3">Rules</h3>';
include($documentation);
//View Source
echo '<a class="sg-btn--top" href="#top">Back to Top</a>';
echo '</div>';
}
//Documentation Tab1 Content
echo '<div role="tabpanel" class="tab-pane" id="Tab1">';
echo '<h3 class="sg-h3">Tab1</h3>';
include($tab1);
echo '<a class="sg-btn--top" href="#top">Back to Top</a>';
echo '</div>';
//Documentation Tab2 Content
echo '<div role="tabpanel" class="tab-pane" id="Tab2">';
echo '<h3 class="sg-h3">Tab2</h3>';
// include($tab2);
echo '<a class="sg-btn--top" href="#top">Back to Top</a>';
echo '</div>';
echo '</div>'; //End Tab Content
echo '</div>'; //End Column
echo '</div>'; //End Row
//echo '<div class="row"><div class="col-md-12">';
//echo '<h3 class="sg-h3">Example</h3>';
//include('markup/'.$type.'/'.$file);
//echo '</div>';
// if (file_exists($documentation)) {
// echo '<div class="col-md-12"><div class="well sg-doc">';
// echo '<h3 class="sg-h3">Rules</h3>';
// include($documentation);
// echo '</div></div></div>';
// }
echo '</div><!--/.sg-display-->';
//echo '</div><!--/.colmd10-->';
echo '</div><!--/.sg-section-->';
endforeach;
}
I created a custom menu called "sub-top-nav" and now I'd like to override the html output. In particular I would like to add an unique class to each item like.
This is how it looks atm:
<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
<div class="content">
<ul class="menu">
<li class="leaf first"><a title="Test 1" href="/test1">Test 1</a></li>
<li class="leaf"><a title="Test 2" href="/test2">Test 2</a></li>
<li class="leaf active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
<li class="leaf last"><a title="Test 4" href="/test4">Test 4</a></li>
</ul>
</div>
</div>
And I'd like to change it into:
<div class="clear-block block block-menu" id="block-menu-menu-sub-top-nav">
<div class="content">
<ul class="menu">
<li class="leaf test1 first"><a title="Test 1" href="/test1">Test 1</a></li>
<li class="leaf test2"><a title="Test 2" href="/test2">Test 2</a></li>
<li class="leaf test3 active-trail"><a class="active" title="Test 3" href="/test3">Test 3</a></li>
<li class="leaf test4 last"><a title="Test 4" href="/test4">Test 4</a></li>
</ul>
</div>
</div>
This would give me more styling power.
Any idea how that works?
Thanks in advance!
Drupal 7 uses theme_menu_link instead of theme_menu_item
<?php
function theme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
?>
I got it to work now. This piece of code might help someone else as well!
It goes into yourtheme/template.php
function phptemplate_menu_item($link, $has_children, $menu = '', $in_active_trail = FALSE, $extra_class = NULL) {
$class = ($menu ? 'expanded' : ($has_children ? 'collapsed' : 'leaf'));
if (!empty($extra_class))
$class .= ' '. $extra_class;
if ($in_active_trail)
$class .= ' active-trail';
$class .= ' ' . preg_replace('/[^a-zA-Z0-9]/', '', strtolower(strip_tags($link)));
return '<li class="'. $class .'">'. $link . $menu ."</li>\n";
}
After looking through the API I finally found an easy solution to tag the root menu with the same class (this is useful to style only the top level menus uniquely, while maintaining them dynamically friendly). Simply use the plid instead of mlid. I noticed the plid is always 0 for top level menus.
function theme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$element['#attributes']['class'][] = 'menu-' . $element['#original_link']['plid'];
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
$count = 1;
return '<li' . drupal_attributes($element['#attributes']) . '>' . $output . $sub_menu . "</li>\n";
}
You can use the theme_menu_item function in your theme's template.php to do pretty much whatever you want to those menu items, including adding classes, ID's, etc.
I'm having a bit of trouble trying to get my head around some php code.
To explain:
I have a navbar made from bootstrap.
I want this nav bar to change it's active class depending on the page.
I have a subnav within the navbar with an li class of 'dropdown'.
When this page is active this li class wants to change to 'dropdown active'
When other pages are active, they just want a simple class of 'active'.
My code is as follows:
PHP:
$pageLoc = 'where';
$nav_items = array('index'=>'Home', 'where'=>'Where?', 'appeals'=>'Current Appeals', 'news'=>'Latest News', 'events'=>'Events', 'dontate'=>'Dontate', );
$nav_sub = array('africa'=>'Africa', 'bangladesh'=>'Bangladesh', 'gaza'=>'Palestine/Gaza', 'kashmir'=>'Kashmir', 'pakistan'=>'Pakistan', 'uk'=>'United Kingdom' );
foreach ($nav_items as $nav_href=>$nav_title) {
if ($pageLoc == $nav_href) && ($pageLoc == 'where') {
echo '<li class="dropdown active">' . $nav_title . '</li>';
}
elseif ($pageHref == $nav_href) && ($pageLoc == 'no') {
echo '<li class="dropdown">' . $nav_title . '</li>';
}
elseif ($pageHref == $nav_href) {
echo '<li class="active">' . $nav_title . '</li>';
}
else {
echo '<li>' . $nav_title . '</li>';
}
}
Navbar:
<ul class="nav pull-right">
<li class="pull-right">
<a class="btn-danger" href="donate"><i class="icon-medkit"> DONATE!</i></a>
</li>
</ul>
<ul class="nav pull-right">
<li class="">
Home
</li>
<li class="dropdown">
<a href="../where/" class="dropdown-toggle disabled" data-toggle="dropdown">
Where?
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li class="nav-header">Where we operate</li>
<li class="divider"></li>
<li>Africa</li>
<li>Bangladesh</li>
<li>Palestine/Gaza</li>
<li>Kashmir</li>
<li>Pakistan</li>
</ul>
</li>
<li class="">
Current Appeals
</li>
<li class="">
Latest News
</li>
<li class="">
Events
</li>
</ul>
I am aware that this php is generating a syntax error. I am no pro unfortunately! :( This is
what I originally had:
foreach ($nav_items as $nav_href=>$nav_title) {
if ($pageHref == $nav_href) {
echo '<li class="active">' . $nav_title . '</li>';
}
else {
echo '<li>' . $nav_title . '</li>';
}
}
You've written:
if ($pageLoc == $nav_href) && ($pageLoc == 'where')
It should say:
if ($pageLoc == $nav_href && $pageLoc == 'where')
On a more general note, the absence of detailed debugging information is a pain, but there are workarounds. For example, if you delete half of the code and try to run it again*, does it still give a syntax error? If so, delete a bit more and see what happens; if not, undelete some and see if it works. Keep trying this and narrowing it down until you find where the error is.
*(obviously, don't delete in such a way that you create syntax errors; for example, if you delete the end of an if clause including the }, you'll get non-matching brackets.)