本の一部である場合にノードに表示されるメニューを作成したい。たとえば、次のようになります。
そのメニューはすべての本に対して表示されるはずです。つまり、システム内の各本に個別のブロックを設定したくないのです。
アコーディオン機能の実装方法には興味がありません。現在のノードのすべてのブック要素のメニュー項目を取得する方法が必要です。
ブックモジュールはブックナビゲーションを備えたブロックを提供しますが、このメニューにすべてのブックを表示したくない.
箱から出してこれを行うcontribモジュールが見つからないことに驚いたので、単純なものを作成しました。
ここでもGithubにあります: https://github.com/balsama/bookoblock (bookoblock
= "Book Outline Block")
情報ファイル(bookoblock.info
):
name = Book Outline Block
description = "Provides a block containing an outline of the current book."
package = Other
core = 7.x
dependencies[] = book
モジュールファイル(bookoblock.module):
<?php
/**
* Define the Book Outline Block/
* Implementation of hook_block_info()
*/
function bookoblock_block_info() {
$block['book_outline'] = array (
'info' => 'Book Outline',
'cache' => DRUPAL_CACHE_PER_PAGE,
);
return $block;
}
/**
* Define the contents and title of the block/
* Implementation of hook_block_view()
*
* Returns a renderable block array containing the current book's outline if
* the node is part of a book.
*
* Returns NULL if the current menu item is not part of a book heirarchy.
*/
function bookoblock_block_view() {
if ($book = bookoblock_is_book_node()) {
$tree = menu_tree_all_data(book_menu_name($book['bid']));
// If we pass 1 as the second param, we just get the top level node in the
// book. Since the key will be the top level mlid, we'll have to use
// ['p1'] in the $book array (which contains the top mlid) when we use it
// for the block title.
$book_name = (book_toc($book['bid'], 1));
// Build the block title and contents
$block['subject'] = $book_name[$book['p1']];
$block['content'] = menu_tree_output($tree);
// Return the block
return $block;
}
// If the current node isn't part of a book, just return nothing.
return NULL;
}
/**
* Checks to see if current node is part of a book.
* Returns book array if it is part of a book, FALSE is not.
*/
function bookoblock_is_book_node() {
if ((arg(0) == 'node') && (is_numeric(arg(1)))) {
$node = menu_get_object();
if (isset($node->book)) {
return $node->book;
}
}
return FALSE;
}
これらの2つのファイルをモジュールディレクトリ内のbookoblock
という名前のフォルダーにドロップし、モジュールを有効にします。 Book Outline
という名前のブロック管理ページに新しいブロックが表示されます。そのブロックは、ノードがブックの一部であるノードページにのみ表示されます。ブック全体の階層メニューが含まれ、そのタイトルはルートノードのタイトルです。
ブックブロック は、私がサイトで使用したものです。それは現在開発リリースを持っていますが、Drupal 7。
それは本ごとにブロックを提供します。その後、コンテキストを使用して、表示の条件を設定できます。
更新-スケーリングに関しては、ブロックの位置を自動化する必要があります。たとえば、新しい本が作成されるとき、新しいコンテキストが正しい条件と反応で追加されます。残念ながら、これはcontribソリューションの低下ほど単純ではありません。
Adamの回答に加えて、本の概要のテーマを設定する方法に関する情報を追加したいと思います。
テーマトリックはほとんどありません。それらを理解するのにかなり時間がかかったので、共有することにしました。
menu_tree_output()
で取得したレンダリング可能な配列をマッサージして、出力を変更できます。次のように、htmlをリーフの要素に直接挿入することもできます。
$leaf['#title'] = "<span class='my-class'>Custom html here.. </span>";
$leaf['#localized_options']['html'] = TRUE;
$leaf['#attributes']['class'][] = 'my-class-link';
または、ツリーの目的のレベルで要素に適用されるテーマ機能を変更できます。
$ leaf ['#theme'] = 'menu_link__my_book_outline';
この場合、hook_menu
でこのテーマへの参照を提供し、フックで宣言されたテーマ関数の実装を提供する必要があります。
/**
* Implements hook_theme()
*/
function my_book_outline_theme() {
return array(
'menu_link__my_book_outline' => array(
'render element' => 'element'
)
);
}
/**
* Returns HTML for the section level elements of the my book outline
* see theme_menu_link for default implementation
*/
function theme_menu_link__my_book_outline(array $variables) {
$element = $variables['element'];
$sub_menu = '';
$output = '<h3>' . $element['#title'] . '</h3>';
if ($element['#below']) {
$sub_menu = drupal_render($element['#below']);
}
return $output . $sub_menu . "\n";
}
このようにして、カスタムレンダリングでtheme_menu_link
呼び出しをオーバーライドします。
$element['#original_link']['depth']
https://drupal.org/node/1930370#comment-7676439 を参照してください。
このリクエストは、コアのBookモジュールからすぐに利用できるものとどのように異なりますか?
元の質問から:
ブックモジュールは、ブックナビゲーションを備えたブロックを提供しますが、このメニューにすべてのブックを表示したくありません。
コアブックブロック構成ページでは、Show block only on book pages
、説明によると:
Show block only on book pages
を選択すると、ブロックには、現在のページのブックに対応する1つのメニューのみが含まれます。この場合、現在のページがブックにない場合、ブロックは表示されません。このブロックを選択的に表示することに加えて、ページ固有の表示設定またはその他の表示設定を使用できます。
(もう一度)何かを逃していない限り、私達二人は何とかして初めてこれを逃したと思います。
スクリーンショット
書籍の構造は実際にはメニューと同じ方法で保存されるため、データベースの編集に慣れている場合は、非常に簡単にカスタムメニューを作成できますブックメニューツリー(したがって、ブロックとして利用できます)。
このYouTubeビデオは、これを行う方法を示しています。
http://www.youtube.com/watch?v=FuQIe5ik9as
あるいは、ニーズに合わせて新しい「メニューブロック」を作成すると、 menu_block モジュールがメニューリストのオプションとして書籍を提供します。