web-dev-qa-db-ja.com

Node Referencesで、タイトルの代わりにカスタムフィールドを表示する方法は?

ノードを参照するときに、選択リストにタイトルではなく別のフィールドを表示することはできますか?

6
Oscar Mederos

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;
}
7
Andy

ノード参照フィールドを作成するときに、「詳細-参照可能なノード(ビュー)」フィールドセットでノードを選択するために使用される「ビュー」を選択できます。また、デフォルトでこのビューに引数を渡すことができます。

5
dobeerman

http://drupal.org/project/nodereference_Explorer は少しやり過ぎかもしれません。ノードを参照するための選択ダイアログが表示され、「他のCCKフィールドをサポートするプラグインアーキテクチャ」と表示されます

2
WestieUK