2015-12-31 39 views
1

我正在尋找一個優雅的(儘可能)解決方案來在Drupal網站中構建特定頁面。來自WebService的Drupal模塊頁面

於是,我開始有:

function hook_menu() { 
    $items = array(); 

    $items['module/articles'] = array(
     'title' => 'List of articles', 
     'page callback' => 'show_article_list', 
     'access arguments' => array('access content'), 
     'type' => MENU_CALLBACK, 
    ); 
    $items['module/articles/%'] = array(
     'title' => '', 
     'page callback' => 'show_article_page', 
     'page arguments' => array(2), 
     'access arguments' => array('access content'), 
     'type' => MENU_CALLBACK, 
    ); 

    return $items; 
} 

的第一項回到我的文章的列表,並且第二內建一個頁面的文章(其中是一個id,使它很簡單)。

問題是,我使用web服務來獲取列表和每個頁面。因此,頁面回調打電話給我的web服務(例如http://api/articles),並根據結果構建頁面。

它的工作原理。但是,如果我想設置每個頁面的標題,則必須使用標題回調,這是另一個功能。而且,我不想再撥打我的網絡服務。 要明確:http://api/articles/id,返回一個結果中的標題和內容。所以使用兩種方法讓我調用這個URL兩次:一個用於標題,另一個用於內容。

有沒有更好的解決方案來解決這個問題?

提前許多感謝,

回答

1

造成這種情況的最簡單和最快的解決方法是使用drupal_set_title()在頁面回調的「模塊/用品/%」菜單項。請參閱:https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_set_title/7

但是,使用此方法只能解決特定問題。更通用和優雅的解決方案是具有一個可以加載和靜態緩存文章的函數。例如,假設您的模塊名爲文章。您首先定義一個函數是這樣的:

function article_load($id) { 
    // The $articles is an array of article objects from the webservice. 
    $articles = &drupal_static(__FUNCTION__); 
    if (!isset($articles[$id])) { 
    $articles[$id] = call_to_your_webservice_to_load_the_article($id); 
    } 
    return $articles[$id]; 
} 

然後,有一件事是,你可以在你的代碼中使用此功能的地方。第二件事是你也可以在菜單中使用所謂的「魔術通配符」。所以,你可以有這樣的:

$items['module/articles/%article'] = array(
    'title' => '', 
    'page callback' => 'show_article_page', 
    'page arguments' => array(2), 
    'access arguments' => array('access content'), 
    'type' => MENU_CALLBACK, 
); 

這意味着,之前Drupal將調用任何菜單回調函數(頁,訪問,標題),它會先檢查是否有名稱的函數article_load存在,將首先調用該函數並將結果傳遞給特定的菜單函數回調。而且由於article_load會靜態緩存數據,因此它會在第一次調用時調用您的webservice,而在所有其他調用中它將只返回緩存的文章對象。因此,您還可以再次使用標題回調,並且不要在頁面回調中使用drupal_set_title()。

我個人更喜歡第二種方法,因爲它允許在請求期間的任何時候加載文章而不需要額外的外部調用,所以它更通用。

另外,不要忘記在菜單鉤子中進行更改時清除緩存。

+0

謝謝你的回答!我正在實施你描述的第二種方法,所以你讓我意識到它是*好方法*。只是一個問題。你說article_load會靜態緩存數據。你的意思是應該自動完成?因爲我手動執行了,使用**&drupal_static(__ FUNCTION __); **(我的測試讓我猜測它不是自動的。) – TiPi

+1

不,緩存不是自動的,你必須用drupal_static()來實現它。所以,當我說「有一個函數可以加載和靜態緩存文章」我的意思是你有一個函數,你必須靜態緩存文章。 –