その他の表示設定

あとは、「家賃」フィールドの表示が「75 000円/月」となっているのを「7.5万円」のようにしたり、「敷金」フィールドが「150 000円」となっているのを「2か月分」と表示させたりといった、表示に関する細かいカスタマイズをしていきます。このような細かいところのカスタマイズまで、Drupal は非常に柔軟に対応できます。

手始めに、「共益費/管理費」フィールドの表示が「2 000円/月」となっているのを、「2,000円/月」(桁区切りのスペースをカンマに変更)となるように、フォーマットを変更してみます。賃貸物件の表示管理(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)にアクセスしてください。

「共益費/管理費」フィールドの列の、右側の操作ボタンをクリック。

フォーマットの設定フォームが現れます。「千の位の印」セレクトボックスで「コンマ」を選択、すぐ下の更新ボタンをクリック。そのままページ下の「保存」ボタンをクリックし、設定を保存します。

コンテンツにアクセスすると、千の位にカンマが入った状態で表示されました。

「家賃」フィールドのカスタマイズ

「家賃」フィールドの表示が「75 000円/月」となっているのを「7.5万円」のように表示させたいと思います。これはさきほどのフォーマット設定に、位取り(千の位、万の位)と、小数点以下の表示桁数を選択できるよう、フックを使って機能を拡張します。カスタムモジュールに、以下のコードを追加してください。

/**
 * Implementation of hook_field_formatter_info()
 * カスタムフォーマットを追加します。
 */
function custom_field_formatter_info() {
  return array(
    'custom_number_yen' => array(
      'label' => t('カスタム円'),
      'field types' => array('number_integer'),
      'settings' => array(
        'thousand_separator' => ' ',
        'decimal_separator' => '.',
        'offset' => 0,
        'scale' => 1,
        'prefix_suffix' => TRUE,
        'prefix' => '',
        'suffix' => '',
        'zero' => '',
      ),
    ),
  );
}

これは hook_field_formatter_info() という、フィールドの表示フォーマットに関するフックです。家賃等の表示用に「カスタム円」という専用のフォーマットを追加しました。以下、これの設定に関する3つの記述をを追加します。

サムネイル拡大表示部分の作成を実践された方は、既に custom_field_formatter_settings_form() という関数が入ってると思います。その中の switch 文(switch ($display['type']) { })に、以下の case を追加してください。

case 'custom_number_yen':
  $options = array(
    ''  => t('<none>'),
    '.' => t('Decimal point'),
    ',' => t('Comma'),
    ' ' => t('Space'),
  );

  $element['thousand_separator'] = array(
    '#type' => 'select',
    '#title' => t('Thousand marker'),
    '#options' => $options,
    '#default_value' => $settings['thousand_separator'],
  );

  $element['decimal_separator'] = array(
    '#type' => 'select',
    '#title' => t('Decimal marker'),
    '#options' => array('.' => t('Decimal point'), ',' => t('Comma')),
    '#default_value' => $settings['decimal_separator'],
  );

  $element['offset'] = array(
    '#type' => 'select',
    '#title' => t('位取り'),
    '#options' => array(0 => '0', 1000 => '千', 10000 => '万'),
    '#default_value' => $settings['offset'],
    '#description' => t('千単位、万単位で表示したい場合に設定してください。')
  );

  $element['scale'] = array(
    '#type' => 'select',
    '#title' => t('Scale'),
    '#options' => drupal_map_assoc(range(0, 10)),
    '#default_value' => $settings['scale'],
    '#description' => t('The number of digits to the right of the decimal.'),
  );

  $element['prefix_suffix'] = array(
    '#type' => 'checkbox',
    '#title' => t('Display prefix and suffix.'),
    '#default_value' => $settings['prefix_suffix'],
  );

  $dependent_element_id = 'edit-fields-'. str_replace('_', '-', $field['field_name']) .'-settings-edit-form-settings-cny-prefix-suffix';
  $element['prefix'] = array(
    '#type' => 'textfield',
    '#title' => t('Prefix'),
    '#default_value' => $settings['prefix'],
    '#size' => 10,
    '#description' => t("Define a string that should be prefixed to the value, like '$ ' or '&euro; '. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array($dependent_element_id => array(TRUE)),
  );

  $element['suffix'] = array(
    '#type' => 'textfield',
    '#title' => t('Suffix'),
    '#default_value' => $settings['suffix'],
    '#size' => 10,
    '#description' => t("Define a string that should be suffixed to the value, like ' m', ' kb/s'. Leave blank for none. Separate singular and plural values with a pipe ('pound|pounds')."),
    '#process' => array('ctools_dependent_process'),
    '#dependency' => array($dependent_element_id => array(TRUE)),
  );

  $element['zero'] = array(
    '#type' => 'textfield',
    '#title' => t('値が 0 のときの表示'),
    '#default_value' => $settings['zero'],
    '#size' => 10,
    '#description' => t('値が 0 の場合の表示をカスタマイズできます。例: 「 - 」、「無し」等。'),
  );
  break;

同じく「サムネイル拡大表示部分の作成」を実践された方は、既に custom_field_formatter_settings_summary() という関数が入ってると思います。その中の switch 文(switch ($display['type']) { })に、以下の case を追加してください。

case 'custom_number_yen':
  $summary[] = number_format(1234.1234567890, $settings['scale'], $settings['decimal_separator'], $settings['thousand_separator']);
  $summary[] = t('位取り: @offset', array('@offset' => $settings['offset']));
  if ($settings['prefix_suffix']) {
    $summary[] = t('Display with prefix and suffix.');
    $summary[] = t('接頭語: @prefix, 接尾語: @suffix', array('@prefix' => $settings['prefix'], '@suffix' => $settings['suffix']));
  }
  $summary[] = t('値が 0 のときの表示: 「@zero」', array('@zero' => $settings['zero']));
  break;

同じく「サムネイル拡大表示部分の作成」を実践された方は、既に custom_field_formatter_view() という関数が入ってると思います。その中の switch 文(switch ($display['type']) { })に、以下の case を追加してください。

case 'custom_number_yen':
  // カスタム円表示フォーマット
  foreach ($items as $delta => $item) {
    // 万単位の表示、千単位の表示などをするため、
    // 位取りの値が 0 でなければ $item['value'] を位取りの値で割ります。
    $value = $settings['offset'] ? $item['value'] / $settings['offset'] : $item['value'];
    $output = (float) number_format($value, $settings['scale'], $settings['decimal_separator'], $settings['thousand_separator']);

    // 「値が 0 のときの表示」を設定している場合は、値が 0 の場合はそれを適用します。
    if ($settings['zero'] && $output == 0) {
      $output = $settings['zero'];
    } else {
      if ($settings['prefix_suffix']) {
        $prefixes = isset($settings['prefix']) ? array_map('field_filter_xss', explode('|', $settings['prefix'])) : array('');
        $suffixes = isset($settings['suffix']) ? array_map('field_filter_xss', explode('|', $settings['suffix'])) : array('');
        $prefix = (count($prefixes) > 1) ? format_plural($item['value'], $prefixes[0], $prefixes[1]) : $prefixes[0];
        $suffix = (count($suffixes) > 1) ? format_plural($item['value'], $suffixes[0], $suffixes[1]) : $suffixes[0];
        $output = $prefix . $output . $suffix;
      }
    }
    $element[$delta] = array('#markup' => $output);
  }
  break;

モジュールの設定を再構築し、すべてのキャッシュをクリアした後、再度、賃貸物件の表示管理(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)にアクセスしてください。

図4

「家賃」フィールドのフォーマットのセレクトボックスに、「カスタム円」というオプションが追加されていると思います。それを選択して、右側の操作ボタンをクリックしてください。

「位取り」に「万」を選択、尺度は「1」、接尾語に「 万円/月」と入力して、すぐ下の「更新」ボタンをクリック、そのままページ下の「保存」ボタンをクリックします。

コンテンツにアクセスすると、家賃が「7.5万円」と、万単位で表示されるようになりました。小数点以下は第1位までと設定したので、そのように表示されています。

「敷金」、「礼金」、「更新料」フィールドのカスタマイズ

敷金、礼金等は、「○○万円」と表示するのではなく、(家賃の)「○ヶ月分」と表示するほうがしっくり来るでしょう。いちおうその前に、家賃で割り切れないような価格設定の場合も想定して、「カスタム円」の設定をしておきます。賃貸物件の表示管理(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)にアクセスし、「家賃」フィールドのフォーマットのセレクトボックスに、「カスタム円」を選択、右側の操作ボタンをクリックします。

「位取り」に「万」、尺度に「1」を選択、接尾語に「 万円/月」、「値が 0 のときの表示」に「無し」と入力して、すぐ下の「更新」ボタンをクリック、そのままページ下の「保存」ボタンをクリックします。

敷金が「15 万円」と表示されるようになりました。値の 0 の場合は、ここで「無し」と表示されます。礼金、更新料についても、同様に設定してください。

次にこれを(家賃の)「○ヶ月分」と表示させる設定をします。カスタムモジュールに以下の記述を追加してください。

/**
 * Implementation of template_preprocess_field()
 */
function custom_preprocess_field(&$variables) {
  $element = $variables['element'];

  // フィールド別の表示調整
  switch ($element['#field_name']) {
    case 'field_deposit':
    case 'field_reward':
    case 'field_renewal_fee':
      // 敷金、礼金、更新料の表示をカスタマイズ。「(家賃の)~ヶ月分」と表せる場合は、そのように表示する。
      $field_rent = field_get_items('node', $element['#object'], 'field_rent');
      $rent = $field_rent[0]['value'];
      if (isset($element['#items'][0]['value']) && $element['#items'][0]['value'] > 0) {
        $months = $element['#items'][0]['value'] / $rent;
        if (is_int($months) && $months > 0) {
          $variables['items'][0]['#markup'] = $months .'ヶ月';
        }
      }
      break;
  }
}

これはフィールド用のテンプレート前処理関数です(※1)。ノードがノードテンプレートによって表示されているのと同様に、各フィールドもまた、フィールドテンプレートによって表示されています。template_preprocess_field() はそれぞれフィールドテンプレートに変数を渡す前のタイミングでコールされるので、ここで変数を操作しました。

モジュールの設定を再構築し、すべてのキャッシュをクリアしたあと、コンテンツにアクセスすると、敷金、礼金が「2ヶ月」、更新料が「1ヶ月」と表示されました。

「築年月」フィールドの表示をカスタマイズ

築年月フィールドが「4月, 2009」と表示されているので、これを「2009年4月」のように表示するようにします。賃貸物件の表示管理(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)から、「築年月」フィールドの操作ボタンをクリックします。

しかしこのフォーマットのセレクトボックスには、適当なオプションがありません。ここに適当なオプションを追加するため、日付と時刻の設定ページ(「管理」 > 「環境設定」 > 「日付と時刻」)にアクセスしてください。

ここで日付タイプを追加します。日付タイプを追加する前に、右上の「書式」タブをクリック。

「書式の追加」をクリック。

「書式文字列」テキストフィールドに、「Y年n月」と入力し、「書式を追加」ボタンをクリックして、書式を追加します。これは PHP の date 関数で使用する書式です。書式を追加したら、「タイプ」タブをクリックして、日付と時刻の設定画面に戻ってください。

「データタイプの追加」をクリックします。

「日付型」に「年月」、「システム内部名称」に「ymjp」、「日付の書式」セレクトボックスのオプションに、今設定した書式があるはずですので、それを選択します。「データタイプの追加」ボタンをクリックして日付型を追加したら、先ほどの賃貸物件の表示設定画面(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)に戻り、「築年月」フィールドの右側の、操作ボタンをクリックしてください。

セレクトボックスのオプションに、今追加したフォーマットが追加されています。これを選択してすぐ下の「更新」ボタンをクリック、そのあとページ下の「保存」ボタンをクリックして、設定を保存してください。

コンテンツにアクセスすると、築年月フィールドのところに「2009年4月 年月」と表示されています。おしりの「 年月」が余計ですが、これはおそらく Date モジュールのバグでしょう。これについてはあとで修正します。

「入居可能時期」フィールドの表示をカスタマイズ

「入居可能時期」フィールドも「火曜日, 7月 3, 2012」のような、あまり日本語にそぐわない表示になっています。これを「2012年7月上旬」といったような「旬(じゅん)」の表記にしたいと思います。賃貸物件の表示管理(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)から、入居可能時期フィールドの操作ボタンをクリックして、「築年月」と同様の設定をしてください。そのあとカスタムモジュールに、以下のコードを追加します。

/**
 * Implementation of hook_date_formatter_dates_alter()
 */
function custom_date_formatter_dates_alter(&$dates, &$context) {
  // 「2012年7月 年月」となってしまう(日付けのあとに文字列「年月」が入ってしまう)不具合に対応。
  // 不具合の原因はいまのところ不明だが、とりあえずこうすることで回避できる。
  $dates['value']['formatted_timezone'] = '';

  // 入居可能時期は旬表示にする。
  if ($context['field']['field_name'] == 'field_availability') {
    $now = time();
    if ($context['item']['value'] <= $now) {
      $dates['value']['formatted'] = $dates['value2']['formatted'] = '即入居可';
    } else {
      $day = date('j', $context['item']['value']);
      if ($day <= 10) {
        $jun = '上旬';
      } elseif ($day <= 20) {
        $jun = '中旬';
      } else {
        $jun = '下旬';
      }
      $dates['value']['formatted'] = $dates['value2']['formatted'] .= $jun;
    }
  }
}

これは Date モジュールの hook_date_formatter_dates_alter() というフックです。フックはコアモジュールだけでなく、サードパーティー製モジュールが独自のフックを提供する場合もあります。これは Date モジュールの、やはりフォーマットに関するフックです。ここで「入居可能時期」フィールドに「上旬、中旬、下旬」という表記を追加し、日付が過去の場合は、「即入居可」と表示するようにしました。ついでに先ほどのバグらしきものもここで修正しておきました。

モジュールの設定を再構築し、キャッシュをクリアしてください。コンテンツにアクセスすると、「入居可能日」フィールドのところに「即入居可」と表示されています。この記事の執筆時点では「2012年7月3日」というのは過去の日付なので、このような表示となりました。「築年月」フィールドを見ると、先ほどのバグが修正されています。


※1: テンプレート前処理関数については前々回「サムネイル拡大表示部分の作成」で説明しています。