8.5.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.0.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.1.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.2.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.3.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.4.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
8.6.x form.api.php hook_form_BASE_FORM_ID_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id)
7.x system.api.php hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id)

Provide a form-specific alteration for shared ('base') forms.

By default, when drupal_get_form() is called, Drupal looks for a function with the same name as the form ID, and uses that function to build the form. In contrast, base forms allow multiple form IDs to be mapped to a single base (also called 'factory') form function.

Modules can implement hook_form_BASE_FORM_ID_alter() to modify a specific base form, rather than implementing hook_form_alter() and checking for conditions that would identify the shared form constructor.

To identify the base form ID for a particular form (or to determine whether one exists) check the $form_state. The base form ID is stored under $form_state['build_info']['base_form_id'].

See hook_forms() for more information on how to implement base forms in Drupal.

Form alter hooks are called in the following order: hook_form_alter(), hook_form_BASE_FORM_ID_alter(), hook_form_FORM_ID_alter(). See hook_form_alter() for more details.


$form: Nested array of form elements that comprise the form.

$form_state: A keyed array containing the current state of the form.

$form_id: String representing the name of the form itself. Typically this is the name of the function that generated the form.

See also





Related topics

55 functions implement hook_form_BASE_FORM_ID_alter()

Note: this list is generated by pattern matching, so it may include some functions that are not actually implementations of this hook.

aggregator_form_aggregator_admin_form_alter in modules/aggregator/aggregator.processor.inc
Implements hook_form_aggregator_admin_form_alter().
block_form_form_test_alter_form_alter in modules/simpletest/tests/form_test.module
Implements hook_form_FORM_ID_alter() on behalf of block.module.
block_form_system_performance_settings_alter in modules/block/block.module
Implements hook_form_FORM_ID_alter().
block_form_user_profile_form_alter in modules/block/block.module
Implements hook_form_FORM_ID_alter() for user_profile_form().
book_form_node_delete_confirm_alter in modules/book/book.module
Implements hook_form_FORM_ID_alter() for node_delete_confirm().

... See full list


modules/system/system.api.php, line 1757
Hooks provided by Drupal core and the System module.


function hook_form_BASE_FORM_ID_alter(&$form, &$form_state, $form_id) {

  // Modification for the form with the given BASE_FORM_ID goes here. For
  // example, if BASE_FORM_ID is "node_form", this code would run on every
  // node form, regardless of node type.
  // Add a checkbox to the node form about agreeing to terms of use.
  $form['terms_of_use'] = array(
    '#type' => 'checkbox',
    '#title' => t("I agree with the website's terms and conditions."),
    '#required' => TRUE,


bryanbraun’s picture

The most common use for this, in my experience, is to alter the node edit page. The hook allows you to target these kind of pages without firing off a hook for every form on the site. Here's an example of how you could set it up to alter the "article edit form" in your module or template.php file:

function mymodule_form_node_form_alter(&$form, &$form_state, $form_id) {
  // Find the content type of the node we are editing.
  $content_type = $form['#node']->type;
  if ($content_type == 'article') {
    // Alter the 'article' form here.
Nitebreed’s picture

This code will only alter the article node form:

function mymodule_form_article_node_form_alter(&$form, &$form_state, $form_id) {
  // Alter the 'article' form here.
gclicon’s picture

The thing to note is that the node add and node edit forms have a different form id.

for example on an article, the form_id for the edit form would be node_article_edit_form while the form_id for the add form would be node_article_form

So while this would alter the node add form

function mymodule_form_article_node_form_alter(&$form, &$form_state, $form_id) {
  // Alter the 'article' form here.

If you want to alter both the add and edit forms, the better approach would be with the base form id and check the node type as was suggested by bryanbraun with the exception that the $form variable does not carry the node anymore. So we'd want to do something like this:

function mymodule_form_node_form_alter(&$form, &$form_state, $form_id) {
  /* @var Drupal\Core\Entity\FieldableEntityInterface $node */
  $node = $form_state->getFormObject()->getEntity();

  if ($node->getType() == 'article') {
    // Alter the 'article' form here.

mineshaftgap’s picture

gclicon, this page is for Drupal 7 API. What you are saying I think applies to Drupal 8.

duncan.moo’s picture

A bit inconsistent but for nodes the BASE_FORM_ID is node_form but for taxonomy terms it is taxonomy_form_term.

function MYMODULE_form_taxonomy_form_term_alter(&$form, &$form_state) {
  // your code here