0

How should I use hook_form_alter() to modify the user login block but not the user login form page? Everything I've tried either modifies both entities or doesn't work, not even using the following hooks.

function mymodule_form_user_login_block_form_alter(&$form, &$form_state, $form_id) {
  // …
}
function mymodule_form_alter(&$form, &$form_state, $form_id) {
  if ($form_id == 'user_login_block') {
    // …
  }
}

2 Answers 2

2

It really depends on what you're trying to accomplish. The user login form has a form ID of user_login_form. That form, with that form ID, may be shown either in the user login block or on the /user page. It is not show twice on the same page - if you're on /user then the block will not be shown. To me, if you want to change that login form, you definitely should be changing it in both places that it appears. For that case, use hook_form_FORM_ID_alter() which in this case is hook_form_user_login_form_alter().

If you simply want to style your block differently, you can use CSS and target the #block-userlogin element or more specifically the #block-userlogin #user-login-form element.

Or, you can alter the block plugin using hook_block_alter().

Or, you can create your own custom block to show your own custom login form.

Or ...

Again, it really depends on what you're trying to do by altering just the block.

5
  • Since I don't want to alter the login page at /user, simply targeting the form ID will not work. My alterations are more involved than CSS will allow, so I need to be able to use a module. It's looking like hook_block_alter() might be my best route. Any resources on how I can use that to target the login block?
    – cofihouse
    Feb 5, 2022 at 5:04
  • I'm not sure if hook_block_alter() will work, since I need to alter the actual elements of the form. I'm guessing hook_block_alter() just alters the build of the block? Am I interpreting that correctly?
    – cofihouse
    Feb 5, 2022 at 5:14
  • Well again, I caution you to think about this - if you're going to add information or add form elements to the login form in one place then you really should do it in all places. To see if hook_block_alter() will do what you want, implement it and print out the $definitions array to see what you have available to change. Worst case, you might have to create a custom form object to replace the contents of the user_login_form inside the block.
    – anonymous
    Feb 5, 2022 at 5:15
  • Also see api.drupal.org/api/drupal/… for other alternatives.
    – anonymous
    Feb 5, 2022 at 5:20
  • The login block shows up in the header. I require alter() to modify some of the wrapper elements on the form fields and make some custom changes to the placeholder text, etc. I'm not adding new form fields. I distinctly need this for theming a block to look different than the user login page. One has a horizontal layout while the other is vertical. That's why I'm asking for this. I know what I need done. I just don't know how to target that user_login_block. It appears this isn't possible without custom building a form, which honestly sucks.
    – cofihouse
    Feb 5, 2022 at 5:21
1

The form used in the login form and in the login page is the one implemented by the Drupal\\user\\Form\\UserLoginForm class. This means that the form ID to check in hook_form_alter() or hook_form_FORM_ID_alter() is the same in both the cases.

Implementing hook_block_view_BASE_BLOCK_ID_alter(), it's possible to alter the rendering output for a block, including the login block.

function mymodule_block_view_user_login_block_alter(array &$build, \Drupal\Core\Block\BlockPluginInterface $block) {
  // Alter the login form, which is stored in $build['user_login_form'].
  // This example changes the size of the name and password fields.
  $build['user_login_form']['name']['#size'] = 18;
  $build['user_login_form']['pass']['#size'] = 18;
}

The plugin ID for the login block is given in the annotation for the UserLoginBlock class. The content of the $build array is returned from UserLoginBlock::build().

  $form = \Drupal::formBuilder()->getForm('Drupal\\user\\Form\\UserLoginForm');
  unset($form['name']['#attributes']['autofocus']);

  unset($form['name']['#description']);
  unset($form['name']['#attributes']['aria-describedby']);
  unset($form['pass']['#description']);
  unset($form['pass']['#attributes']['aria-describedby']);
  $form['name']['#size'] = 15;
  $form['pass']['#size'] = 15;

  $placeholder = 'form_action_p_4r8ITd22yaUvXM6SzwrSe9rnQWe48hz9k1Sxto3pBvE';
  $form['#attached']['placeholders'][$placeholder] = [
    '#lazy_builder' => [
      '\\Drupal\\user\\Plugin\\Block\\UserLoginBlock::renderPlaceholderFormAction',
      [],
    ],
  ];
  $form['#action'] = $placeholder;

  $items = [];
  if (\Drupal::config('user.settings')->get('register') != UserInterface::REGISTER_ADMINISTRATORS_ONLY) {
    $items['create_account'] = [
      '#type' => 'link',
      '#title' => $this->t('Create new account'),
      '#url' => Url::fromRoute('user.register', [], [
        'attributes' => [
          'title' => $this->t('Create a new user account.'),
          'class' => [
            'create-account-link',
          ],
        ],
      ]),
    ];
  }
  $items['request_password'] = [
    '#type' => 'link',
    '#title' => $this->t('Reset your password'),
    '#url' => Url::fromRoute('user.pass', [], [
      'attributes' => [
        'title' => $this->t('Send password reset instructions via email.'),
        'class' => [
          'request-password-link',
        ],
      ],
    ]),
  ];
  return [
    'user_login_form' => $form,
    'user_links' => [
      '#theme' => 'item_list',
      '#items' => $items,
    ],
  ];
1
  • This looks like what I'm after! Thank you! I will try this and report back soon.
    – cofihouse
    Feb 9, 2022 at 4:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.