如何对 drupal 模块中的字段集使用自定义 #theme 函数?
我有一个模块可以构建包含字段集的表单。我不想使用 元素来呈现字段集标题,而是想将此内容放置在
元素中。但我只想更改模块返回的表单的行为,因此我不想将任何新功能放入主题的 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>Basic Account Info</legend>
test
</fieldset>
为什么我的 #theme 函数没有机会替换整个
向模块内的字段集提供 #theme 函数有什么不同?
I have a module that builds a form that includes a fieldset. Instead of using the <legend>
element to render the fieldset title, I want to place this content in a <div>
element instead. But I want to change the behavior only for the form returned by my module, so I don't want to place any new functionality into my theme's template.php file.
In mymod.module I have defined:
// 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;
}
When my page gets rendered, I expected to see the fieldset representing 'Basic Account Info' to be wholly replaced by my test message 'test'. Instead what happens is that the <fieldset>
and <legend>
elements are rendered as normal, but with the body of the fieldset replaced by the test message instead, like this:
<fieldset>
<legend>Basic Account Info</legend>
test
</fieldset>
Why doesn't my #theme function have the chance to replace the entire <fieldset>
element? If I wrap a textfield in this function instead, I am able to completely replace the <input>
element along with its label. Furthermore, if I provide an override in my site's template.php for theme_fieldset, it works as expected and I am able to completely replace the <fieldset>
, so I know it is possible.
What's different about providing #theme functions to fieldsets inside a module?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您是否尝试过重写 theme_fieldset() 而不是使用 #theme 函数?我相信您可以在 .module 文件中执行类似的操作:
这将适用于所有字段集。您可以对您想要影响的字段集对 $element 进行某种检查,然后对所有其他字段集使用默认实现。
看一下: http://api.drupal.org/api/function/theme_fieldset /6
Have you tried overriding theme_fieldset() instead of using the #theme function? I believe you could do something like this in your .module file:
This would apply to all fieldsets. You could do some kind of check on $element for the fieldsets you want to affect and then use the default implementation for all others.
Take a look at: http://api.drupal.org/api/function/theme_fieldset/6
我知道这是一篇旧帖子 - 但我遇到了同样的问题。我想出了一个丑陋的解决办法。这绝对是 Form API 中的一个错误。也许我的临时修复会对某人有所帮助。
我在这里找到(并附加)了一个错误报告: http://drupal.org/node/225698
值得在尝试我的黑客修复之前检查一下。
我不确定此示例中
$form['Basic Account Info']
中的子项是什么,但基本上您可以做的是使用drupal_render()
fieldset 的子级,然后重新创建一个与$form['Basic Account Info']
分开的 fieldset 数组,使用theme()
为其设置主题,并将其传递回表单数组,如下所示标记..超级骗子黑客攻击,可能会导致与表单状态断开连接以及潜在的验证失败——但这两者都可以通过表单 api 的反复试验来修复。我不会推荐这个,除非你真的想亲自接触 PHP 和 drupal 表单 API,但这确实是唯一的方法,除非你可以在模块中没有可变字段集主题……也许尝试一下前缀和后缀?
I know this is an old post -- but I've run into the same issue. I came up with an ugly work around. This is definitely a bug in the Form API. Maybe my temporary fix will be helpful to someone.
I found (and appended) a bug report here: http://drupal.org/node/225698
Worth checking that before trying my hacky fix.
I'm not sure what the children are in
$form['Basic Account Info']
in this example, but basically what you can do is usedrupal_render()
on that fieldset's children, and then recreate a fieldset array separate from$form['Basic Account Info']
, theme it withtheme()
and pass it back to the form array as markup..super-duper hacking, likely causes disconnect with form state and potential validation failure -- but both are fixable by trial and error with the form api. I wouldn't recommend this unless you really want to get your hands dirty with PHP and drupal form API, but that's really the only way, unless you can live without variable fieldset themes in your module... Maybe try prefix and suffix?
这只是我的想法,但也许区别在于字段集不是表单元素,而只是分隔符或分组符(如果您愿意的话)。也许
#theme
回调仅适用于表单元素?This is just off the top of my head but maybe the difference is because a fieldset is not a form element but just a seperator or a grouper, if you will. Maybe the
#theme
callback is only for form elements?代码的概念有效,这意味着您可以做您想做的事情。
有一些事情可以解释为什么它不起作用。
$form['Basic Account Info']
。在进行任何审核之前,请尝试查看
$form
。当我尝试复制您的代码时遇到一个错误:The concept of your code works, meaning you can do what you want to do.
There are some things that can explain why it doesn't work.
$form['Basic Account Info']
.Try to take a look at
$form
before you do any of the moderations. When I tried to copy your code I run into a bug:我也有同样的问题。
您需要使用
#theme_wrappers
而不是#theme
I was having the same issue.
You need to use
#theme_wrappers
instead of#theme