Skip to main content

How to add a new column to a taxonomy term admin listing page

Drupal

If you're like me, you often find yourself wanting to show additional information on the admin screens within a Drupal website. The most common scenario is the content listing page. Adding more content to the content listing page is easy since it is built with a Drupal View. Unfortunately, taxonomy term listing pages are not built with a Drupal View. I have not found much discussion on the reason for this, but I have a feeling that it's due to the drag-and-drop nature of that listing page.

Fear not, for I have a code snippet you can add to a custom module and tailor to your specific needs.

/**
 * Implements hook_form_FORM_ID_alter().
 *
 * Adds term ID to taxonomy overview page.
 */
function HOOK_form_taxonomy_overview_terms_alter(&$form, FormStateInterface $form_state, $form_id) {

  $terms = $form['terms'];
  $keys = Element::children($terms);

  if (empty($keys)) {
    return;
  }

  /** @var \Drupal\taxonomy\Entity\Term $first_term */
  $first_term = $terms[reset($keys)]['#term'];

  if (!in_array($first_term->bundle(), ['region'])) {
    return;
  }

  $col_position = array_search('term', array_keys($terms[reset($keys)])) || 0;

  if (isset($form['terms']['#header'])) {
    array_splice($form['terms']['#header'], $col_position + 1, 0, [t('ID')]);
  }

  foreach ($keys as $key) {
    /** @var \Drupal\taxonomy\Entity\Term $term */
    $term = $terms[$key]['#term'];

    $id = [
      '#type' => 'html_tag',
      '#tag' => 'span',
      '#value' => $term->id(),
    ];

    array_splice($form['terms'][$key], $col_position + 1, 0, ['id' => $id]);
  }
}

It turns out that the taxonomy listing page is a form, so this snippet alters that form and adds a column for the term ID. You can customize this to display any property or field on terms. I chose the ID property as it is on all terms.

On line 18, you can see that I target this to the "region" vocabulary. This conditional can be removed if you want this to apply to all listing pages. Or you can convert this to a switch to add different columns to different vocabularies.

if (!in_array($first_term->bundle(), ['region'])) {
  return;
}

On lines 32-36 you can see the render array that I put into the column. You can place anything within this render array, including links and other rich HTML.

$id = [
  '#type' => 'html_tag',
  '#tag' => 'span',
  '#value' => $term->id(),
];

Here is the final result:

Screenshot demonstrating a new column on aterm listing page