I am using the core book module and have exactly one book. I would like to show a block containing the book navigation (or table of contents) open to the current page/node I'm on. The problem is that the default Book navigation block behaves like I'd want but shows the book name as the first entry and first level chapters under that (and collapsed if using DHTML Menu). I would much rather have the first level chapters as the primary entries and I'll use the book title as the block title.
I've used this piece of code as a block; it does the exact same thing as the default book navigation block.
<?php $book_top_page=168; $tree = menu_tree_all_data(book_menu_name($book_top_page)); print menu_tree_output($tree); ?>
The following code below shows exactly what I need but does NOT open to the current page. (code snippet found on d.o)
Are there any modules or code snippets that can do this? Any suggestions how I can modify the code below to open the item/page based on the current node? (such as adding active-trail class where necessary) Thanks.
- John
<?php $book_top_page = 168; $levels_deep = 3; $emulate_book_block = true;
if (!function_exists('book_struct_recurse')){ function book_struct_recurse($nid, $levels_deep, $children, $current_lineage = array(), $emulate_book_block = true) { $struct = ''; if ($children[$nid] && ($levels_deep > 0 || ($emulate_book_block && in_array($nid, $current_lineage)))) { $struct = '<ul>'; foreach ($children[$nid] as $key => $node) { if ($tree = book_struct_recurse($node->nid, $levels_deep - 1, $children, $current_lineage, $emulate_book_block)) { $struct .= '<li>'; $struct .= l($node->title, 'node/'. $node->nid); $struct .= $tree; $struct .= '</li>'; } else { if ($children[$node->nid]){ $struct .= '<li>'. l($node->title, 'node/'. $node->nid) .'</li>'; } else { $struct .= '<li>'. l($node->title, 'node/'. $node->nid) .'</li>'; } } } $struct .= '</ul>'; return $struct; } } }
$current_lineage = array();
$result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n2.nid parent, ml.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid INNER JOIN {menu_links} ml ON b.mlid = ml.mlid INNER JOIN {book} b2 on b2.mlid = ml.plid INNER JOIN {node} n2 on b2.nid = n2.nid WHERE n.status =1 ORDER BY ml.weight, n.title'));
while ($node = db_fetch_object($result)) { if (!$children[$node->parent]) { $children[$node->parent] = array(); } array_push($children[$node->parent], $node);
/* This function is broken, and for my purposes, not needed ********** if (arg(0) == 'node' && is_numeric(arg(1)) && arg(1) == $node->nid) { $_temp = book_location($node); foreach ($_temp as $key => $val){ $current_lineage[] = $val->nid; } $current_lineage[] = arg(1); } */ }
echo book_struct_recurse($book_top_page, $levels_deep, $children, $current_lineage, $emulate_book_block);
?>
Figures. You work on a problem for most of the afternoon with no success, send a request for help to thousands of people on the support list, then you solve your own problem 20 minutes later!
http://drupal.org/project/menu_block does the trick.
- John
John Callahan wrote:
I am using the core book module and have exactly one book. I would like to show a block containing the book navigation (or table of contents) open to the current page/node I'm on. The problem is that the default Book navigation block behaves like I'd want but shows the book name as the first entry and first level chapters under that (and collapsed if using DHTML Menu). I would much rather have the first level chapters as the primary entries and I'll use the book title as the block title.
I've used this piece of code as a block; it does the exact same thing as the default book navigation block.
<?php $book_top_page=168; $tree = menu_tree_all_data(book_menu_name($book_top_page)); print menu_tree_output($tree); ?>
The following code below shows exactly what I need but does NOT open to the current page. (code snippet found on d.o)
Are there any modules or code snippets that can do this? Any suggestions how I can modify the code below to open the item/page based on the current node? (such as adding active-trail class where necessary) Thanks.
- John
<?php $book_top_page = 168; $levels_deep = 3; $emulate_book_block = true; if (!function_exists('book_struct_recurse')){ function book_struct_recurse($nid, $levels_deep, $children, $current_lineage = array(), $emulate_book_block = true) { $struct = ''; if ($children[$nid] && ($levels_deep > 0 || ($emulate_book_block && in_array($nid, $current_lineage)))) { $struct = '<ul>'; foreach ($children[$nid] as $key => $node) { if ($tree = book_struct_recurse($node->nid, $levels_deep - 1, $children, $current_lineage, $emulate_book_block)) { $struct .= '<li>'; $struct .= l($node->title, 'node/'. $node->nid); $struct .= $tree; $struct .= '</li>'; } else { if ($children[$node->nid]){ $struct .= '<li>'. l($node->title, 'node/'. $node->nid) .'</li>'; } else { $struct .= '<li>'. l($node->title, 'node/'. $node->nid) .'</li>'; } } } $struct .= '</ul>'; return $struct; } } } $current_lineage = array(); $result = db_query(db_rewrite_sql('SELECT n.nid, n.title, n2.nid parent, ml.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid INNER JOIN {menu_links} ml ON b.mlid = ml.mlid INNER JOIN {book} b2 on b2.mlid = ml.plid INNER JOIN {node} n2 on b2.nid = n2.nid WHERE n.status =1 ORDER BY ml.weight, n.title')); while ($node = db_fetch_object($result)) { if (!$children[$node->parent]) { $children[$node->parent] = array(); } array_push($children[$node->parent], $node); /* This function is broken, and for my purposes, not needed ********** if (arg(0) == 'node' && is_numeric(arg(1)) && arg(1) == $node->nid) { $_temp = book_location($node); foreach ($_temp as $key => $val){ $current_lineage[] = $val->nid; } $current_lineage[] = arg(1); } */ } echo book_struct_recurse($book_top_page, $levels_deep, $children, $current_lineage, $emulate_book_block); ?>
-- [ Drupal support list | http://lists.drupal.org/ ]