サムネイル拡大表示部分の作成

図1 は、前回画像スタイルを設定したところに、テーマのスタイルシート('sites/all/themes/bartik/css/style.css')を編集して配置を整えたところです。

赤で囲ったボックスのところは、室内写真のサムネイルを多数配置できるよう、スクロール式にします。サムネイルの1つをクリックすると、左側に大きく表示されるようにします。これらの動作はスクリプトファイルに記述し、Drupal にそれを読み込ませる形となります。

その前に、拡大表示エリア(点線の部分です)にデフォルトで表示する画像を設定したいと思います。ここには室内写真フィールド(フィールドの値の数は無制限に設定されています)の最初の値に、前回設定した拡大表示用の画像スタイル('inside_picture')を適用した画像を表示します。

ノードテンプレート(node--forrent.tpl.php)に拡大表示のデフォルトを渡すテンプレート変数 $field_inside_picture_default を追加します。現在適用されているテーマ('sites/all/themes/bartik')の template.php に、以下の記述を探してください。

/**
 * Override or insert variables into the node template.
 */
function bartik_preprocess_node(&$variables) {
  if ($variables['view_mode'] == 'full' && node_is_page($variables['node'])) {
    $variables['classes_array'][] = 'node-full';
  }
}

この関数はテンプレート前処理関数というもので、template_preprocess_node() の template の部分を、記述するテーマ名/モジュール名に置き換えることで、ノードテンプレートに処理が移る直前にコールされるようになります。ここでは bartik というテーマに記述されているので、bartik_preprocess_node() となっています。引数の $variables には、ノードテンプレートで利用可能な変数が入っていて、ここで変数の値に手を加えたり、新たに追加したりすることが出来ます。$variables['変数名'] はノードテンプレート内では $変数名 として使えます。

このフックの中に、以下の記述を追加します。

  $node = $variables['node'];
  if ($variables['page'] && $node->type == 'forrent') {

    // 室内写真の拡大表示を追加
    if (isset($variables['content']['field_inside_picture'])) {
      $items = $variables['content']['field_inside_picture']['#items'];

      // 室内写真の最初の1枚をデフォルトの拡大表示として使用する。
      $field = field_view_value('node', $node, 'field_inside_picture', $items[0], array(
        'type' => 'image',
        'settings' => array(
          'image_style' => 'inside_picture',
        ),
      ));

      $field['#prefix'] = '<div class="inside-picture-front">';
      $field['#suffix'] = '</div>';
      $variables['content']['field_inside_picture_default'] = $field;
    }
  }

これで変数 $field_inside_picture_default が追加できたので、ノードテンプレート(node--forrent.tpl.php)の拡大画像を表示する箇所(図1 の点線部分に該当する箇所)に、以下のコードを追加します。

<?php print render($content['field_inside_picture_default']); ?>

拡大表示のデフォルトが表示されました。

もうひとつ、スクリプトを動作させるための準備として、室内写真のサムネイルに、前回追加した「拡大表示用画像スタイル」のファイルへのリンクを設定します。スクリプトの内容としては、「クリックしたサムネイル画像の親要素(a)の href 属性の値を、拡大表示エリアに表示する」という感じになります。

ここで賃貸物件の表示管理画面(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)にアクセスし、「室内写真」フィールドの操作ボタンをクリックして「画像へのリンク」セレクトボックスから「画像スタイルのファイルへのリンク」を選択、...といきたいところですが、「画像へのリンク」セレクトボックスには、「コンテンツ」と「ファイル」のオプションしかありません。「コンテンツ」はノードページへのリンクを設定し、「ファイル」はオリジナルファイルへのリンクを設定します。リサイズなどのエフェクトを通した画像へのリンクは、このままでは設定できません。

これに画像スタイルのエフェクトを通したファイルへのリンクを設定できるよう、カスタムモジュールを使って機能を拡張します。

カスタムモジュールの作り方を参考に、カスタムモジュールを作成し、有効化してください。そのあと「環境設定」 > 「パフォーマンス」から、「すべてのキャッシュをクリアー」ボタンをクリックして、キャッシュをクリアしてください。

カスタムモジュールに、以下のコードを追加します。

/**
 * Implementation of hook_field_formatter_info_alter()
 */
function custom_field_formatter_info_alter(&$info) {
  // イメージフォーマットの設定に「リンクするファイルの画像スタイル」オプションを追加。
  $info['image']['settings']['image_link_style'] = '';
  $info['image']['module'] = 'custom';
}

/**
 * Implements hook_field_formatter_settings_form().
 */
function custom_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];

  switch ($display['type']) {
    case 'image':
      $element = image_field_formatter_settings_form($field, $instance, $view_mode, $form, &$form_state);

      $image_styles = array('' => t('None (original image)'));
      $image_styles += image_style_options(FALSE);
      $dependent_element_id = 'edit-fields-'. str_replace('_', '-', $field['field_name']) .'-settings-edit-form-settings-image-link';
      $element['image_link_style'] = array(
        '#title' => t('リンクするファイルの画像スタイル'),
        '#type' => 'select',
        '#default_value' => $settings['image_link_style'],
        '#options' => $image_styles,
        '#process' => array('ctools_dependent_process'),
        '#dependency' => array($dependent_element_id => array('file')),
      );
      break;
  }

  return $element;
}

/**
 * Implements hook_field_formatter_settings_summary().
 */
function custom_field_formatter_settings_summary($field, $instance, $view_mode) {
  $display = $instance['display'][$view_mode];
  $settings = $display['settings'];

  $summary = array();
  switch ($display['type']) {
    case 'image':
      $summary[] = image_field_formatter_settings_summary($field, $instance, $view_mode);
      if ($settings['image_link'] && $settings['image_link_style']) {
        $image_link_styles = image_style_options(FALSE);
        $summary[] = t('リンクするファイルの画像スタイル: @style', array('@style' => $image_link_styles[$settings['image_link_style']]));
      }
      break;
  }

  return implode('<br />', $summary);
}

/**
 * Implementation of hook_field_formatter_view()
 */
function custom_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
  $element = array();
  $settings = $display['settings'];

  switch ($display['type']) {
    case 'image':
      // 画像フォーマットのリンクにスタイルを適用
      $element = image_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display);
      if ($settings['image_link'] == 'file' && $settings['image_link_style']) {
        foreach ($items as $delta => $item) {
          $uri = array(
            'path' => image_style_url($settings['image_link_style'], $item['uri']),
            'options' => array(),
          );
          $element[$delta]['#path'] = isset($uri) ? $uri : '';
        }
      }
      break;
  }

  return $element;
}

いきなりちょっと大きなコードになってしまいましたが、これは次の四つのフックの実装です。

フックとは、Drupal のページリクエスト処理の様々なプロセスにおいて、独自のコードを処理に組み込むことができるしくみです。関数名の 'hook_' のところをテーマ名/モジュール名に置き換えて定義することで、それぞれのフックがコールされるタイミングにコールされるようになります。

これらのフックはフィールドのフォーマットの設定(表示設定)に関するものです。これらのフックを有効化するために、モジュール管理ページ(「管理」 > 「モジュール」)から、ページ下「設定を保存」ボタンをクリックし、そのあと「環境設定」 > 「パフォーマンス」から、「すべてのキャッシュをクリアー」ボタンをクリックして、キャッシュをクリアしてください。

もういちど、賃貸物件の表示管理画面(「管理」 > 「サイト構築」 > 「コンテンツタイプ」 > 「賃貸物件」 > 「表示管理」)にアクセスし、「室内写真」フィールドの操作ボタンをクリックして「画像へのリンク」セレクトボックスで「ファイル」を選択してみてください。

画像へのリンクに「ファイル」を選択すると、「リンクするファイルの画像スタイル」を選択できるセレクトボックスが現れ、設定されている画像スタイルの中から選択できるようになりました。

ここで拡大表示用の画像スタイル('inside_picture')を選択し、すぐ下の「更新」ボタンをクリックした後、ページ下の「保存」ボタンをクリックして設定を保存してください。

コンテンツにアクセスすると、室内写真のサムネイルに拡大表示用画像スタイルのファイルへのリンクが設定されています。これでようやく準備は整いました。あとはスクリプトをDrupal に読み込ませるだけです(ここではスクリプトの中身までは触れません。興味のある方はデモサイトを覗いてみてください)。

さきほど少し編集した template.php('sites/all/themes/bartik/template.php')の bartik_preprocess_node() に、以下のコードを追加します。

  // 室内写真のスクロールスクリプトを読み込む。
  drupal_add_js(drupal_get_path('theme', 'bartik') .'/js/bartik.js');

スクリプトファイルはテーマに jsフォルダを作成し、そこに配置しました('sites/all/modules/themes/bartik/js/bartik.js')。drupal_add_js() は、引数に js ファイルのパスを渡すと、ページに読み込んでくれます。drupal_get_path() は、テーマやモジュールのパスを返します。 

これでサムネイル拡大表示部分の作成は完了です。

図5 はスクロールの確認のために室内写真を追加し、スクリプトを読み込んだところです。