ノードを参照するときに、選択リストにタイトルではなく別のフィールドを表示することはできますか?
Dobeermanが言うように、ソースとしてビューを使用できますが、CCKはバックグラウンドでビューを操作します(この質問の結果として知りました)。関数_nodereference_potential_references_views()
でnodereference.module
を調べると、次のコードが見つかります。
// We do need title field, so add it if not present (unlikely, but...)
$fields = $view->get_items('field', $display);
if (!isset($fields['title'])) {
$view->add_item($display, 'field', 'node', 'title');
}
// If not set, make all fields inline and define a separator.
$options = $view->display_handler->get_option('row_options');
if (empty($options['inline'])) {
$options['inline'] = drupal_map_assoc(array_keys($view->get_items('field', $display)));
}
if (empty($options['separator'])) {
$options['separator'] = '-';
}
$view->display_handler->set_option('row_options', $options);
つまり、これは
したがって、タイトルフィールドを非表示に構成し、適切なセパレータを指定すると、ほぼすべての効果を作成できるはずです。ビューで希望どおりの結果が得られない場合(たとえば、メニューの位置によるノードの順序付け)は、別のアプローチを使用する必要があります。
独自のCCKウィジェットを作成することも、(より単純な)form_alterフックを使用することもできます。後者の場合、CCKはこの段階ではフォームを処理していないため、フォームを通常の方法で編集することはできません。#after_build
関数を使用する必要があります。
興味がある場合は、メニューで順序付けされたノード参照を表示するために使用される2番目のアプローチの例を示します。
/**
* Implements hook_form_alter().
*/
function banners_form_alter(&$form, &$form_state, $form_id) {
// Modify nodereferences for banners so that pages are shown in primary links
// order.
if ($form['#id'] === 'node-form' && isset($form['#field_info']['field_pages'])) {
if (!isset($form['#after_build'])) {
$form['#after_build'] = array();
}
$form['#after_build'][] = 'banners_after_build';
}
}
/**
* After_build callback for modifying CCK field select options.
*/
function banners_after_build($form, &$form_state) {
// Get the menu data
$new_options = banners_generate_page_options();
if (isset($form['#field_info']['field_pages'])) {
$old_options = $form['field_pages']['nid']['nid']['#options'];
$final_options = banners_process_options($new_options, $old_options);
$form['field_pages']['nid']['nid']['#options'] = $final_options;
}
// Return new form
return $form;
}
/**
* Uses the old options to filter out unreferenced nids and add those that
* weren't detected in a menu structure to the other option group.
* @param $new_options
* The options list created by scanning the menus.
* @param $old_options
* The options list originally passed to the form.
*
* @return
* The final options list with option groups for each menu and for orphans.
*/
function banners_process_options($new_options, $old_options) {
// Have to assume that $old_options could get quite large, whereas
// $new_options is based on menus, and shouldn't get too large.
// Iterate through $new_options (the menu nids) and remove nids from
// $old_options that exist in $new_options, and remove nids from $new_options
// that don't exist in $old_options. After this $old_options has valid nids
// that aren't under the menu hierarchy.
foreach ($new_options as $menu_title => $options) {
foreach ($options as $nid => $title) {
if (isset($old_options[$nid])) {
unset($old_options[$nid]);
}
else {
unset($new_options[$menu_title][$nid]);
}
}
}
$final_options = array();
// If the field is not marked required, there'll be an option for - None -
// and it's keyed to the empty string.
if (isset($old_options[''])) {
$final_options[''] = $old_options[''];
unset($old_options['']);
}
$final_options += $new_options;
$final_options['Others'] = $old_options;
return $final_options;
}
/**
* Generates FAPI options for the allowed menus' node links.
*
* @return
* A FAPI options array with all node links on the allowed menus (NB this has
* not been filtered in any other way).
*/
function banners_generate_page_options() {
$menus = array('primary-links', 'menu-top-menu');
$options = array();
foreach ($menus as $menu_name) {
$tree = menu_tree_all_data($menu_name);
$menu = menu_load($menu_name);
$options[$menu['title']] = _banners_process_tree($tree);
}
return $options;
}
/**
* Recursive function to generate the options array, keyed by nid.
*/
function _banners_process_tree($tree, $depth = 0) {
$options = array();
foreach ($tree as $item) {
$matches = array();
if (preg_match('~^node/(\d+)$~', $item['link']['link_path'], $matches)) {
// Link points to a node
$nid = $matches[1];
$options[$nid] = str_repeat('--', $depth) . ' ' . $item['link']['title'];
if ($item['below']) {
$options += _banners_process_tree($item['below'], $depth + 1);
}
}
}
return $options;
}
ノード参照フィールドを作成するときに、「詳細-参照可能なノード(ビュー)」フィールドセットでノードを選択するために使用される「ビュー」を選択できます。また、デフォルトでこのビューに引数を渡すことができます。
http://drupal.org/project/nodereference_Explorer は少しやり過ぎかもしれません。ノードを参照するための選択ダイアログが表示され、「他のCCKフィールドをサポートするプラグインアーキテクチャ」と表示されます