I'm not sure where I'm going wrong, but I'm trying to make the slash only appear on the first drop down level of a menu. I'm doing this in php.
Here is my code
function appendMainNav($subid){
global $_PAGES_TABLE, $_HTTP_ADDRESS;
$subWrapper='';
$subClass='';
$mainClass='mega-nav-wrapper overlay-bg';
if($this->hasParentMenu($subid) > 0){
$subWrapper = 'sub-nav-main-wrapper';
$subClass='sub-nav-wrapper';
$mainClass='';
}
$p=1;
$str = "";
$str.= '<div class="'.$subWrapper.'">';
$str.=' <ul class="'.$mainClass.''.$subClass.'">';
$query = mysql_query("SELECT * FROM $_PAGES_TABLE P WHERE P.parent='".$subid."' AND P.show='1' AND P.active='1' ORDER BY num");
while( $result = mysql_fetch_object($query) ){
$page = new Page($result->id);
$page->setFromDatabase();
$lastClass='';
if(($page->linkto != '0' && $page->linkto != 0 && $page->linkto != '') || $page->linkto == '#'){
$linkto = $page->linkto;
}else{
$linkto = $page->id;
}
$appendArrow='';
$arrowSelect = "";
$slash =' ';
if($this->hasChildrenMenu($page->id) > 0){
$slash = ' /';
}
$str .='<li class="subnav_item'.$lastClass.'"><a class="'.$appendArrow.'" href="'.getSEOLink($linkto).'">'.$page->{'title'.$langVar}.''.$slash.'</a>';
//$str.='<li><span>/</span></li>';
if($this->hasChildrenMenu($page->id) > 0){
$str.= $this->appendMainNav($page->id);
}
$str.='</li>';
$p++;
}
$str.=' </ul>';
$str.='</div>';
return $str;
At the moment it only appears on the sub menu item that has a drop drop down as well. The second drop down mustn't have anything.
My menu looks like this
menu 1 menu 2 / menu 3
submenu 1
submenu 2
submenu 3
and this is how I want it to look
menu 1 / menu 2 / menu 3 /
submenu 1
submenu 2
submenu 3
An easy solution would be to add a flag to the function and change the conditional:
function appendMainNav($subid, $noSlash = false){
...
if(!$noSlash){
$slash = ' /';
}
...
if($this->hasChildrenMenu($page->id) > 0){
$str.= $this->appendMainNav($page->id, true);
}
...
Related
I got a simple sidemenu that is displayed using a foreach:
<?
if($contentcr[0]['catid'] == '9'){
foreach($pagecr as $page){
$landingnospace = str_replace(' ', '_', $page['alias']);
$title = $page['title'];
if($title != '') {
$contentje .= '<li>'.$title.'</li>';
}
}
echo $contentje;
}
else{
echo 'Alternatief sidemenu';
}
?>
The alias of the page is displayed in the url using .htaccess:
DirectoryIndex
RewriteEngine on
RewriteBase /_extern/website1/
#Indexes uitzetten
Options -Indexes
#Website1
RewriteRule ^(.*).html content.php?alias=$1 [L]
I am currently using two queries on the page, one for db_content and one for db_categories
db_content:
// content
$content = "SELECT * FROM `db_content` WHERE alias = '".$_GET['alias']."' ";
$contentcon = $conn->query($content);
$contentcr = array();
while ($contentcr[] = $contentcon->fetch_array());
db_categories
// Pages
$page = "SELECT con.title, con.alias, con.images, con.introtext
FROM db_content con
LEFT JOIN db_categories cat ON con.catid = cat.id
AND cat.alias = '".$_GET['alias']."' WHERE con.state = 1 ORDER BY `ordering` DESC";
$pagecon = $conn->query($page);
$pagecr = array();
while ($pagecr[] = $pagecon->fetch_array());
So how can I compare the results in the foreach to the alias in the url, and if they match add the class: current-menu-item to the list tag?
You could introduce a $class variable and see if the current $page["alias"] equals the $_GET["alias"]. If so, apply the class current-menu-item, if not, leave it blank.
<?
if($contentcr[0]['catid'] == '9'){
$alias = $_GET["alias"];
foreach($pagecr as $page){
$landingnospace = str_replace(' ', '_', $page['alias']);
$title = $page['title'];
if($title != '') {
// magic happens here
$class = ($page["alias"] == $alias)?"current-menu-item":"";
$contentje .= '<li><a class="'.$class.'" href="http://www.website.nl/_extern/website1/'.$landingnospace.'.html">'.$title.'</a></li>';
}
}
echo $contentje;
}
else{
echo 'Alternatief sidemenu';
}
?>
Thanks to all of you I have been able to create a variable: $mytitle from the active parent menu item in Joomla 3.
This is my code:
$menu = JFactory::getApplication()->getMenu();
$parent = $menu->getItem( $menu->getActive()->parent_id );
$parentname = $parent->title;
$parentlink = JRoute::_( $parent->link . '&Itemid=' . $parent->id );
$menulevel = $menu->getActive()->level; $activename= $menu->getActive()->title;
$mytitle = ($menulevel == 1)?$activename:$parentname;
echo $mytitle;
This works great but now I need to use it on my submenu item (VMenuBlock). The code is as follows and I cannot seem to figure out how to place the variable so that it works?
function modChrome_vmenu($module, &$params, &$attribs)
{
if (!empty ($module->content)) {
if (function_exists('VMenuBlock'))
echo VMenuBlock(($module->showtitle != 0) ? $module->title : '', $module->content,
$params->get('moduleclass_sfx'));
else
echo Block(($module->showtitle != 0) ? $module->title : '', $module->content,
$params->get('moduleclass_sfx'));
}
}
Any help is appreciated!,
Thanks!
Doug
I'm trying to create a complex sidebar navigation system that remains the same depending on what top-level page you're viewing. For example, say I have this navigation:
Home
About
Our Company
Location
Hours
Our PeopleJim
Dave
Sarah
Kelly
PortfolioLogos
Websites
Contact
Now, if the user was anywhere within the About section, I'd want the sidebar to display:
About
Our Company
Location
Hours
Our PeopleJim
Dave
Sarah
Kelly
That goes for if they're in the main About page, in the Our Company page, or in the Location page. I need the whole navigation visible regardless of depth.
If the user was in a page with no sub-items, such as Contact, the sidebar needs to show:
Home
About
Portfolio
Contact
What's more, the ordering needs to be based on a WordPress Menu (one main menu, each sidebar can't be it's own; that's too complicated for the user). I don't know if that complicates things or not.
In the past, I've managed to get something to display children and sibling pages, but it doesn't display parent pages, and doesn't display in the order that the user defines.
<ul>
<?
global $wp_query;
if( empty($wp_query->post->post_parent) ) {
$parent = $wp_query->post->ID;
}
else {
$parent = $wp_query->post->post_parent;
}
wp_list_pages ("&title_li=&child_of=$parent");
?>
</ul>
If this can be modified to work the way I want it, that'd be great. I'm going to try and figure this out on my own, and will post updates as I make progress.
UPDATE 1: I've made a bit of progress determining what the absolute parent is. I think I'm on the right track.
<?
if ($post->post_parent) {
$ancestors = get_post_ancestors($post->ID);
$root = count($ancestors)-1;
$parent = $ancestors[$root];
} else {
$parent = $post->ID;
}
echo "Current Page: " . $post->ID . "<br />";
echo "Top Level Parent: " . $parent;
?>
UPDATE 2: I can now determine the correct page ID to query for a menu, so I think I'm getting close.
<?
$children = get_pages("child_of=".$post->ID);
if ($post->post_parent) {
$ancestors = get_post_ancestors($post->ID);
$root = count($ancestors)-1;
$parent = $ancestors[$root];
} elseif (count($children) != 0) {
$parent = $post->ID;
} else {
$parent = 0;
}
echo "Current Page: " . $post->ID . "<br />";
echo "Top Level Parent: " . $parent;
?>
UPDATE 3: I'm nearly there! The only problem is this uses the page's order from the editor, not from the menu. Is it possible to edit this to work with a menu instead?
<aside>
<?
$children = get_pages("child_of=".$post->ID);
if ($post->post_parent) {
$ancestors = get_post_ancestors($post->ID);
$root = count($ancestors)-1;
$parent = $ancestors[$root];
$sidebarDepth = 0;
$postParentID = get_post($parent);
$title = $postParentID->post_title;
} elseif (count($children) != 0) {
$parent = $post->ID;
$sidebarDepth = 0;
$postParentID = get_post($parent);
$title = $postParentID->post_title;
} else {
$parent = 0;
$sidebarDepth = 1;
$frontPageID = get_option("page_on_front");
$exclude = $frontPageID;
$postParentID = get_post($frontPageID);
$title = $postParentID->post_title;
}
?>
<header>
<h6><? echo $title ?> »</h6>
</header>
<section>
<nav>
<?
echo "<ul>";
wp_list_pages("child_of=" . $parent . "&depth=" . $sidebarDepth . "&exclude=" . $exclude . "&title_li=&");
echo "</ul>";
?>
</nav>
</section>
</aside>
Figured it out! I modified the code from this answer to add a start_in option to wp_nav_menu, and modified my code from there. Now this works exactly as I wanted it.
In functions.php:
// add start_in argument to navigation
add_filter("wp_nav_menu_objects",'my_wp_nav_menu_objects_start_in',10,2);
function my_wp_nav_menu_objects_start_in( $sorted_menu_items, $args ) {
if (isset($args->start_in) && $args->start_in != 0) {
$menu_item_parents = array();
foreach ($sorted_menu_items as $key => $item) {
if ($item->object_id == (int)$args->start_in) $menu_item_parents[] = $item->ID;
if (in_array($item->menu_item_parent, $menu_item_parents)) {
$menu_item_parents[] = $item->ID;
} else {
unset($sorted_menu_items[$key]);
}
}
return $sorted_menu_items;
} else {
return $sorted_menu_items;
}
}
In page.php (or whatever template you want):
<aside>
<?
if ($post->post_parent) {
$ancestors = get_post_ancestors($post->ID);
$root = count($ancestors)-1;
$parent = $ancestors[$root];
} elseif (count(get_pages("child_of=".$post->ID)) != 0) {
$parent = $post->ID;
} else {
$parent = get_option("page_on_front");
$sidebarDepth = 1;
$exclude = $parent;
}
if ($post->post_parent || count(get_pages("child_of=".$post->ID)) != 0) {
$sidebarDepth = 0;
$start_in = $parent;
$depth = 0;
} else {
$depth = 1;
$start_in = 0;
}
$parentID = get_post($parent);
$parentTitle = $parentID->post_title;
$parentURL = get_permalink($parentID);
?>
<header>
<h6><? echo $parentTitle ?> »</h6>
</header>
<section>
<nav>
<?
wp_nav_menu(
array(
"container" => false,
"depth" => $depth,
"items_wrap" => '<ul>%3$s</ul>',
"start_in" => $start_in,
"theme_location" => "first"
)
);
?>
</nav>
</section>
</aside>
I want to create my dropdown menu from a mysql query, but i'm having trouble with the sub-items.
My basic table:
NavigationID ParentID Name Url
1 1 Home home
2 2 About about
3 3 Products products
4 3 Category1 #
5 3 Category2 #
6 4 Product1 #
7 5 Product2 #
My simple MySQL Query and adding to array:
class Navigation{
private $data;
public function __construct($par){
if(is_array($par))
$this->data = $par;
}
public function __toString(){
return '<li>'.$this->data['Name'].'</li>';
}
}
$query = mysql_query("SELECT * FROM Navigation n") or die(mysql_error());
$num = mysql_num_rows($query);
$menuitems = array();
while($row = mysql_fetch_assoc($query)){
$menuitems[] = new Navigation($row);
}
echo '<div id="nav"><ul>';
foreach($menuitems as $item){
echo $item;
}
echo '</ul></div>';
The result of this is:
<div id="nav"><ul>
<li>Home</li>
<li>About</li>
<li>Products</li>
<li>Category1</li>
<li>Category2</li>
<li>Product1</li>
<li>Product2</li>
</ul></div>
But what I would REALLY like is this:
<div id="nav"><ul>
<li>Home</li>
<li>About</li>
<li>Products
<ul>
<li>Category1
<ul>
<li>Product1</li>
</ul>
</li>
<li>Category2
<ul>
<li>Product2</li>
</ul>
</li>
</ul>
</li>
</ul></div>
How can I achieve this result? I've tried many other examples, but none seems to help me. Maybe I'm not searching for the right thing.
Why to make it complicated, this could be done with a very simple recursive function.
This is what I did in my local machine. I have the connection parameter and then called a function
bulit_tree(0);
In this function it will check if the argument is 0 then select all
the item where id and parentid is same.
Then loop through and use the recursive function and generate sub tree.
Need to make sure that the $con is accesible within the function.
$con = mysql_connect("localhost","testuser","testpass");
$db_selected = mysql_select_db('testdb', $con);
if (!$db_selected) {
die ('Can\'t use testdb : ' . mysql_error());
}
bulit_tree(0);
function bulit_tree($pid=0){
global $con ;
if($pid == 0 ){
$qry = "select * from Navigation where NavigationID = ParentID";
$q = mysql_query($qry,$con);
if(mysql_num_rows($q) > 0 ){
echo '<ul>';
while($row = mysql_fetch_assoc($q)){
echo '<li>'.$row["Name"].'';
bulit_tree($row["NavigationID"]);
echo '</li>';
}
echo '</ul>';
}
}else{
$qry = "select * from Navigation where ParentID = ".$pid." AND NavigationID <> ".$pid;
$q = mysql_query($qry,$con);
if(mysql_num_rows($q) > 0 ){
echo '<ul>';
while($row = mysql_fetch_assoc($q)){
echo '<li>'.$row["Name"].'';
bulit_tree($row["NavigationID"]);
echo '</li>';
}
echo '</ul>';
}
}
}
You might need to restructure your DB first. Consider a join table. This comes handy especially if your Product falls into multiple categories.
Master table:
NavigationID Name Url
1 Home home
2 About about
3 Products products
4 Category1 #
5 Category2 #
6 Product1 #
7 Product2 #
Lookup Table:
NavigationID ParentId
1 1
2 2
3 3
4 3
5 3
6 4
7 5
Then in your class, you can make it structured like:
<?php
class Navigation{
private $menuitems;
public function __construct($par){
if(is_array($par))
$this->menuitems = $par;
}
public function __toString() {
$this->printNavigation($this->menuitems);
}
private function printMenuItem($menu) {
echo '<li>'.$menu->name.'';
if(count($menu->children)) {
print printNavigation($menu->children);
}
'</li>';
}
private function printNavigation($menuItems) {
echo "<ul>";
foreach ($menuitems as $menu {
$this->printMenuItem($menu);
}
echo "</ul>";
}
}
class MenuItem{
private $url;
private $name;
private $children;
public function __construct($par){
if(is_array($par)) {
$this->url = $par['url'];
$this->$name = $par['name'];
$this->children = $this->fetchChildren($par['NavigationID']);
}
}
function fetchChildren($id) {
$query = mysql_query("SELECT * from navigation n INNER JOIN Lookup l on l.parentID = n.NavigationID
WHERE n.NavigationID = $id") or die(mysql_error());
$num = mysql_num_rows($query);
if($num > 0) {
while($row = mysql_fetch_assoc($query)){
$this->children[] = new MenuItem($row);
}
}
}
}
$query = mysql_query("SELECT * from navigation n INNER JOIN Lookup l on l.NavigationID = n.NavigationID
WHERE l.NavigationID = l.parentIDn
AND l.NavigationID != n.NavigationID") or die(mysql_error());
$num = mysql_num_rows($query);
$menuitems = array();
while($row = mysql_fetch_assoc($query)){
$menuitems[] = new MenuItem($row);
}
$navigation = new Navigation($menuitems);
echo "<div id='nav'>$navigation</div>";
Thanx for all the comments. I've gone with Agha's suggestion of using a recursive function.
http://crisp.tweakblogs.net/blog/317/formatting-a-multi-level-menu-using-only-one-query.html
I am having a problem with making the links in my bar work properly the database is setup like so my db http://bloodkittens.com/resources/upload/db.png
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
mysql_connect("localhost", "dbuser", "******");
mysql_select_db("guild");
// prepare special array with parent-child relations
$menuData = array(
'items' => array(),
'parents' => array()
);
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name FROM main_menu` ORDER BY parentID_menu");
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
}
// menu builder function, parentId 0 is the root
function buildMenu($parentId, $menuData)
{
$html = '';
$parent='';
if (isset($menuData['parents'][$parentId]))
{
$menuClass= ($parentId==0) ? ' class="navbar" id="navbar"' : '';
$parent= ($parentId==0) ? 0 : 1;
$html = "<ul{$menuClass}>\n";
foreach ($menuData['parents'][$parentId] as $itemId)
{
//subment
$result=mysql_query("select * from main_menu where parentID_menu='$itemId'");
if (mysql_num_rows($result)>(int)0 && $parentId!=0) {
$subm =' class="navbar"';
}else{
$subm ='';
}
//end
$menu = $parentId == 0 ? ' class="menulink"' : ''; //class of main menu
$html .= '<li>' . "<a{$subm}{$menu} href=\"#\" >{$menuData['items'][$itemId]['name']}</a>";
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
?>
How would i make it so that the value link_menu would be the href in the code for each separate entry in the db? rather then \'#\' because the code works completely and i'm very happy how it looks after i apply my css to it but the links aren't working
For work the menu sorting
must be add a new field in the table,
and change this query from
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY parentID_menu");
to :
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY menu_sort");
you never seem to select it
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu, link_menu, name FROM main_menu ORDER BY parentID_menu");
and then..
$html .= '<li>' . "<a{$subm}{$menu} href=\"{$menuData['items'][$itemId]['link_menu']}\" >{$menuData['items'][$itemId]['name']}</a>";
Instead of href=\"#\" >, use this:
href=\"{$menuData['items'][$itemId]['link_menu']}\" >
the code that i used was in the end like this i think i got it to work by pure luck but regardless i win : )
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
mysql_connect("localhost", "BloodKittens", "Zangoshi1");
mysql_select_db("bloodkittens");
// prepare special array with parent-child relations
$menuData = array(
'items' => array(),
'parents' => array(),
'links' => array()
);
$result = mysql_query("SELECT id_menu id, parentID_menu parentId, label_menu name, link_menu link FROM main_menu ORDER BY parentID_menu");
while ($menuItem = mysql_fetch_assoc($result))
{
$menuData['items'][$menuItem['id']] = $menuItem;
$menuData['parents'][$menuItem['parentId']][] = $menuItem['id'];
$menuData['links'] = $menuItem['link'];
}
// menu builder function, parentId 0 is the root
function buildMenu($parentId, $menuData)
{
$html = '';
$parent='';
if (isset($menuData['parents'][$parentId]))
{
$menuClass= ($parentId==0) ? ' class="navbar" id="navbar"' : '';
$parent= ($parentId==0) ? 0 : 1;
$html = "<ul{$menuClass}>\n";
foreach ($menuData['parents'][$parentId] as $itemId)
{
//subment
$result=mysql_query("select * from main_menu where parentID_menu='$itemId'");
if (mysql_num_rows($result)>(int)0 && $parentId!=0) {
$subm =' class="navbar"';
}else{
$subm ='';
}
//end
$menu = $parentId == 0 ? ' class="menulink"' : ''; //class of main menu
$html .= '<li>' . "<a{$subm}{$menu} href=\"{$menuData['items'][$itemId]['link']}\" >{$menuData['items'][$itemId]['name']}</a>";
// find childitems recursively
$html .= buildMenu($itemId, $menuData);
$html .= '</li>';
}
$html .= '</ul>';
}
return $html;
}
// output the menu
echo buildMenu(0, $menuData);
?>