10

How can I hide or disable the title field on the node edit form?

If I do so from the content type Manage form display tab (admin/structure/types/manage/CONTENT_TYPE_MACHINE_NAME/form-display), then I get some integrity constraint errors in the log.

So I don't want to show default title field in Node edit form. If I hide the title field normally like other fields. Got white screen after node creation. And log says title field can't be null .... and so on ...

3
  • Are you looking for Node::setTitle ?
    – Jimmy Ko
    Commented Sep 26, 2016 at 9:48
  • @JimmyKom Thanks for comment. let me rephrase, I don't want to show default title field in Node edit form. If I hide the title field normally like other fields. Got white screen after node creation. And log says title field can't be null .... and so on ... Commented Sep 26, 2016 at 10:38
  • do you solve your problem? Commented May 3, 2017 at 2:57

5 Answers 5

8

You can use hook_form_alter() function to alter any form (including node edit form) and disable Title field. Check sample code below:

use Drupal\field_collection\Entity\FieldCollectionItem;

function [MODULE_NAME]_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  switch ($form_id) {
    case 'node_[CONTENT_TYPE]_edit_form':
      $form['title']['#disabled'] = 'disabled';
      break;
  }
}

If you're altering only one form you can check hook_form_FORM_ID_alter() function and change FORM_ID with node_[CONTENT_TYPE]_edit_form where CONTENT_TYPE is your node type form.

EDIT :

To automatically set node title without allowing user to see title field, you can use Automatic Entity Label Module. The module is in dev version for D8, but we can give it a try if functioning properly.

If don't want to use Automatic Entity Label module, you can try doing same with custom code, check sample code here

11
  • 1
    Thanks but disabling the field is not a problem. It seems drupal core don't allow to create node without title. How you will address this error from DB Drupal\Core\Entity\EntityStorageException: SQLSTATE[23000]: Integrity constraint violation: 1048 Column 'title' cannot be null: INSERT INTO {node_field_data} Commented Sep 26, 2016 at 10:46
  • Ok, so basically you don't want to show title field neither on add nor edit node content and allow users to create content, right? If yes, check out this module Automatic Entity Label if this helps. The module is currently in its dev version.
    – Yogesh
    Commented Sep 26, 2016 at 10:51
  • that is in dev for D8. not sure safe to use... Commented Sep 26, 2016 at 10:52
  • 1
    If the Automatic Entity Label module doesn't work, you can try sample code given on this link Auto fill Drupal 8 title?.
    – Yogesh
    Commented Sep 26, 2016 at 10:54
  • 1
    How are you identifying nodes in the administrative interface if they do not have a title? How are you accounting for meta data and such? This is pretty unorthodox, just saying. Best to fill in some value, somehow.
    – Kevin
    Commented Sep 26, 2016 at 18:41
4

tl;dr: Specify a default title, and don't allow the user to change it.

The D7→D8 change records state:

node_type->has_title removed in favor of entity form displays

Now that it is possible to configure the behavior of the node title widget using Entity form displays, the special flag to hide the title form element for nodes is no longer needed.

To hide the title for a certain node type, use the "Manage form display" UI or hide it with a snippet like the following:

$form_display = entity_get_form_display('node', 'article', 'default');
$form_display->removeComponent('title');
$form_display->save();

After reading that, I tried a few ways of doing it. Only the last one works, so this answer should serve as a warning of what not to try:

Edit the entity_form_display config

If it is your own module, edit core.entity_form_display.node.my_content_type.default.yml and remove the title key from content. This works for fields, but if I remove the title or any of the other default things like promoted, created, etc., they are still displayed on the form at /node/add/my_content_type.

Modify the entity_form_display in code

Add this code to my_module_install :

$form_display = entity_get_form_display('node', 'my_content_type', 'default');
$form_display->removeComponent('title');
$form_display->save();

This works visually, but there are three problems with this solution: - It still causes the integrity constraint errors you refer to. - It causes the config in the database to override the config in the file at install time, which is a bad idea, IMHO. - entity_get_form_display is deprecated

Hide it in the entity_form_display config

Hide it, but don't remove it. In core.entity_form_display.node.my_content_type.default.yml:

hidden:
  title: false

By trial and error, I found the logic to be reversed here. This, too, causes the integrity constraint errors you refer to.

Hide it using CSS

I tried this, and it seems that empty strings are also disallowed for the title. So you either have to create your own entity type, which reimplements most of the code from the core node module, or...

The only working solution I could find

Specify a default title, and don't allow the user to change it.

function my_module_form_node_my_content_type_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {
  $form['title']['#disabled'] = 'disabled';
  $form['title']['widget'][0]['value']['#default_value'] = 'none';
}

You could change none to my_module, a timestamp, or your favourite brand of peanut butter.

2

This is how I solve this issue in a project. At this moment Automatic Entity Label don't have a Drupal 8 version, if you see the code you will find only a info.yml file.

You always need to set the title, so in the creation of the entity you set the title.

use Drupal\node\NodeInterface;

/**
 * Implements hook_ENTITY_TYPE_create
 */
function YOUR_MODULE_node_create(NodeInterface $node) {
  switch ($node->getType()) {
    case 'CONTENT_TYPE_MACHINE_NAME':
      $node->title = 'Date: ' . date('Y-m-d G:i:s');
      break;
  }
}

And the other part is hide the title in the node form, to do this you can use:

/**
 * Implements hook_form_alter().
 */
function YOUR_MODULE_form_alter(array &$form, FormStateInterface $form_state, $form_id) {
  //With this you will know your form_id (see in the next function YOUR_FORM_ID)
  dpm($form_id);
}

And in this hook you will hide the title, with this you do the trick

/**
 * Implements hook_form_FORM_ID_alter().
 */
function YOUR_MODULE_form_YOUR_FORM_ID_alter(array &$form, FormStateInterface $form_state, $form_id) {
  $form['title']['#access'] = FALSE;
}
1

You could also use the automatic node title module. This will allow you to set the node title to whatever you want in the content type configuration, but will not display the field on add or edit.

0

I found the title to be useful in many ways in the layout builder: - Show content preview - Use it as block Id

My solution generates automatic titles by using the block type title and counting the number of blocks from the same type.

function [module]_form_alter(&$form, \Drupal\Core\Form\FormStateInterface $form_state, $form_id) {

  if ($form_id === 'layout_builder_add_block') {
    // Get the blocks plugins id counter.
    $bundle = $form['settings']['block_form']['#block']->bundle();
    $plugin_id = 'inline_block:' . $bundle;

    // Get the blocks plugins id count array.
    if ($node = $form_state->getTemporary()['gathered_contexts']['layout_builder.entity']->getContextData()->getEntity()) {
      $block_count = 0;
      foreach ($node->layout_builder__layout as $section) {
        $components = $section->section->getComponents();
        foreach ($components as $block) {
          if ($plugin_id === $block->getPluginId()) {
            $block_count += 1;
          }
        }
      }
    }

    // If not exist start from 0.
    // Insert default title.
    $form['settings']['label']['#default_value'] = t('%title-%title_id', [
      '%title' => $form['settings']['admin_label']['#plain_text'],
      '%title_id' => $block_count,
    ]);
    // Change title description.
    $form['settings']['label']['#title'] = t('Block id');
    $form['settings']['label']['#description'] = t('Automatic id generator. Can be modified by user but must be unique.');
    // Update and hide display title checkbox.
    // $form['settings']['label_display']['#default_value'] = FALSE;
    // $form['settings']['label_display']['#access'] = FALSE;
  }

  if ($form_id === 'layout_builder_update_block') {
    // Change title description.
    $form['settings']['label']['#title'] = t('Block id');
    $form['settings']['label']['#description'] = t('Automatic id generator. Can be modified by user but must be unique.');
    // Update and hide display title checkbox.
    // $form['settings']['label_display']['#default_value'] = FALSE;
    // $form['settings']['label_display']['#access'] = FALSE;
  }
}

/**
 * HOOK_preprocess_block.
 */
function [module]_preprocess_block(&$variables) {
  // Add id into block.
  $label = qfcc_structure_normaliseLabelToId($variables['label']);
  if (!$label) {
    $label = rand(100, 999);
  }
  $variables['attributes']['id'] = 'block-' . $label;
}

function [module]_normaliseLabelToId($text) {
  if (!$text) {
    return NULL;
  }

  $text = trim(strtolower($text));
  $text = str_replace(' ', '-', $text);
  $text = str_replace('_', '-', $text);
  $text = preg_replace('/[^a-z0-9\-]/', '', $text);
  return $text ?? NULL;
}

enter image description here enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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