来自WebService的Drupal模块页面

时间:2015-12-31 08:44:05

标签: php web-services drupal drupal-7 drupal-modules

我正在寻找一个优雅(尽可能)的解决方案来在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,使其变得简单)。

关键是,我使用webservice来获取列表和每个页面。因此,页面回调会调用我的网络服务(例如http://api/articles)并根据结果构建页面。

有效。但是,如果我想设置每个页面的标题,我必须使用标题回调,这是另一个功能。而且,我不想再打电话给我的网络服务。 为清楚起见:http://api/articles/id,在一个结果中返回标题和内容。所以使用两种方法让我调用这个url两次:一个用于标题,另一个用于内容。

有没有更好的方法来解决这个问题?

非常感谢,

1 个答案:

答案 0 :(得分:1)

最简单,最快速的解决方案是在'module / articles /%'菜单项的页面回调中使用 drupal_set_title()。请参阅:https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_set_title/7

但是,通过这种方法,您只能解决您的特定问题。更通用和更优雅的解决方案是具有可以加载和静态缓存文章的功能。例如,假设您的模块名为 article 。首先定义一个这样的函数:

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()。

我个人更喜欢第二种方法,因为它允许在请求期间的任何时候加载文章而无需进行额外的外部调用,因此它更通用。

另外,当您在菜单挂钩中进行更改时,不要忘记清除缓存。