I am trying to alter a form for the Question content type, whose ID is node-question-form.

I set up a module and tried to implement hook_FORM_ID_alter(), but it's not invoked. Even the simplest implementation as the following is not working.

function constellator_form_alter(&$form, &$form_state, $form_id) {
  echo "alter the form";

I have been stuck with this since this morning. Nothing is working for me.

  • Are you declaring your hooks in your module_name.module file? Did you rebuild your cache after declaring your hook? The basic declaration of hooks is pretty much the same as Drupal 7. Check: api.drupal.org/api/drupal/core%21core.api.php/group/hooks/8.3.x
    – mvdgun
    Aug 3 '17 at 13:33
  • This is not hook_FORM_ID_alter... this is hook_form_alter - where it needs to be modulename_form_alter. The arguments must also be $form, and FormStateInterface $form_state. That is the difference in Drupal 8. After adding it, you must clear the cache. PS: use a debugger. print;exit;die;... no good.
    – Kevin
    Aug 3 '17 at 14:03

Here is a working example I have pulled from a project and altered to have your module name.

Add this at the top of your .module file:

use Drupal\Core\Form\FormStateInterface;

Then copy this in

 * Implements hook_form_alter().
function constellator_form_alter(&$form, FormStateInterface $form_state, $form_id) {

  // Adding custom validation for the welcome page type field.
  if ($form_id == 'node_article_edit_form' || $form_id == 'node_article_form') {
    // Do some stuff.

I think most likely what you aren't doing is clearing the Drupal cache to register the hook. You can click on "clear all caches". Or better yet, install the drush command line utility and use "drush cr".

enter image description here

  • As of Drupal 8.7.3, this appears to be incorrect-- when I used mymodule_form_alter(&$form, FormStateInterface $form_state, $form_id), I got TypeError: Argument 2 passed to mymodule_form_alter() must be an instance of FormStateInterface, instance of Drupal\Core\Form\FormState given. I changed my hook signature to (&$form, $form_state, $form_id), and no more complaints.
    – user1359
    Aug 5 '19 at 19:47
  • This IS correct for all versions of Drupal 8 (and Drupal 9) - if you got that error it means your "use" statement is missing or wrong.
    – anonymous
    Nov 13 '20 at 3:16

If you have set up a custom theme, then without adding any namespace requirement you can easily alter your form using hook_form_form_id_alter() in your theme_name.theme file.

function bootstrap_ga_form_user_login_form_alter(&$form, &$form_state, $form_id) {
  global $base_url;
  $form['#validate'][] = '_bootstrap_ga_form_user_login_form_validate';

I added a custom validation to the user login form. bootstrap_ga is the custom theme name.

  • 1
    This won't work for Drupal 8.
    – Kevin
    Aug 3 '17 at 14:38
  • 1
    Yes it will @Kevin - there's a missing global var, no type type hinting on the $form_state and a benign pass-by-reference, but none of those will stop the code from working. It's valid PHP, and valid per integration with the Drupal API. Not best practice, but definitely working.
    – Clive
    Aug 3 '17 at 14:50

Try this it in your custom module

Use the Below Namespace

    use Drupal\node\Entity\Node;
    use Drupal\Core\Form\FormStateInterface;

Use this hook_form_alter for the particular node

function modulename_form_Form_ID_form_alter(&$form, &$form_state, $form_id){   
  //echo <pre>; print_r($form); die;

And this hook will be used to edit the particular node form id

  • 3
    You can't pass form_state by reference. it is now an object, not an array, in Drupal 8. It must be passed in as FormStateInterface $form_state.
    – Kevin
    Aug 3 '17 at 14:02
  • 1
    Also in a hook_form_FORM_ID_alter, there is no need to pass $form_id, you wouldn't need it.
    – Kevin
    Aug 3 '17 at 14:18
  • Though its an object, we can use $form_state->getValue('paritcular field') to change the field . right! Aug 3 '17 at 14:18
  • 4
    While type hinting is considered best practice, there's no "must" about using it. Similarly objects are generally passed by reference, definitely so in this case, so there's no need for the & before the parameter, but including it is no problem - it's still valid PHP. Also Drupal is passing the 3rd parameter to hook_form_FORM_ID_alter(), so it's good practice for the hooks to include it in their signature too. While this answer doesn't really address the problem the question raises, it is an alternative, it is valid and it doesn't deserve these ill-considered pile-on down votes
    – Clive
    Aug 3 '17 at 14:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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