Drupal 8自定义注册登录表单创建方法及模板实现咨询
嘿,作为Drupal 8新手,自定义注册登录表单确实容易摸不着头脑,之前的方案没用大概率是没踩对Drupal的核心套路~我给你一步步拆解具体实现方法,顺便解答你关于模板的问题!
一、先搭好自定义模块的架子
Drupal 8所有自定义功能都得放在自定义模块里,咱先创建一个简单的模块:
- 在
modules/custom目录下新建文件夹custom_user_forms - 新建
custom_user_forms.info.yml文件,内容如下:
name: Custom User Forms type: module description: Customizes user registration and login forms core_version_requirement: ^8 || ^9 || ^10 package: Custom
- 启用这个模块(后台扩展页面找它,或者用
drush en custom_user_forms -y命令)
二、修改现有表单(新手首选)
直接复用Drupal自带的注册/登录表单逻辑,只修改我们需要的部分,这样不用自己写验证、提交的复杂代码:
1. 自定义注册表单
在custom_user_forms.module文件里添加hook_form_user_register_form_alter钩子,用来修改默认注册表单:
<?php /** * Implements hook_form_FORM_ID_alter() for user_register_form. */ function custom_user_forms_form_user_register_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { // 示例1:添加一个自定义的"昵称"字段 $form['nickname'] = [ '#type' => 'textfield', '#title' => t('Nickname'), '#required' => TRUE, '#weight' => 0, // 调整字段显示顺序,0表示在最前面 ]; // 示例2:修改默认"邮箱"字段的提示文字 $form['account']['mail']['#description'] = t('Please enter a valid email address we can reach you at.'); // 示例3:移除默认的"用户名"字段(如果想让用户用邮箱登录) // unset($form['account']['name']); // 添加自定义验证规则 $form['#validate'][] = 'custom_user_forms_register_validate'; } /** * Custom validation for registration form. */ function custom_user_forms_register_validate(&$form, \Drupal\Core\Form\FormStateInterface $form_state) { $nickname = $form_state->getValue('nickname'); if (strlen($nickname) < 3) { $form_state->setErrorByName('nickname', t('Nickname must be at least 3 characters long.')); } }
2. 自定义登录表单
同样用hook_form_user_login_form_alter修改默认登录表单:
/** * Implements hook_form_FORM_ID_alter() for user_login_form. */ function custom_user_forms_form_user_login_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) { // 示例1:默认勾选"记住我" $form['remember_me']['#default_value'] = TRUE; // 示例2:添加一个自定义的"帮助链接" $form['help_link'] = [ '#markup' => '<p><a href="/forgot-password">Forgot your password?</a></p>', '#weight' => 10, ]; // 示例3:修改登录按钮的文字 $form['actions']['submit']['#value'] = t('Sign In'); }
写完代码后一定要清除缓存(后台配置->性能->清除所有缓存,或者用drush cr命令),不然Drupal不会识别新代码!
三、完全自定义表单(适合彻底改逻辑)
如果自带的表单逻辑满足不了你(比如要加特殊的登录验证、自定义用户创建逻辑),可以自己写一个完全独立的表单:
1. 创建自定义登录表单类
在src/Form/CustomLoginForm.php里写:
<?php namespace Drupal\custom_user_forms\Form; use Drupal\Core\Form\FormBase; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Url; class CustomLoginForm extends FormBase { /** * {@inheritdoc} */ public function getFormId() { return 'custom_login_form'; } /** * {@inheritdoc} */ public function buildForm(array $form, FormStateInterface $form_state) { $form['email'] = [ '#type' => 'email', '#title' => t('Email Address'), '#required' => TRUE, ]; $form['password'] = [ '#type' => 'password', '#title' => t('Password'), '#required' => TRUE, ]; $form['remember_me'] = [ '#type' => 'checkbox', '#title' => t('Remember me'), '#default_value' => TRUE, ]; $form['actions']['#type'] = 'actions'; $form['actions']['submit'] = [ '#type' => 'submit', '#value' => t('Sign In'), '#button_type' => 'primary', ]; // 添加忘记密码链接 $form['forgot_password'] = [ '#markup' => '<p><a href="' . Url::fromRoute('user.pass')->toString() . '">Forgot your password?</a></p>', ]; return $form; } /** * {@inheritdoc} */ public function validateForm(array &$form, FormStateInterface $form_state) { $email = $form_state->getValue('email'); $password = $form_state->getValue('password'); // 这里写自定义验证逻辑,比如检查邮箱是否存在,密码是否正确 $user = user_load_by_mail($email); if (!$user || !\Drupal::service('user.auth')->authenticate($user->getAccountName(), $password)) { $form_state->setErrorByName('email', t('Invalid email or password.')); } } /** * {@inheritdoc} */ public function submitForm(array &$form, FormStateInterface $form_state) { $email = $form_state->getValue('email'); $user = user_load_by_mail($email); // 登录用户 user_login_finalize($user); // 跳转到首页 $form_state->setRedirect('<front>'); } }
2. 配置路由
新建custom_user_forms.routing.yml文件,定义表单的访问路径:
custom_user_forms.login: path: '/custom-login' defaults: _form: '\Drupal\custom_user_forms\Form\CustomLoginForm' _title: 'Custom Login' requirements: _anonymous: 'TRUE'
清除缓存后,访问/custom-login就能看到你的自定义登录表单了!
四、能不能用模板创建这类表单?
答案是可以,但模板只负责修改表单的显示样式,不能处理表单的逻辑(验证、提交)。
Drupal的表单都对应一个Twig模板,比如:
- 注册表单的模板是
user-register-form.html.twig - 登录表单的模板是
user-login-form.html.twig
你可以在自定义模块的templates目录下创建这些模板,覆盖默认的,用来调整HTML结构、样式:
比如创建templates/user-login-form.html.twig:
{# 自定义登录表单模板 #} <div class="custom-login-form"> <h2>{{ 'Sign In'|t }}</h2> {{ form.form_build_id }} {{ form.form_token }} {{ form.form_id }} <div class="form-group"> {{ form.email }} </div> <div class="form-group"> {{ form.password }} </div> <div class="form-group"> {{ form.remember_me }} </div> <div class="form-actions"> {{ form.actions.submit }} </div> {{ form.forgot_password }} </div>
模板里的{{ form.field_name }}对应你在代码里定义的表单元素,你可以自由调整它们的布局、添加自定义HTML类、文字等。但要注意,表单的字段定义、验证逻辑还是得通过前面的模块代码来实现,模板只是“美化”显示。
最后别忘了清除缓存,让模板生效!
内容的提问来源于stack exchange,提问作者Ravina Madhani

