パスの設定

だいたい形になってきたところで、賃貸物件ノードへのパスを設定することにします。現在 'node/{ノード ID}' というパスでアクセス出来ていると思いますが、これを賃貸物件検索の追加の要件にあるように 'forrent/content/{ノード ID}' というパスでアクセス出来るようにします。

Drupal では、通常このようなパスの設定には url エイリアスというしくみが使われます。これは設定したいページごとに、設定したいページの数だけ、エイリアスを作成する、というものです。基本ページの作成では、この方法でパスを設定しました。しかし、不動産物件検索サイトのような、何千何万件というコンテンツを扱うとなると、これでは大変です。

いくつか方法はありますが、ここでは「Views モジュールでノードページを作る」という方法を採りたいと思います。Views モジュールはコンテンツのリストを作成するのによく使われますが、実はノードページの作成も簡単に出来ます。

物件ノードビューの作成

モジュールのインストールを参考に、Views モジュールをインストールしてください(Views の場合は、同梱の Views UI モジュールも有効化してください)。

「管理」 > 「サイト構築」から、Views のリンクをクリック。

これが Views の管理ページです。さっそく物件ノードページを作成してみましょう。左上の「add new view」をクリックしてください。

新規のビューの設定です。「View name」に「物件ノードページ」と入力、表示に「コンテンツ」、タイプには「賃貸物件」を選択します。「Create a page」にチェックを入れ、パスに「forrent/content」と入力します。「Display format」は、「Unformatted list」 of 「full posts」となるように選択し、「Items to display」は「1」、「Use a pager」のチェックは外します。この設定でページ下「Save & exit」ボタンをクリックしてください。

前回までに作成した賃貸物件ノードによく似たページが表示されたと思います。これは今 Views で作成したページです。パスは「forrent/content」となっているはずです。

Views は様々なコンテンツのリストを表示します。今、ソート(並び順)はデフォルト(新着順)のまま、「Items to display(表示するアイテム数)」を「1」に設定したので、ここでは「賃貸物件」ノードを新着順に1つだけ表示しているわけです。「Items to display」を「10」に設定すれば、10 件表示されます((もちろん)該当するコンテンツが10件あれば、...ですが)。一般的に、コンテンツのリストを表示する場合は要約(コンテンツの一部)を表示することが多いと思いますが、「Display format」で「full posts」を選択したので、フルモード(ノードページと同じ内容)で表示されています。

これに、URL からの引数(※1)としてノード ID を渡すことで、表示するノードを特定するようにします。

物件ノードビュー: URL からの引数の設定

「物件ノードページ」と書いてあるタイトルの右上にマウスをかざすと、コンテキストリンクが表示されるので、「Edit view」をクリックしてください。

ビューの設定画面です。ここでまず、右側の「Advanced」をクリックして、アドバンスエリアを表示させてください。これからコンテキストフィルターの設定をします。コンテキストフィルターとは、URL からの引数によって、表示するリストにフィルタリングを加えることです。URL からの引数とは、表示するページのパスの後に続く、スラッシュ('/')で区切られた値のことです。この場合は 'forrent/content' 以下の値のことで、例えば、リクエストのパスが 'forrent/content/10' なら、URL からの引数は「10」となります。URL からの引数が「10」なら、ノード ID が「10」のノードを表示させるようにする、ということです。

説明だけでは分かりにくいので、とりあえずやってみましょう。「CONTEXTUAL FILTERS」の右側の追加ボタンをクリックしてください。

コンテキストフィルターの追加ダイアログが開きます。左上の For のところは、ここでは「All displays」を選択します。次にフィルターのセレクトボックスは「コンテンツ」を指定してください。

「コンテンツ」に関係する引数がリストアップされます。この中から「コンテンツ: Nid」という項目を探してチェックを入れ、「Apply (all displays)」ボタンをクリックしてください。

引数「コンテンツ: Nid」の設定に入ります。WHEN THE FILTER VALUE IS NOT IN THE URL(URL からの引数がない場合)のところの設定では、Show "Page not found" にチェックを入れます。

「EXCEPTIONS」をクリックし、「Exception value」のところ(デフォルトで「all」と入力されています)に「%」と入力します。

少しスクロールしたところの WHEN THE FILTER VALUE IS IN THE URL OR A DEFAULT IS PROVIDED(URL からの引数がある場合)のところの設定では、「Override title」にチェックを入れ、テキストフィールドには「%1」と入力します。こうすることで、引数で指定したノードのタイトルが、ページタイトルとして適用されるようになります。

「Specify validation criteria(引数を検証する)」にチェックを入れ、出現した項目の中の「Validator」に「コンテンツ」を選択、コンテンツタイプは「賃貸物件」にチェックを入れます。「Validate user has access to the content(アクセス権の検証)」チェックボックスにチェックを入れ、「Access operation to check(適用するオペレーション)」では「ビュー」を選択します。「Filter value format」はノード ID 、「Action to take if filter value does not validate(検証にパスしなかった場合の処置)」は「Show "Page not found"」を選択します。

そこまで設定したら、ダイアログの「Apply( All displays)」ボタンをクリックし、ダイアログを閉じます。ページ右上の「保存」ボタンをクリックして、設定を保存してください。

こんなページが表示されたでしょうか。これは図9 の WHEN THE FILTER VALUE IS NOT IN THE URL(URL からの引数がない場合の設定)のところの設定で、Show "Page not found" としたためです。実はこのビューのページ('forrent/content')はそのままでは使用しません。引数があるときだけ表示するようにします(※2)。このページに引数として、作成したノード ID を入れてみてください。「forrent/content/{ノード ID}」となります。

引数を加えたパスでアクセスすると、このようなページが表示されます。図10 のところでページタイトルを設定しているので、ノードのタイトルが適用されています(図4 と比較してみてください)。「賃貸物件」ノードページと違うところといえば、赤で囲った部分にタイトルが重複して表示されているのと、前回作成したサムネイル拡大表示部分が無いことくらいでしょうか。これはテンプレートの処理の中で、このページがノードページとして扱われていないためです。これを修正するのに、カスタムモジュールに以下の記述を追加します。

/**
 * Implementation of template_preprocess_node()
 */
function custom_preprocess_node(&$variables) {
  // bukken_node ビューのページは、ノードページとして扱う
  if (isset($variables['view'])) {
    if ($variables['view']->name == 'bukken_node') {
      $variables['page'] = TRUE;
    }
  }
}

これは前回、サムネイルの拡大表示の設定のときにも使用したテンプレート前処理関数(template_preprocess_node())です。'template_' の部分をテーマ/モジュール名に置き換えて関数名を定義するため、custom_preprocess_node() となっています。テーマではなくモジュールに記述するのは、デザインの変更などでテーマを切り換えたときにも、そのまま使えるようにするためです。テンプレート処理の中で、ノードが単体ページとして扱われるかどうかは、変数 $page で判断されるため、これを修正しました。

モジュール管理ページ(「管理」 > 「モジュール」)にアクセスし、そのままページ下の「設定を保存」ボタンをクリックして、モジュールの設定を再構築してください。そのあと「管理」 > 「環境設定」 > 「パフォーマンス」から、「すべてのキャッシュをクリアー」ボタンをクリックして、キャッシュをクリアしてください。

ふたたび新しいコンテンツページ('forrent/content/{ノード ID}')にアクセスすると、重複していたタイトルが消え、サムネイル拡大表示部分が表示されました。これでデフォルトのノード('node/{ノード ID}')と全く同じページ(※3)が 'forrent/content/{ノード ID}' で表示されるようになりました。

アウトバウンドの設定

これで意図したパスでコンテンツにアクセス出来るようになりましたが、ひとつ問題があります。このままでは Drupal のシステムが内部リンクを生成する際、依然 'node/{ノード ID}' というパスを生成してしまいます。

これを修正するため、カスタムモジュールに以下のコードを追加します。

/**
 * Implementation of hook_url_outbound_alter()
 */
function custom_url_outbound_alter(&$path, &$options, $original_path) {
  $args = explode('/', $path);

  // 物件ノードページの url エイリアスは設定していないので、ここで設定する。
  // 物件ノードのパスは {forrent|forsale}/content/{nid} です。
  if (count($args) == 2 && $args[0] == 'node' && is_numeric($args[1])) {
    $type = node_load($args[1])->type;

    if ($type == 'forrent') {
      $args[0] = $type;
      array_splice($args, 1, 0, array('content'));
      $path = implode('/', $args);
    }
  }
}

これは hook_url_outbound_alter() というフックで、Drupal のシステムが内部リンクのパスを生成する際、必ず通過する関数 url() の中でコールされます。したがって、ここでの操作は動的に生成される内部リンクすべてに適用され、賃貸物件のノードのパスはすべて、'forrent/content/{ノード ID}' で生成されるようになります。

モジュール管理ページ(「管理」 > 「モジュール」)のページ下「設定の保存」ボタンをクリックし、モジュールの設定を再構築してください。そのあとキャッシュをクリアしてください。これで、物件ノードページのパスの設定は完了です。


※1 URL からの引数: 割り当てられたパスの後に続く、スラッシュ('/')で区切られた値。

※2 ビューのパスに「forrent/content/%」(最後にパーセント文字を追加)と設定すれば、図9 の設定をしなくても同様の動作となります。ここでそうしないのは、あとでこれをメニューに登録するためです。(そのあたりについては、またのちほど説明します。)

※3 管理者権限でアクセスしたときに表示される「編集」タブが表示されないので、その点まで考えると全く同じではありません。しかしコンテキストメニュー(コンテンツ部分の右上にマウスオーバーしたときに現れるショートカットリンク)があるので、機能的には問題ないでしょう。