Score:0

How can I alter the login form in the login block but not in the login page?

tr flag

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') {
    // …
  }
}
Score:2
fr flag

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.

tr flag
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?
tr flag
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?
fr flag
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.
fr flag
Also see https://api.drupal.org/api/drupal/core%21modules%21block%21block.api.php/group/block_api/9.3.x for other alternatives.
tr flag
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.
Score:1
us flag

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,
    ],
  ];
tr flag
This looks like what I'm after! Thank you! I will try this and report back soon.
mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.