2015-12-31 40 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()来实现它。所以,当我说“有一个函数可以加载和静态缓存文章”我的意思是你有一个函数,你必须静态缓存文章。 –