Drupal: How To Show Book Hierarchy
Here, I will tell you how to show full content of all books in hierarchy on your Drupal-based site. The method below has 4 steps with code examples for different Drupal versions.
Solution:
It’s better to show the content as an individual page rather than a block because a block is usually not so big:
- Create a page,
- Insert an appropriate code (different for different Drupal versions),
- Insert input parameter: “PHP”,
- Save changes.
Drupal 5
function book_tree_recurse_all($nid, $depth, $children) {
if ($depth > 0) {
if ($children[$nid]) {
foreach ($children[$nid] as $foo => $node) {
if ($tree = book_tree_recurse_all($node->nid, $depth – 0, $children)) {
$output .= ‘<li class=”expanded”>';
$output .= l($node->title, ‘node/’. $node->nid);
$output .= ‘<ul>’. $tree .'</ul>';
$output .= ‘</li>';
} else {
$output .= ‘<li class=”leaf”>’. l($node->title, ‘node/’. $node->nid) .'</li>';
}
}
}
}
return $output;
}
function book_tree_expanded($parent = 0, $depth = 3) {
$result = db_query(db_rewrite_sql(‘SELECT n.nid, n.title, b.parent, b.weight FROM {node} n INNER JOIN {book} b ON n.nid = b.nid AND n.vid = b.vid WHERE n.status = 1 AND n.moderate = 0 ORDER BY b.weight, n.title’));
while ($node = db_fetch_object($result)) {
$list = $children[$node->parent] ? $children[$node->parent] : array();
array_push($list, $node);
$children[$node->parent] = $list;
}
if ($tree = book_tree_recurse_all($parent, $depth, $children)) {
return ‘<div class=”menu”><ul>’. $tree .'</ul></div>';
}
}
print book_tree_expanded(0);
Drupal 6
function book_toc_recursive($bid, $pid) {
$sql = “SELECT a.mlid, b.link_path, b.link_title FROM {book} a INNER JOIN {menu_links} b ON a.mlid = b.mlid WHERE (a.bid=%d) AND (b.plid=%d) order by a.mlid”;
$result = db_query(db_rewrite_sql($sql), $bid, $pid);
if ($result) {
print “<ul>”;
while ($data = db_fetch_object($result)) {
print “<li>” . l($data->link_title, $data->link_path) . “</li>”;
book_toc_recursive($bid, $data->mlid);
}
print “</ul>”;
}
}
$all_books=book_get_books();
foreach ($all_books as $book_id=>$link) {
book_toc_recursive($book_id, 0);
}<?php
//v.7
unset($output);
function is_book_page_new($changed) {
//time period when articles are considered new.
if ($changed>strtotime(“-7 day”)) return ‘ class=”changed”‘;
}
function book_toc_recursive($bid, $pid) {
$sql=”SELECT b.mlid, ml.link_path, ml.link_title, ml.has_children, n.changed FROM book b INNER JOIN menu_links AS ml ON b.mlid = ml.mlid, {node} AS n WHERE (b.bid=%d) AND (ml.plid=%d) AND b.nid=n.nid AND n.status=1 ORDER BY b.mlid”;
$result = db_query(db_rewrite_sql($sql), $bid, $pid);
if ($result) {
while ($data = db_fetch_object($result)) {
$output.='<li’.is_book_page_new($data->changed).’>’.l($data->link_title, $data->link_path);
if ($data->has_children) $output.='<ul>’.book_toc_recursive($bid, $data->mlid).'</ul>';
$output.='</li>';
}
}
return $output;
}
$all_books=book_get_books();
foreach ($all_books as $book_id=>$link) {
print ‘<ul class=”book_toc”>’.book_toc_recursive($book_id, 0).'</ul>';
}
?>
Good luck!
Some modifications are needed for Drupal 7:
strtotime(“-7 day”)) return ‘ class=”changed”‘;
}
function book_toc_recursive($bid, $pid) {
$sql=”SELECT b.mlid, ml.link_path, ml.link_title, ml.has_children, n.changed FROM book b INNER JOIN menu_links AS ml ON b.mlid = ml.mlid, {node} AS n WHERE (b.bid=”.$bid.”) AND (ml.plid=”.$pid.”) AND b.nid=n.nid AND n.status=1 ORDER BY b.mlid”;
$array = array($bid, $pid);
$result = db_query($sql);
if ($result) {
$output=”;
//while ($data = db_fetch_object($result)) {
foreach ($result as $data) {
$output.=’changed).’>’.l($data->link_title, $data->link_path);
if ($data->has_children) $output.=”.book_toc_recursive($bid, $data->mlid).”;
$output.=”;
}
}
return $output;
}
$all_books=book_get_books();
foreach ($all_books as $book_id=>$link) {
print ”.book_toc_recursive($book_id, 0).”;
}
?>