基本ノード(nid "123")が存在し、モジュールは_hook_menu
_を使用して2つのパスを登録しました:
first/%node
_second
両方のページコールバックはnode_page_view($node)
を使用してノードの全ページビューを表示しますが、2番目のコールバックはnode_load(123)
を使用して_$node
_への参照を取得します。
したがって、_http://localhost/first/123
_と_http://localhost/second
_は、ユーザーに関する限り同じように見えます。
ただし、_hook_preprocess_page
_は最初のパスでのみnode
変数を受け取るため、Drupalは_node_load
_を検出すると_%node
_以外の処理を実行しますワイルドカード、_hook_preprocess_page
_がどちらの場合でも_$node
_への参照を受け取るようにするための任意の考え? (2番目のパスですべてを内部で処理すると、2番目のパスから最初のパスにリダイレクトするよりもはるかにわかりやすいURLが生成されるため)。
例:
_<?php
/**
* Implementation of hook_preprocess_page().
*/
function mymodule_preprocess_page(&$vars){
if (@isset($vars['node'])) echo '<h1>[mymodule.module] Node is defined</h1>';
else echo '<h1>[mymodule.module] Node is NOT defined</h1>';
}
/**
* Implementation of hook_menu().
*/
function mymodule_menu(){
return array(
'first/%node' => array(
'title' => 'First callback',
'page callback' => 'mymodule_page_first',
'page arguments' => array(1),
'access callback' => TRUE,
),
'second' => array(
'title' => 'Second callback',
'page callback' => 'mymodule_page_second',
'access callback' => TRUE,
),
);
}
/**
* Page callback for url "http://localhost/first/123".
*/
function mymodule_page_first($node){
echo '<h1>[mymodule.module] Function mymodule_page_first</h1><pre>';
var_dump($node);
echo '</pre>';
return node_page_view($node);
}
/**
* Page callback for url "http://localhost/second".
*/
function mymodule_page_second(){
$node = node_load(123); //the ID of an existing node
echo '<h1>[mymodule.module] Function mymodule_page_second</h1><pre>';
var_dump($node);
echo '</pre>';
return node_page_view($node);
}
_
(ファイルのソース_mymodule.module
_)
これまでの私の最高の/唯一の希望は、_node_page_view
_のソースを調査し、_node_page_view
_が呼び出された瞬間と_module_invoke_all
_が呼び出された瞬間の間に何が起こるかを見つけるまでトリガーするすべての関数ですフックが呼び出されるトリガー。
「first /%node」パスに対してmymodule_preprocess_page()
が呼び出されると、パスがモジュールのノードに関連付けられているため、ノードオブジェクトが取得されます。
パスにノードIDとしてマークされているノードIDへの参照が含まれていないため、Drupalはノードオブジェクトを「/ admin/content/node」などのパス(Drupal 6パス)に関連付けることができません。 Drupal Webサイトに数百のノードが含まれる可能性があることを考慮して、どのノードオブジェクトがこのようなパスに対して返すかDrupal
あなたの質問は、「Drupalある場合にノードオブジェクトを関連付けることはできますが、別の場合には関連付けないことはできますか?」です。
答えは template_preprocess_page() コードにあります。このコードは、テンプレートpage.tpl.phpがレンダリングされる前に実行されます。
その関数には、次のコードがあります。
_if ($node = menu_get_object()) {
$variables['node'] = $node;
}
_
menu_get_object() のデフォルトパラメータは_$type = 'node', $position = 1, $path = NULL
_です。これは、template_preprocess_page()
が、位置#1のプレースホルダに関連付けられているノードオブジェクトを要求していることを意味します。たとえば、arg(1)
から返される値。
menu_get_object()
のソースを見ると、実行されているコードが次のようになっていることがわかります。
_function menu_get_object($type = 'node', $position = 1, $path = NULL) {
$router_item = menu_get_item($path);
if (isset($router_item['load_functions'][$position]) && !empty($router_item['map'][$position]) && $router_item['load_functions'][$position] == $type . '_load') {
return $router_item['map'][$position];
}
}
_
デフォルトの引数を使用して、関数はルートアイテム#1に関連付けられた読み込み関数がnode_load()
であることを確認します。ロード関数がそれである場合、ロード関数によって返された値を呼び出し関数(この場合はtemplate_preprocess_node()
)に返します。
ノードオブジェクトを自動的に取得するには、メニューコールバックで「second /%node」のようなパスを使用する必要があります(デフォルトのmenu_get_object()
引数と互換性があります)。唯一の問題は、そのようなパスの場合、ノードIDを渡す必要があることです。 URLが http://example.com/second の場合、Drupalは、プレースホルダーの必須パラメーターが渡される必要があるため、404エラーページを表示します。
この問題を解決するには、モジュールが2つのメニューコールバックを定義する必要があります。1つは「秒」に関連付けられ、もう1つは「秒/%node」に関連付けられています。最初のメニューコールバックはノードオブジェクトを取得しませんが、2番目のメニューコールバックはノードオブジェクトを取得します(そしてmymodule_preprocess_page()
もそれを取得します)。
別の方法として、mymodule_preprocess_page()
のコードを次のようなものに変更する必要があります。
_/**
* Implementation of hook_preprocess_page().
*/
function mymodule_preprocess_page(&$vars){
// Check if the page being served is one of the pages handled by the module.
if (arg(0) == 'first' || arg(0) == 'second') {
if (isset($vars['node'])) {
// The page is a node page.
}
else {
$vars['node'] = mymodule_load_the_default_node();
}
// …
}
}
_
Drupalは、URLに '%node'ワイルドカードを表示すると、引数がノードIDを参照していることを認識しているため、$node
変数を自動的に設定し、hook_preprocess_page
。「2番目の」メニューコールバックで、$vars['node']
変数を設定する必要があります。これにより、hook_preprocess_page
を使用できます。
リファレンス: http://drupal.org/node/22417