2

我有一个构建包含字段集的表单的模块。我不想使用该<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;
}

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

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

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

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

4

5 回答 5

2

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

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

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

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

于 2010-05-05T06:26:54.460 回答
1

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

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

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

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

$fieldsetElement = array(
   //$child is the key of whatever child you need in the fieldset
   //you may have to alter this for multiple children, stringing 
   //together multiple drupal_render calls on each children
   //(#children needs to be a string.. unless your theme can handle the array)
   '#children'=>drupal_render($form['Basic Account Info'][$child]),
   '#attributes'=>array(),//set real attributes
   '#title'=>$form['Basic Account Info']['#title']
);
$form['Basic Account Info'] = array(
  '#type'=>'markup',//not really needed, is default
  '#value'=>theme('mymod_fieldset',$fieldsetElement)
);

超级骗子黑客,可能会导致与表单状态断开连接和潜在的验证失败——但两者都可以通过表单 api 的反复试验来修复。我不推荐这个,除非你真的想用 PHP 和 drupal 表单 API 弄脏你的手,但这确实是唯一的方法,除非你可以在你的模块中没有可变的字段集主题......也许试试前缀和后缀?

于 2011-09-21T15:06:43.827 回答
0

我遇到了同样的问题。

您需要使用#theme_wrappers而不是#theme

'#type' => 'fieldset',
'#theme_wrappers' => array('mymodule_fieldset'),
于 2013-02-22T23:41:16.660 回答
0

这只是我的想法,但也许区别在于 fieldset 不是表单元素,而只是分隔符或grouper,如果您愿意的话。也许#theme回调仅适用于表单元素?

于 2010-05-04T07:59:38.033 回答
0

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

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

  • 字段集不是$form['Basic Account Info']
  • 需要清除缓存。
  • $form['Basic Account Info']['#theme'] 在稍后的代码执行中丢失/覆盖。

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

  • 需要加载 user.pages.inc 文件
于 2010-05-04T10:23:23.007 回答