如何在drupal模块中的字段集中使用自定义#theme函数?

时间:2010-05-04 04:54:02

标签: php drupal drupal-fapi drupal-themes

我有一个模块,可以构建一个包含字段集的表单。我希望将此内容放在<legend>元素中,而不是使用<div>元素来呈现字段集标题。但是我想仅为我的模块返回的表单更改行为,所以我不想在主题的template.php文件中添加任何新功能。

在mymod.module中我定义了:

// custom rendering function for fieldset elements
function theme_mymod_fieldset($element) {
  return 'test';
}

// implement hook_theme
function mymod_theme() {
  return array(
    'mymod_fieldset' => array('arguments' => array('element' => NULL)),
    'mymod_form' => array('arguments' => array())
  );
}

// return a form that is based on the 'Basic Account Info' category of the user profile
function mymod_form() {
  // load the user's profile
  global $user;
  $account = user_load($user->uid);

  // load the profile form, and then edit it
  $form_state = array();
  $form = drupal_retrieve_form('user_profile_form', $form_state, $account, 'Basic Account Info');

  // set the custom #theme function for this fieldset
  $form['Basic Account Info']['#theme'] = 'mymod_fieldset';

  // more form manipulations
  // ...

  return $form;
}

当我的页面被渲染时,我希望看到代表“基本帐户信息”的字段集完全被我的测试消息“test”取代。相反,发生的事情是<fieldset><legend>元素被渲染为正常,但是字段集的主体被测试消息替换,如下所示:

<fieldset>
  <legend>Basic Account Info</legend>
  test
</fieldset>

为什么我的#theme函数没有机会替换整个<fieldset>元素?如果我在这个函数中包装一个textfield,我可以完全替换<input>元素及其标签。此外,如果我在网站的template.php中为theme_fieldset提供覆盖,它会按预期工作,我可以完全替换<fieldset>,所以我知道这是可能的。

将#theme函数提供给模块内的字段集有什么不同?

5 个答案:

答案 0 :(得分:2)

您是否尝试过覆盖theme_fieldset()而不是使用#theme功能?我相信你可以在你的.module文件中做这样的事情:

function mymodule_fieldset($element) {
  // do something;
  return $html;
}

这适用于所有字段集。您可以对要影响的字段集的$ element进行某种检查,然后对所有其他字段集使用默认实现。

看看:http://api.drupal.org/api/function/theme_fieldset/6

答案 1 :(得分:1)

我知道这是一篇旧帖子 - 但我遇到了同样的问题。我想出了一个丑陋的工作。这绝对是Form API中的一个错误。也许我的临时修复对某人有帮助。

我在这里找到(并附加)了一个错误报告:http://drupal.org/node/225698

值得在尝试我的hacky修复之前检查一下。

我不确定这个例子中$form['Basic Account Info']中的孩子是什么,但基本上你可以做的就是在该fieldset的子节点上使用drupal_render(),然后重新创建一个与{{{1}分开的字段集数组1}},用$form['Basic Account Info']为主题,并将其作为标记传递给表单数组。

theme()
超级黑客攻击,可能导致与表单状态和潜在验证失败的连接 - 但两者都可以通过api形式的试错来解决。我不推荐这个,除非你真的想弄脏PHP和drupal表单API,但这真的是唯一的方法,除非你可以在你的模块中没有变量fieldset主题...也许尝试前缀和后缀?< / p>

答案 2 :(得分:0)

这只是我的头脑,但可能不同之处在于,如果你愿意,一个字段集不是一个表单元素,而只是一个分隔符或一个石斑鱼。也许#theme回调仅适用于表单元素?

答案 3 :(得分:0)

您的代码的概念有效,这意味着您可以做您想做的事。

有些事情可以解释为什么它不起作用。

  • 字段集不是$form['Basic Account Info']
  • 需要清除缓存。
  • $ form ['基本帐户信息'] ['#theme']在代码执行后期丢失/覆盖。

在执行任何审核之前,请尝试查看$form。当我试图复制你的代码时,我遇到了一个错误:

  • 需要加载user.pages.inc文件

答案 4 :(得分:0)

我遇到了同样的问题。

您需要使用#theme_wrappers代替#theme

'#type' => 'fieldset',
'#theme_wrappers' => array('mymodule_fieldset'),