it-swarm-ko.tech

hook_preprocess_page : "node_load () + node_page_view ()"대 "% node + node_page_view ()"

기본 노드 (nid "123")가 존재하고 모듈이 hook_menu를 사용하여 두 경로를 등록했습니다.

  • first/%node
  • second

두 페이지 콜백 모두 node_page_view($node)을 사용하여 노드의 전체 페이지보기를 표시하지만 두 번째 콜백은 추가로 node_load(123)을 사용하여 $node에 대한 참조를 가져옵니다.

따라서 http://localhost/first/123http://localhost/second는 사용자에 관한 한 동일하게 보입니다.


그러나 hook_preprocess_page는 첫 번째 경로로만 node 변수를받습니다. 따라서 Drupal은 node_load 와일드 카드를 볼 때 분명히 %node 이상의 작업을 수행합니다. hook_preprocess_page가 두 경우 모두에서 $node에 대한 참조를 받도록하는 것이 무엇인지 아십니까?? (두 번째 경로에서 내부적으로 모든 것을 처리하면 두 번째 경로에서 첫 번째 경로로 리디렉션하는 것보다 훨씬 더 친숙한 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 후크를 트리거합니다.

2
wildpeaks

mymodule_preprocess_page()이 "first/% node"경로에 대해 호출되면 경로가 모듈의 노드와 연결되어 있으므로 노드 개체를 가져옵니다.
Drupal은 노드 ID로 표시된 노드 ID에 대한 참조가 경로에 포함되어 있지 않기 때문에 "/ admin/content/node"(Drupal 6 경로)와 같은 경로와 노드 개체를 연결할 수 없습니다. Drupal 웹 사이트가 수백 개의 노드를 포함 할 수 있다는 점을 고려할 때, 이러한 경로에 대해 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 오류 페이지가 표시됩니다.
이 문제를 해결하기 위해 모듈은 두 개의 메뉴 콜백을 정의해야합니다. 하나는 "second"와 연관되고 다른 하나는 "second/% node"와 연관됩니다. 첫 번째 메뉴 콜백은 노드 객체를 가져 오지 않고 두 번째 메뉴 콜백은 노드 객체를 가져옵니다 (그리고 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();
    }
    // …
  }
}
3
kiamlaluno

Drupal URL에서 '% node'와일드 카드가 표시되면 인수가 노드 ID를 참조하고 있음을 알고 있으므로 $node 변수를 자동으로 설정하여 hook_preprocess_page. "두 번째"메뉴 콜백에서 $vars['node'] 변수를 설정해야합니다. 이렇게하면 hook_preprocess_page를 사용할 수 있습니다.

참조 : http://drupal.org/node/22417

1
Chaulky