カテゴリリストの作成2

市区町村のカテゴリリスト

'forrent/area/{県名}' のページに表示するカテゴリリストを作成します。これは、「県」ターム階層下の「市区」タームのリストになります。

「県」のカテゴリリストは、単純にカテゴリへのリンクとして表示しましたが、市区・町村のカテゴリリストについては、カテゴリーを複数選択したい場合を想定して、複数選択可のチェックボックスとして表示することにします。

ディスプレイの追加とブロックの設定

前回作成した「ターム一覧 - エリアから探す」のビューに、ブロックのディスプレイを追加します。

ビューの編集画面にアクセスし、左上「+Add」の「ブロック」をクリックします。

Display name に「ブロック1」、Block name に「ターム一覧 - エリアから探す(市区)」と入力し、画面右上「保存」ボタンをクリックして、ビューの設定を保存します。

ブロック管理ページ(「管理」 > 「サイト構築」 > 「ブロック」)にアクセスすると、今作成した「ターム一覧 - エリアから探す(市区)」ブロックが追加されているので、リージョンに「コンテンツ」を設定します。設定したら、ページ下の「ブロックの保存」ボタンをクリック。

「ターム一覧 - エリアから探す(市区)」ブロックは、「コンテンツ」リージョンに移動しました。ブロックの設定は、ブロックのタイトルに「<none>」、「特定ページでのブロックの表示」には「forrent/area/*」と入力します。設定したら「ブロックの保存」ボタンをクリック。

'forrent/area/{県名}' にアクセスしたところです。今設定したブロックが表示されています。この時点でのブロックの内容は、前回設定した 'forrent/area' のページと全く同じです。これはさきほど新しく追加したディスプレイが、ビューの設定を継承しているためです。

ここで「県」のタクソノミータームが表示されているのを、アクセスしたページの階層下の「市区」のタクソノミータームが表示されるように、ビューを編集します。

ビューの編集

コンテキストフィルターの設定

ビューの管理画面(「管理」 > 「サイト構築」 > 「Views」)にアクセスし、「ブロック1」ディスプレイをアクティブにしてください。

コンテキストフィルターの「追加」をクリック。

コンテキストフィルターの追加画面です。For のところは「This block (override)」を選択(※「This block (override)」を選択することで、ここでの設定はこのディスプレイだけに限定されます)、フィルタは「タクソノミーターム」を選択します。「タクソノミーターム: パスに使用する名前 (field_path_name)」の項目にチェックを入れ、「Apply (this display)」ボタンをクリックします。

グループの設定はデフォルトのまま、「Apply and continue」ボタンをクリック。

「タクソノミーターム: パスに使用する名前 (field_path_name)」の設定です。Relation セレクトボックスは「親1」を選択。WHEN THE FILTER VALUE IS NOT AVAILABLE(引数が無い場合の設定)で、Provide default value にチェックを入れ、タイプに「Raw value from URL」、Path component に「3」を選択します。こうすることで、例えばアクセスしたパスが 'forrent/area/chiba' だとすると、3つめの引数「chiba」が対象となります。この設定で、「Apply (this display)」ボタンをクリック。

先ほどの「ブロックの設定」で、表示するページには「forrent/area/*」と入力しましたが、この設定では、URL からの引数が4つある場合('forrent/area/{県名}/{カテゴリ ID}')のページにも、このブロックが表示されてしまいます。'forrent/area/{県名}/{カテゴリ ID}' のページには別のブロックを表示させるようにしたいので、URL からの引数が4つある場合には非表示となるよう、ここで設定します。

コンテキストフィルターにもうひとつ、「Global: Null」のフィルターを追加します。

グループの設定はデフォルトのまま、「Global: Null」の設定画面で、WHEN THE FILTER VALUE IS NOT AVAILABLE(引数が無い場合の設定)では、Provide default value にチェックを入れ、タイプに「Raw value from URL」、Path component に「4」を選択します。

WHEN THE FILTER VALUE IS AVAILABLE OR A DEFAULT IS PROVIDED(引数がある場合の設定)では、Specify validation criteria(値を検証する)にチェックを入れ、Validator に「PHP Code」、PHP validate code には、

if (empty($argument)) {
  return TRUE;
}

と入力、Action to take if filter value does not validate(検証にパスしなかった場合の処置)には「Hide view」を選択します。これで URL からの引数の4つめの値がある場合には、このビュー(ブロック)は表示されません。この設定で、「Apply (this display)」ボタンをクリックしてください。

表示フィールドの設定

表示フィールドの設定をします。まず、最初に作成したブロックの設定を継承している場合は、「タクソノミーターム: タームID」と「タクソノミーターム: 名前」は「親1」に関連付けされていると思います。

これらの関連付け(Relationship)を「親1」 → 「親」に変更します。

「タクソノミーターム: 名前」については、カスタムリンクを編集します。

少しスクロールしたところの「REWRITE RESULTS」フィールドセット開き、「Output this field as a link」のところの「Link path」を「!1/area/[field_path_name]/[tid]」に修正します。

設定が済んだら、ビューの編集画面の右上「保存」ボタンをクリックして.ビューの設定を保存してください。

'forrent/area/{県名}' にアクセスすると、{県名} の「子」タームが、その階層下のタームに登録されている物件の件数とともに表示されました。リンク先はカスタムのタクソノミーページ('forrent/area/{県名}/{ターム ID}')となっています。

カスタムスタイルの追加

図15のカテゴリリストを、複数選択できるよう、チェックボックスにして表示します。これは、ビューのフォーマットにカスタムスタイルを追加することで実現します。カスタムモジュールの views フォルダに 'custom_plugin_style_jump_menu_checkboxes.inc' という名前のファイルを作成し、内容を以下のように記述してください。

<?php
/**
 * 複数選択可能なチェックボックスのジャンプメニュー
 */
class custom_plugin_style_jump_menu_checkboxes extends views_plugin_style_jump_menu {
  function option_definition() {
    $options = parent::option_definition();

    $options['argument'] = array('default' => '');
    $options['argument_separator'] = array('default' => '+');
    $options['fieldset_title'] = array('default' => '選択してください。');
    $options['fieldset_format'] = array('default' => 'collapsible');

    return $options;
  }

  /**
   * Render the given style.
   */
  function options_form(&$form, &$form_state) {
    parent::options_form($form, $form_state);

    $form['path'] = array(
      '#type' => 'textfield',
      '#title' => t('Path'),
      '#default_value' => $this->options['path'],
    );

    $handlers = $this->display->handler->get_handlers('field');
    foreach ($handlers as $id => $handler) {
      $options[$id] = $handler->ui_name();
    }

    $form['argument'] = array(
      '#type' => 'select',
      '#title' => t('Argument'),
      '#options' => $options,
      '#default_value' => $this->options['argument'],
      '#description' => t('選択アイテムにジャンプする際、パスの引数として使用されます。'),
    );

    $form['argument_separator'] = array(
      '#type' => 'textfield',
      '#title' => t('Multiple argument separator'),
      '#default_value' => $this->options['argument_separator'],
      '#size' => 4,
      '#description' => t('複数のアイテムを選択した場合に、引数のセパレータとして使用されます。'),
    );

    $form['fieldset_title'] = array(
      '#type' => 'textfield',
      '#title' => t('フィールドセットのタイトル'),
      '#default_value' => $this->options['fieldset_title'],
    );

    $form['fieldset_format'] = array(
      '#title' => t('フィールドセットのフォーマット'),
      '#type' => 'select',
      '#options' => array(
        'open' => t('open'),
        'collapsible' => t('collapsible'),
        'collapsed' => t('collapsed'),
      ),
      '#default_value' => $this->options['fieldset_format'],
    );
  }

  /**
   * Render the display in this style.
   *
   * This is overridden so that we can render our grouping specially.
   */
  function render() {
    $sets = $this->render_grouping($this->view->result, $this->options['grouping']);

    // Turn this all into an $options array for the jump menu.
    $this->view->row_index = 0;
    $options = array();
    $paths = array();

    foreach ($sets as $title => $records) {
      foreach ($records as $row_index => $row) {
        $this->view->row_index = $row_index;
        $key = strip_tags(decode_entities($this->get_field($this->view->row_index, $this->options['argument'])));
        $field = decode_entities($this->row_plugin->render($row));
        if ($title) {
          $options[$title][$key] = $field;
        }
        else {
          $options[$key] = $field;
        }
        $this->view->row_index++;
      }
    }
    unset($this->view->row_index);

    $settings = array(
      'path' => $this->tokenize_value($this->options['path'], NULL),
      'button' => $this->options['text'],
      'argument' => $this->options['argument'],
      'argument_separator' => $this->options['argument_separator'],
      'fieldset_title' => $this->tokenize_value($this->options['fieldset_title'], NULL),
      'fieldset_format' => $this->options['fieldset_format'],
    );

    $form = drupal_get_form('custom_jump_menu_checkboxes', $options, $settings);
    return $form;
  }
}

function custom_jump_menu_checkboxes($form, &$form_state, $options = array(), $settings = array()) {
  drupal_add_css(drupal_get_path('module', 'custom') .'/custom.css');

  $form['settings'] = array(
    '#type' => 'value',
    '#value' => $settings,
  );

  // 特別カスタマイズ
  if ($settings['fieldset_title'] == '沿線をさらに絞る') {
    $settings['fieldset_title'] = '駅を指定する';
  }

  $form['jump_fieldset'] = array(
    '#type' => 'fieldset',
    '#title' => $settings['fieldset_title'],
    '#collapsible' => $settings['fieldset_format'] != 'open' ? TRUE : FALSE,
    '#collapsed' => $settings['fieldset_format'] == 'collapsed' ? TRUE : FALSE,
  );

  $form['jump_fieldset']['jump'] = array(
    '#type' => 'checkboxes',
    '#options' => $options,
    '#attributes' => array(
      'class' => array('jump-menu-checkboxes'),
    ),
  );

  $form['jump_fieldset']['go'] = array(
    '#type' => 'submit',
    '#value' => $settings['button'],
  );

  return $form;
}

function custom_jump_menu_checkboxes_submit($form_id, &$form_state) {
  $args = array();
  foreach ($form_state['values']['jump'] as $value) {
    if ($value) {
      $args[] = $value;
    }
  }

  if (!empty($args)) {
    $path = $form_state['values']['settings']['path'];
    $separator = $form_state['values']['settings']['argument_separator'];
    $form_state['redirect'] = $path .'/'. implode($separator, $args);
  }
}

次に、このカスタムスタイルを利用可能にするため、custom.views.inc('custom/views/custom.views.inc')に、以下のコードを追加します。

/**
 * Implementation of hook_views_plugins()
 */
function custom_views_plugins() {
  $plugins = array(
    'style' => array(
      'jump menu checkboxes' => array(
        'title' => t('jump menu checkboxes'),
        'help' => t('複数選択可能なチェックボックスのジャンプメニューです。'),
        'handler' => 'custom_plugin_style_jump_menu_checkboxes',
        'uses fields' => TRUE,
        'uses options' => TRUE,
        'uses row plugin' => TRUE,
        'type' => 'normal',
      ),
    ),
  );

  return $plugins;
}

custom.info に以下の記述を追加します。

files[] = views/custom_plugin_style_jump_menu_checkboxes.inc

モジュールの設定を再構築し、キャッシュをクリアしてください。

ビューのフォーマットを変更します。ビューの編集画面から、フォーマットのところの「Grid」(現在使用しているフォーマット)をクリック。

ビューのスタイルフォーマットの選択画面です。For のところは「This block (override)」を選択、「jump menu checkboxes」というオプションが入ってると思います。これは今追加したカスタムのスタイルフォーマットです。チェックを入れて「Apply (this display)」ボタンをクリック。

「jump menu checkboxes」の設定画面です。パスのところに「!1/area/!2」と入力します。「!1」、「!2」のところはそれぞれ、コンテキストフィルターの1つめの値、2つめの値に置きかえられます(この場合は 'forrent/area/chiba' となります)。

少しスクロールして、Argument に「タクソノミーターム: ターム ID」を選択します。これで、さきほどのパスに、引数として選択したタームのターム ID を渡した値('forrent/area/chiba/{ターム ID}')にジャンプします。複数のタームを選択した場合は、Multiple argument separator('+')で区切った値が引数となります。フィールドセットのタイトルには「エリアを選択してください」と入力、フィールドセットのフォーマットは「オープン」を選択し、「Apply (this display)」ボタンをクリック。

ビューの編集画面に戻ったら、画面右上「保存」ボタンをクリックして、ビューの設定を保存してください。

'forrent/area/{県名}' にアクセスし、CSS を若干編集したところです。アクセスしたページの階層下のカテゴリ(「市区」のタクソノミーターム)が一覧で表示されました。それぞれのカテゴリーには、登録されている物件数があわせて表示されています。クリックするとカスタムのタクソノミーページ('forrent/area/{県名}/{ターム ID}')にアクセス出来ます。複数のカテゴリーにチェックを入れて送信すれば、複数のカテゴリーの物件をあわせて表示することも可能です。