После изучения API Drupal 6 написал такое:
<?php
//http://api.drupal.org/api/function/book_block/6
function book_toc_recursive() {
$book_menus = array();
$pseudo_tree = array(0 => array('below' => FALSE));
foreach (book_get_books() as $book_id => $book) {
$menu_item=menu_tree_all_data($book['menu_name'], $book);
$book_menus[$book_id] = menu_tree_output($menu_item);
}
return theme('book_all_books_block', $book_menus);
}
echo book_toc_recursive();
?>
//http://api.drupal.org/api/function/book_block/6
function book_toc_recursive() {
$book_menus = array();
$pseudo_tree = array(0 => array('below' => FALSE));
foreach (book_get_books() as $book_id => $book) {
$menu_item=menu_tree_all_data($book['menu_name'], $book);
$book_menus[$book_id] = menu_tree_output($menu_item);
}
return theme('book_all_books_block', $book_menus);
}
echo book_toc_recursive();
?>
Код выводит таки оглавление, но до 2го уровня вложенности.
А мне нужно все уровни. Чтобы было как настоящее содержание в книге.
Подскажите как это сделать.
Вложение | Размер |
---|---|
book_toc_recursive.png | 41.81 КБ |
Комментарии
чот у бука нужных апишных нет, пришлось вручную набросать:
<?php
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 "
";- " . l($data->link_title, $data->link_path) . "
while ($data = db_fetch_object($result)) {
print "
";
book_toc_recursive($bid, $data->mlid);
}
print "
";
}
}
book_toc_recursive(181, 0);
?>
Чего-то не получается. Получаю кучу предупреждений типа:
warning: Illegal offset type in isset or empty in .../modules/taxonomy/taxonomy.module on line 1014.
Сейчас будем искать решение. Спасибо огромное за ответ.
в taxonomy модуле делаешь исправления?
Нет, не делал...
Ура! Заработало. Оказалось, что нужно было подставить id существующей книги, а не 0, ни 1, ни 181 у меня не было...
Ок. Вот код, который выводит полное оглавление всех книг в Друпал 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 "
";- " . l($data->link_title, $data->link_path) . "
while ($data = db_fetch_object($result)) {
print "
";
book_toc_recursive($bid, $data->mlid);
}
print "
";
}
}
$all_books=book_get_books();
foreach ($all_books as $book_id=>$link) {
book_toc_recursive($book_id, 0);
}
?>
Посмотреть работу сниппета можно на морде сайта drupalcookbook.ru
Ура! Огромное спасибо за помощь.
Решение было сохранено на сайте DrupalCookBook.ru:
Вывести полное содержание всех книг (book) на сайте в виде иерархии.
Авторы, предложившие решения, также указаны в сохранённой статье.
Код, который выдаёт сниппет не валидный. Не закрываются теги...
а можно пример незакрытия тегов?
дополняю:
пояснения к функции:
function book_toc_recursive($bid, $pid)
$bid - номер книжки
$pid - номер начального узла, используется в рекурсии, для начала 0
// if ($result) {
// можно чуть обезопаситься:
// 8-ая строка
print "<li>" . l(check_plain($data->link_title), $data->link_path) . "</li>";
...
Наконец-то дошли руки (хотя я ногами хожу) и я переделал этот скрипт. Исправил ошибку с незакрытыми тегами и чуток оптимизировал вывод:
<?php
//v.5
unset($output);
function book_toc_recursive($bid, $pid) {
$sql="SELECT b.mlid, ml.link_path, ml.link_title, ml.has_children FROM book b INNER JOIN menu_links ml ON b.mlid = ml.mlid WHERE (b.bid=%d) AND (ml.plid=%d) order by b.mlid";
$result = db_query(db_rewrite_sql($sql), $bid, $pid);
if ($result) {
while ($data = db_fetch_object($result)) {
$output.="
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)."
";
}
?>
Проверить валидность можно тут (скрипт работает на главной): http://validator.w3.org/check?verbose=1&uri=http%3A%2F%2Fdrupalcookbook....
Раньше была туча ошибок - жаловался на незакрытые теги
<ul> и <li>
.продублировалось ссобщение нижестоящие.
вставил код для Д6 в блок. У всех кроме юзер№1 ошибка:
user warning: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'order by a.mlid)' at line 1 query: SELECT a.mlid, b.link_path, b.link_title FROM book a INNER JOIN menu_links b ON a.mlid = b.mlid INNER JOIN node_access na ON na.nid = n.nid WHERE (na.grant_view >= 1 AND ((na.realm = 'all' AND na.gid = 0) OR (na.realm = 'domain_site' AND na.gid = 0) OR (na.realm = 'domain_id' AND na.gid = 0)) ) AND ( (a.bid=3) AND (b.plid=0) order by a.mlid) in /includes/common.inc(1537) : eval()'d code on line 5.
a.mlid) - чо за скобка?
оказалось конфликтует с domain access.
выход пока нашёл такой:
$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";
/*echo db_rewrite_sql($sql);*/
$result = db_query($sql, $bid, $pid);
if ($result) {
print "<ul class=\"menu\">";
while ($data = db_fetch_object($result)) {
print "<li>" . l($data->link_title, $data->link_path) ;
book_toc_recursive($bid, $data->mlid). "</li>";
}
print "</ul>";
}
}
$all_books=book_get_books();
foreach ($all_books as $book_id=>$link) {
book_toc_recursive($book_id, 0);
}
и что бы css для меню подхватывался перенёс book_toc_recursive($bid, $data->mlid) во внутрь тега li
Ну незнаю может пригодиться но я вот нашел такое решение.
foreach ($menu_items as $key => $val)
{
if (strpos($val, 'book')!==false)
{
echo theme('dhtml_menu_tree',menu_tree_all_data($menu_items[$key]));
}
}
Строка
использована мною для создания меню с помощью мода DHTML Menu.
А так по идее идее стоку
Можно заменить на
$book_menus[$key] = menu_tree_output($menu_book);
Ну а дальше с массивом $book_menus можно делать все что угодно.
Был косячок в запросе. Правильно - так.
<?php
//v.7 for Drupal 6
unset($output);
function is_book_page_new($changed) {
//Период, в течении которого статьи считаются новыми.
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.='
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).'
';
}
?>
А как сделать чтобы вывод по алфавиту был, а то как-то
некрасивонеудобно получается?Правь запрось, добавь order by
А можно подробнее - я в пхп не силен.
В запросе
<?php
$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";
?>
ORDER BY b.mlid меняем на ORDER BY b.link_title
Вообще все ссылки пропадают...
Точно больше ничего не менял в коде/запросе? Поставь как было и попробуй ещё раз.
нет скачал вышеприведенный код для вывода развернутого содержания и заменил сортировку...
Сейчас тоже смотрю на это дело. Попробуй не ORDER BY b.link_title , а ORDER BY ml.link_title
===
и вопрос глупый попутно можно задать?
Задача: Нужно вывести одну из подшивок на такое отображение.
Я так понимаю нужно исправить вот эту строчку:
book_toc_recursive($book_id, 0);
Вопрос: Где посмотреть этот самый book_id или как именно исправить?
UPD
Вот примерно это хотел http://setegnom.com/node/774
>>>Где посмотреть этот самый book_id
это циферка после node/, например, у node/9, book_id = 9 (вдруг таким как я пригодиццо)
Спасибо, отличный сниппет. Первоначальный код у меня выводил ограниченную вложенность, код в редакции fasdalf выводит полную структуру.