I'm a newbie of Drupal. I'm trying to develop a bootstrap 3 template, but I have a problem with the navbar dropdown menu implementation. I followed these steps:
in my mytheme/templates folder I create a page.tpl.php file with the following code:
if ($page['header'])
...
$main_menu = variable_get('menu_main_links_source', 'main-menu');
$tree = menu_tree($main_menu);
print drupal_render($tree);
...
in mytheme folder I create a template.php file with these functions:
function mytheme_menu_tree($variables) {
return '<ul class="nav navbar-nav">' . $variables['tree'] . '</ul>';
}
function mytheme_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$dropdown = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
$dropdown = 'class="dropdown"';
$element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li ' .$dropdown. ' >' . $output . $sub_menu . "</li>\n";
}
with this code I'm at a good point, but I need to remove classes "nav navbar-nav" from children and add the class "dropdown-menu".
This is the result of my code:
<ul class="nav navbar-nav">
<li>XYZ</li>
<li>ASD</li>
<li class="dropdown">XXX
<ul class="nav navbar-nav">
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
</ul>
and this is what I would like to obtain:
<ul class="nav navbar-nav">
<li>XYZ</li>
<li>ASD</li>
<li class="dropdown">XXX
<ul class="dropdown-menu"> <!-- HERE IS THE DIFFERENCE -->
<li>...</li>
<li>...</li>
<li>...</li>
</ul>
</li>
</ul>
Maybe I can do something like this:
function mytheme_menu_tree($variables) {
if ( [check if I'm at the first level] ) {
return '<ul class="nav navbar-nav">' . $variables['tree'] . '</ul>';
} else {
return '<ul class="dropdown-menu">' . $variables['tree'] . '</ul>';
}
}
but I don't know how... Any idea?
I too am a bit of a newbie when it comes to Drupal and was also having this problem. I have tweaked your function and it works for me:
function SeatradeKorea_menu_link(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$dropdown = '';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
$sub_menu = str_replace('nav navbar-nav', 'dropdown-menu', $sub_menu);
$dropdown = 'class="dropdown"';
$element['#localized_options']['attributes']['class'][] = 'dropdown-toggle';
}
$output = l($element['#title'], $element['#href'], $element['#localized_options']);
return '<li ' .$dropdown. ' >' . $output . $sub_menu . "</li>\n";
}
I have added a str_replace() into your #below element to replace the "nav navbar-nav" with "dropdown-menu"
Related
im generating a bootstrap navbar using codeigniter, its working fine but i want the admin link to be aligned to the right. here is my code:
function get_menu ($array, $child = FALSE)
{
$CI =& get_instance();
$str = '';
if (count($array)) {
$str .= $child == FALSE ? '<ul class="nav navbar-left navbar-custom">' . PHP_EOL : '</ul>' . PHP_EOL;
foreach ($array as $item) {
$active = $CI->uri->segment(1) == $item['slug'] ? TRUE : FALSE;
if (isset($item['children']) && count($item['children'])) {
$str .= $active ? '<li class="dropdown active">' : '<li class="dropdown">';
$str .= '<a class="dropdown-toggle" data-toggle="dropdown" href="' . site_url(e($item['slug'])) . '">' . e($item['title']);
$str .= '<b class="caret"></b></a>' . PHP_EOL;
$str .= get_menu($item['children'], TRUE);
}
else {
$str .= $active ? '<li class="active">' : '<li>';
$str .= '' . e($item['title']) . '';
}
// Closing tags
$str .= '</li>' ;
}
//add dashboard link to the right of menu for login
$str .= '<li>' . '<p class="navbar-text navbar-right"><a
`href="admin/dashboard" class="navbar-link"> ADMIN</a></p></li>' . PHP_EOL;
$str .= '</ul>' . PHP_EOL;
}
im getting a navbar with required links but its all inline. any help is aappreciated. Cheers
This is because of where you are adding the navbar-right class. You have to add it to an ul element. Change your second to last string:
$str .= '<li>' . '<p class="navbar-text navbar-right"><a `href="admin/dashboard" class="navbar-link"> ADMIN</a></p></li>' . PHP_EOL;
To something along these lines:
<ul class="nav navbar-nav navbar-right">
<li> ADMIN</li>
</ul>
And do not add it inside of your current ul element, that will also not work; you need to close the navbar-left class then add the navbar-right.
Looking something like this:
UPDATE
I think I got it, you do not have the nav element around your navbar, and that is probably what is causing the issues with alignments...
<?php
function get_menu ($array, $child = FALSE)
{
$CI =& get_instance();
$str = '';
if (count($array)) {
$str .= $child == FALSE ? '<nav class="navbar navbar-default"> <ul class="nav navbar-nav navbar-custom">' . PHP_EOL; // create the <nav> element
foreach ($array as $item) {
$active = $CI->uri->segment(1) == $item['slug'] ? TRUE : FALSE;
if (isset($item['children']) && count($item['children'])) {
$str .= $active ? '<li class="dropdown active">' : '<li class="dropdown">';
$str .= '<a class="dropdown-toggle" data-toggle="dropdown" href="' . site_url(e($item['slug'])) . '">' . e($item['title']);
$str .= '<b class="caret"></b></a>' . PHP_EOL;
$str .= get_menu($item['children'], TRUE);
}
else {
$str .= $active ? '<li class="active">' : '<li>';
$str .= '' . e($item['title']) . '';
}
// Closing tags
$str .= '</li>' ;
}
$str .= '</ul>' . PHP_EOL;
//add dashboard link to the right of menu for login
$str .= '<ul class="nav navbar-nav navbar-right">
<li> ADMIN</li>
</ul>' . PHP_EOL;
// add the nav closing tag
$str .= '</nav>' . PHP_EOL;
}
?>
i have a folder 'server' and inside of server i have anothers folders 'computer1' and 'computer2' and inside of computer1 i have more folder and inside of computer2 i have more folders too
So i have a sidebar and until now i put this to show the computer1 and computer2
<ul class="nav side-menu">
<?php
foreach (glob('server/sandro/*', GLOB_ONLYDIR)as$subfolder) {
echo '<li><a><i class="fa fa-home"></i>'. basename($subfolder) .'<span class="fa fa-chevron-down"></span></a>';
echo '<ul class="nav child_menu">';
echo '</ul>';
echo '</li>';
}
?>
</ul>
and well..it's result, but now i want to add inside of
echo '<ul class="nav child_menu">';
echo '</ul>';
the rest of subfolders that are inside of the computer1 and computer2
please, help-me.
Hi you have to use function and call function in itself
<ul class="nav side-menu">
<?php
function foldersList($folderName = NULL) {
$return = '';
foreach (glob('./server/sandro/' . $folderName . '*', GLOB_ONLYDIR) as $subfolder) {
// call function to check subfolders - don't forget write `/`
$subFolders = foldersList(basename($subfolder). '/');
$return .= '<li><a><i class="fa fa-home"></i>' . basename($subfolder) . '<span class="fa fa-chevron-down"></span></a>';
$return .= '<ul class="nav child_menu">';
// if subfolder exist add to return variable
$return .= $subFolders != '' ? $subFolders : '';
$return .= '</ul>';
$return .= '</li>';
}
return $return;
}
echo foldersList();
?>
</ul>
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 am using Joomla 1.5 and have copied the mod_mainmenu to create a custom menu module. The menu has submenu items (inner UL tags). Here the menu's HTML:
<ul id="sub-menu">
<li class="parent item10"><span>Arts</span>
<ul>
<li class="item29">
<span>Arts Show</span></li>
<li class="item29">
<span>Another Arts Show</span></li>
</ul>
</li>
<li class="parent item15"><span>News</span>
<ul>
<li class="item18">
<span>News Show</span></li>
</ul>
</li>
</ul>
I need to take the above HTML and rewrite it to look like this before it reaches the page:
<div id="sub-menu">
<h3 class="parent item10"><span>Arts</span></h3>
<div>
<a class="item29" href="link2.php"><span>Arts Show</span></a><br />
<a class="item29" href="link3.php"><span>Another Arts Show</span></a>
</div>
<h3 class="parent item15"><span>News</span></h3>
<div>
<a class="item18" href="link7.php"><span>News Show</span></a>
</div>
</div>
How do you do this in PHP? Thanks.
Since jQuery UI Accordion don't handle nested list, you can use other jquery plugins that does (giyf).
If you want to modify html output from your duplicated mod_mainmenu, then simply locate/modify corresponding code (it should be in a view since joomla use mvc).
PHP has a Document Object Model class which can be used for this purpose.
However it would be a whole lot easier to just change the template that drives the output in Joomla and make the change at its source.
Here's a full script to do the job. It's in pure php.
<?php
$dataStr = '<ul id="sub-menu">
<li class="parent item10"><span>Arts</span>
<ul>
<li class="item29">
<span>Arts Show</span></li>
<li class="item29">
<span>Another Arts Show</span></li>
</ul>
</li>
<li class="parent item15"><span>News</span>
<ul>
<li class="item18">
<span>News Show</span></li>
</ul>
</li>
</ul>';
$tempStr = str_replace('<ul ','<div ',$dataStr);
$dataStr = str_replace('<li class="parent','<h3 class="parent ',$tempStr);
$tempStr = str_replace('<ul>','<div>',$dataStr);
$dataStr = str_replace('</ul>','</div>',$tempStr);
$tempStr = str_replace('</li>','',$dataStr);
$dataStr = str_replace('><a ','><a_keep ',$tempStr);
$tempStr = str_replace('<a ','',$dataStr);
$dataStr = str_replace('<li ','<a ',$tempStr);
$tempStr = str_replace('><a_keep ','><a ',$dataStr);
$dataStr = $tempStr;
$newDataStr = "";
$startIndex = 0;
$endIndex = strpos($dataStr, "\n", $startIndex);
$trimNextLine = false;
while (1==1){
if($endIndex == false){
break;
}
$currentLine = substr($dataStr,$startIndex,$endIndex-$startIndex);
$trimCurrentLine = ltrim($currentLine);
$subStrCurrentLine = substr($trimCurrentLine,0,5);
if($subStrCurrentLine==""){
;//do nothing
}
else if($subStrCurrentLine=="<h3 c"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString . "</h3>\n";
}
else if($subStrCurrentLine=="<a cl"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)-1));
$newDataStr = $newDataStr . $tempString;
$trimNextLine = true;
}
else if($subStrCurrentLine=="<div>"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString."\n";
$trimNextLine = true;
}
else if($subStrCurrentLine=="</div"){
$tempString = ' '.ltrim(substr($currentLine,0,strlen($currentLine)));
$newDataStr = $newDataStr . $tempString."\n";
$trimNextLine = true;
}
else{
if ($trimNextLine == true){
$trimNextLine = false;
$nextStartIndex = $endIndex+1;
$nextEndIndex = strpos($dataStr, "\n", $nextStartIndex);
$nextLine = substr($dataStr,$nextStartIndex,$nextEndIndex-$nextStartIndex);
$trimNextLine = ltrim($nextLine);
$subStrNextLine = substr($trimNextLine,0,5);
if($subStrNextLine=="<a cl"){
$newDataStr = $newDataStr . ' ' . ltrim($currentLine)."<br />\n";
}
else{
$newDataStr = $newDataStr . ' ' . ltrim($currentLine)."\n";
}
}
else{
$newDataStr = $newDataStr . $currentLine."\n";
}
}
$startIndex = $endIndex+1;
$endIndex = strpos($dataStr, "\n", $startIndex);
}
$tempString = substr($dataStr,$startIndex,strlen($dataStr)-$startIndex);
$newDataStr = $newDataStr . $tempString . "\n";
echo($newDataStr);
?>
I have this issue with OpenCart where I want to display my shop categories in a custom way and count the parent categories.
I currently modified the code so far that I get the following output
<ul id="catOpContainer">
<li id="switchCatOp1">Parent Cat 1
<ul id="catOp1">
<li>Child cat 1</li>
Child Cat 2</li>
</ul>
</li>
Parent Cat 2
<ul id="catOp1">
<li>Child cat 1</li>
Child cat 2</li>
</ul>
</li>
Parent Cat 3</li>
</ul>
</ul>
instead of the desired
<ul id="catOpContainer">
<li id="switchCatOp1">Parent Cat 1
<ul id="catOp1">
<li>Child Cat 1</li>
<li>Child Cat 2</li>
</ul>
</li>
<li id="switchCatOp2">Parent Cat 2
<ul id="catOp2">
<li>Child Cat 1</li>
<li>Child Cat 2</li>
<li>Child Cat 3</li>
</ul>
</li>
</ul>
It's obvious that there are some missing elements, but I have no clue about a possible solution. I also don't have a clue how to count the parent categories, so that I can toggle the subcategories.
I currently have the following code snippet:
<?php
class ControllerModuleCategory extends Controller {
protected $category_id = 0;
protected $path = array();
protected function index() {
$this->language->load('module/category');
$this->data['heading_title'] = $this->language->get('heading_title');
$this->load->model('catalog/category');
$this->load->model('tool/seo_url');
if (isset($this->request->get['path'])) {
$this->path = explode('_', $this->request->get['path']);
$this->category_id = end($this->path);
}
$this->data['category'] = $this->getCategories(0);
$this->id = 'category';
if (file_exists(DIR_TEMPLATE . $this->config->get('config_template') . '/template/module/category.tpl')) {
$this->template = $this->config->get('config_template') . '/template/module/category.tpl';
} else {
$this->template = 'default/template/module/category.tpl';
}
$this->render();
}
protected function getCategories($parent_id, $current_path = '') {
$category_id = array_shift($this->path);
$output = '';
$results = $this->model_catalog_category->getCategories($parent_id);
if ($results) {
if ($parent_id == 0) {
$output .= '<li id="switchCatOp1">';
} else {
$output .= '<ul id="catOp1"><li>';
}
}
foreach ($results as $result) {
if (!$current_path) {
$new_path = $result['category_id'];
} else {
$new_path = $current_path . '_' . $result['category_id'];
}
$output .= '';
$children = '';
// if ($category_id == $result['category_id']) {
$children = $this->getCategories($result['category_id'], $new_path);
// }
if ($this->category_id == $result['category_id']) {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>';
} else {
$output .= '<a href="' . $this->model_tool_seo_url->rewrite(HTTP_SERVER . 'index.php?route=product/category&path=' . $new_path) . '">' . $result['name'] . '</a>';
}
$output .= $children;
$output .= '</li>';
}
if ($results) {
$output .= '</ul>';
}
return $output;
}
}
?>
I really hope someone knows a solution.
You do not need to customize controller. It has already Parent and child category listing, Just open the category module, and past below code.
<div class="box-category">
<ul>
<?php foreach ($categories as $category) { ?>
<li>
<?php if ($category['category_id'] == $category_id) { ?>
<?php echo $category['name']; ?>
<?php } else { ?>
<?php echo $category['name']; ?>
<?php } ?>
<?php if ($category['children']) { ?>
<ul>
<?php foreach ($category['children'] as $child) { ?>
<li>
<?php if ($child['category_id'] == $child_id) { ?>
<?php echo $child['name']; ?>
<?php } else { ?>
<?php echo $child['name']; ?>
<?php } ?>
</li>
<?php } ?>
</ul>
<?php } ?>
</li>
<?php } ?>
</ul>
</div>