Add 3rd party setting to Node type in Drupal

Components

Let's say you want to add some custom settings, such as a checkbox to the Node type form, so you can later dynamically limit the query to only include node types that have this value checked.

Image

You can easily do this by using third-party settings. Alter the Node type form by adding a field to it, and then add the corresponding entity builder function:

use Drupal\Core\Form\FormStateInterface;
use Drupal\node\NodeTypeInterface;

/**
 * Implements hook_form_FORM_ID_alter().
 */
function MY_MODULE_form_node_type_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\node\Entity\NodeType $node_type */
  $node_type = $form_state->getFormObject()->getEntity();
  $custom_checkbox = $node_type->getThirdPartySetting('MY_MODULE', 'custom_checkbox', FALSE);

  $form['custom_checkbox'] = [
    '#type' => 'checkbox',
    '#title' => t('Custom checkbox'),
    '#default_value' => $custom_checkbox,
  ];

  $form['#entity_builders'][] = 'MY_MODULE_form_node_type_edit_form_builder';
}

/**
 * Entity builder for the node type form with custom options.
 */
function MY_MODULE_form_node_type_edit_form_builder($entity_type, NodeTypeInterface $type, &$form, FormStateInterface $form_state) {
  $type->setThirdPartySetting('MY_MODULE', 'custom_checkbox', $form_state->getValue('custom_checkbox'));
}

That's pretty much it, the only thing left to add is the config/schema file. This file should be named after your module, so in our example, it would be:

config/schema/MY_MODULE.schema.yml

and its content would be:

node.type.*.third_party.MY_MODULE:
  type: mapping
  label: 'Additional Note type settings'
  mapping:
    custom_checkbox:
      type: boolean
      label: 'Custom checkbox'

Now, later when we want to select only the content types that have this field checked, we could write a query like this:

function MY_MODULE_get_custom_checkbox_content_types(): array {
  $content_types = \Drupal::entityTypeManager()->getStorage('node_type')->loadMultiple();
  $custom_checkbox_content_types = [];

  foreach ($content_types as $content_type) {
    $custom_checkbox = $content_type->getThirdPartySetting('MY_MODULE', 'custom_checkbox', FALSE);
    if ($custom_checkbox) {
      $custom_checkbox_content_types[] = $content_type->id();
    }
  }

  return $custom_checkbox_content_types;
}

And that's it, a very useful feature that isn't difficult to implement and can help avoid hardcoding in a function where a condition related to the content type is checked.

About the Author

Goran Nikolovski is a web and AI developer with over 10 years of expertise in PHP, Drupal, Python, JavaScript, React, and React Native. He founded this website and enjoys sharing his knowledge.