在Drupal 6中覆盖用户注册表单

3

我希望能够在Drupal 6中自定义用户注册表单。

我已经找到了数千个教程,可以向我展示如何覆盖整个表单的输出结构,但是我想移动表单元素等等,我似乎无法找到最好的方法来实现这一点。

5个回答

9
要进一步解释Jeremy的回答,你需要学习Drupal的表单APIuser_register()。简而言之,你需要构建一个关联数组;数组中的每个元素都对应一个表单元素。
数组中的每个表单元素都是它自己的关联数组。它们可以有不同的类型:文本字段、选择菜单、复选框等:请参阅表单API参考以了解所有类型。
每个表单元素还可以有一个权重:这是你如何排列元素的方式。权重较低的元素会在表单中先出现于权重较高的元素。
你可以使用fieldset来将元素分组。当你使用一个fieldset时,它会创建一个带有自己权重值的表单部分。

假设你有一个包含三个字段的表单:姓名公司电子邮件地址。应该首先显示姓名,其次是公司,第三是电子邮件地址。可以这样指定表单:

$form['name'] = array(
  '#type' => 'textfield',
  '#title' => t('Name'),
  '#weight' => 1,
);
$form['company'] = array(
  '#type' => 'textfield',
  '#title' => t('Company'),
  '#weight' => 2,
);
$form['email'] = array(
  '#type' => 'textfield',
  '#title' => t('E-mail address'),
  '#weight' => 3,
);

请注意#weight键。如果您希望公司出现在电子邮件地址之后,您需要将$form['company']['#weight']设置为比3更高的值。
现在假设您想将姓名公司分组到名为个人信息的字段集中。您的表单现在看起来像这样:
$form['personal'] = array(
  '#type' => 'fieldset',
  '#title' => t('Personal information'),
  '#weight' => 1,
);
$form['personal']['name'] = array(
  '#type' => 'textfield',
  '#title' => t('Name'),
  '#weight' => 1,
);
$form['personal']['company'] = array(
  '#type' => 'textfield',
  '#title' => t('Company'),
  '#weight' => 2,
);
$form['email'] = array(
  '#type' => 'textfield',
  '#title' => t('E-mail address'),
  '#weight' => 3,
);

请注意,现在$form['personal']的数组元素包括NameCompany
如果您想在字段集中使Name显示在Company之后,请将其#weight设置为高于2。由于Name现在是一个具有较低#weight的字段集的一部分,即使您将$form['personal']['name']['#weight']设置为4,它也不会使Name显示在E-mail address之后。
因此,您要尝试使用hook_form_alter()来修改user_register表单,以更改某些表单元素的权重,创建自己的字段集,并将某些表单元素移动到新创建的字段集中。
有许多方法可以在主题中完成此操作,但我更喜欢创建自定义模块。创建自定义模块,并实现hook_form_alter()
function test_form_alter(&$form, $form_state, $form_id) {
  if ($form_id === 'user_register') { // Only modify the user registration form
    // Before you can get down to business, you need to figure out the
    // structure of the user registration form. Use var_dump or kpr to dump
    // the $form array. 

    // Note: if you want to use kpr on the user registration form, give
    // anonymous permission to see devel information.
    // kpr($form);

    // Move Name field to after E-Mail field
    $form['name']['#weight'] = 2;
    $form['mail']['#weight'] = 1;

    // Group Name and E-mail together into a fieldset
    $form['personal_info'] = array(
      '#type' => 'fieldset',
      '#title' => t('Personal information'),
    );

    $form['personal_info']['name'] = $form['name'];
    $form['personal_info']['mail'] = $form['mail'];

    // The last block only copied the elements: unset the old ones.
    unset($form['name']);
    unset($form['mail']);
  }
}

在更复杂的表单中,将事物从一个字段集移动到另一个字段集可能会在提交表单时产生意外结果。这是因为$form ['name']$form ['group']['name']不同,并且与$form ['other_group']['name']也不同。在user_register表单上,您大部分时间都不必担心这个问题,但请查看#tree和#parents手册页面以获取更多信息。
这涵盖了修改用户注册表单中现有字段的内容:如果要添加新字段,我强烈建议使用Content Profile。如果要自己创建自定义字段,则会变得更加复杂,因为您将不得不实现自己的验证和提交处理程序。内容配置文件为您处理此过程:请查看其自述文件,了解如何激活其用于注册表单。

3
使用hook_form_alter,您可以对表单进行任何操作。
例如,更改权重可以更改在页面上的位置。
如果您尝试:
MYMODULE_form_user_profile_form_alter(&$form, $form_state) {
// do your processing here
var_dump($form);
}

将MYMODULE替换为您的模块名称。

您将看到表单的结构,您可以在其中更改值以更改标签权重、描述等。


这个应该放在哪里?是放在主题目录下的template.php文件中吗? - Tim
你需要将这段代码放在自定义模块中,在Drupal 7中,你也可以在主题中执行类似的操作。 - googletorp

2
在一个模块中,首先使用hook_theme()函数,假设你的模块名称为'd6_forms':
function d6_forms_theme() {
  return array(
    'user_register' => array(
      'template' => 'templates/user-register-form',
      'arguments' => array('form' => NULL),
    ),        
  );
}

这将使user_register表单在指定的文件夹中查找模板。因此,请确保在您的模块文件夹中有一个名为“templates”的文件夹,并包含一个名为“user-register-form.tpl.php”的文件。
您会注意到,在hook_theme()中,模板文件(.tpl.php)的扩展名未提供。这是正常的,您不需要在那里指定它。但请确保模板具有该扩展名,并且它的名称不仅仅是'user-register-form.php'!
在那个模板文件中,您可以访问$form变量,所以打印出来看看有哪些字段。推荐使用devel模块,因为它能够以漂亮的方式(使用dpm())打印大型Drupal数组。如果您没有Devel模块或不想使用它,则也可以使用以下代码:' . print_r($form, 1) . '';。
要打印一个字段,只需使用,这将打印该字段并确保它按预期工作。因此,例如,如果您想在$form数组中打印“name”字段,只需使用。
您不必打印每个字段!只需打印您想要移动的字段即可(对于基本的Drupal注册表单,大约有3个:名称、电子邮件和提交)。要打印所有剩余的字段,请在您的模板末尾使用。
重要的是,您不要忘记这一点,因为$form变量包含绝对需要让您的表单工作的内容(例如令牌等)。因此,在制作表单模板时,很好的标准行为是首先在模板底部打印该代码片段。
以下是一个小型注册表单模板的完整示例,带有一些基本的HTML:
<?php 
  // What is in that $form var ? To check, uncomment next line
  // print '<pre>' . print_r($form, 1) . '</pre>'; 
?>

<div style="background-color:#ddd;padding:10px;">
  <?php print drupal_render($form['name']); ?>
  <?php print drupal_render($form['mail']); ?>
</div>

<div>
  <?php print drupal_render($form['submit']); ?>
</div>                 

<?php print drupal_render($form); ?>

用户注册是否有默认模板?tpl.php?是否可以在某个地方仅修改该模板? - PartySoft

0

谢谢。我目前正在使用配置文件模块,但我真正想要的是覆盖表单的布局,比仅仅使用css能提供的更多。也就是说,我不想将字段分组到单独的fieldset中等。 - Tim

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接