2

Please how can I alter the default field settings whenever a new field is added?

NB I am not asking how to set the default whenever a new entity is added. This is about changing the pre-populated values on the page "Administration->Structure->Content types->XXX->Manage fields->Add field when a field is added"

NB This question is for D8. In D7 the answer is to use hook_field_info_alter.

Specifically I am using the module allowed_formats, and I would like every new text_with_summary or text_long field to have defaults of:

  • Allowed formats = "Basic HTML" only
  • Form display settings "Hide the help link About text formats." and "Hide text format guidelines." enabled.

The defaults need to work even if the new field is created in code. In particular it's important to work for the Body field that is created automatically on a new content type.

I'm struggling because looking at the code, the defaults come from the public static function TextWithSummaryItem::defaultFieldSettings and there doesn't seem to be any hook.

  • You can use these entity hooks for the field, view mode and form mode config entities api.drupal.org/api/drupal/… – 4k4 Jul 21 '17 at 16:12
  • @4k4 thanks for the response. Please can you explain which of hooks on that page? The hooks look like they are for hooking changes on an entity, i.e. content. I am trying to hook changes on a field, i.e. structure. – AdamS Jul 21 '17 at 16:23
  • 2
    In D8 the field structure is stored in config entities. For example when the node module creates the body field for a new content type you can use hook_field_config_presave() to change the settings before they are saved. Or hook_entity_form_display_presave() for the settings in the form mode. – 4k4 Jul 21 '17 at 16:42
  • 2
    api.drupal.org/api/drupal/… is an example of how comment.module controls the default settings for new config fields. The isSyncing check is important. – Berdir Jul 21 '17 at 19:59
  • 1
    Form display is indeed a good question. All entities have $entity->original available, which is the original unaltered entity that you can use to detect changes. In this case you could get the new and old compoents, do an array_diff() to get only those that were added, then check their type. Adding a new field adds it to default display automatically, editing another form display might not work in the same way as the form is displayed and saved, so maybe you need a form alter for that – Berdir Jul 23 '17 at 11:22
2

Thanks to @Berdir and @4k4 who helped me out several times - I just followed their ideas, tested and wrote up the answers.

This first hook alters the field settings. I've included a second example for image settings.

function XXX_field_config_create(FieldConfigInterface $field) {
  if ($field->isSyncing()) return;

  switch ($field->getType()) {
    case 'image':
      $field->setSettings(['file_directory' => 'images', 'max_resolution' => '1080x1080']);
      break;

    case 'text_with_summary':
    case 'text_long':
      $field->setThirdPartySetting('allowed_formats', 'basic_html', 'basic_html');
      break;
  }
}

This second hook alters the form display settings. The array_diff_key command is used to determine which fields are new.

/**
 * Implements hook_ENTITY_TYPE_presave().
 *
 * Override field form display defaults used when a field is added to a content type.
 */
function XXX_entity_form_display_presave(EntityFormDisplay $display) {
  $fields = $display->getComponents();
  $origFields = (isset($display->original)) ? $display->original->getComponents() : [];
  foreach (array_diff_key($fields, $origFields) as $newField => $settings) {
    switch ($settings['type']) {
      case 'text_textarea_with_summary':
      case 'text_textarea':
        $settings['third_party_settings']['allowed_formats'] = ['hide_help' => '1', 'hide_guidelines' => '1'];
        $display->setComponent($newField, $settings);
        break;
    }
  }
}
  • Please do not ask new questions in answers. If you have found an answer to your question, leave the working part here and ask the other issue as a new separate question (provide a link to this issue for reference if needed). If your question is not yet answered, edit your latest findings in the original question and wait for a complete answer. That way we can keep all combinations of questions ans answers relevant. Thanks :) – Neograph734 Jul 22 '17 at 22:57
  • 1
    You can't do all in one hook, the field is added to the default form mode on submit anyway, so you can hook into this when this is happening. The create hook is only to prepare the entity for the form, nothing is saved at this point, because you don't know whether the user submits the form. – 4k4 Jul 23 '17 at 11:34
  • @4k4 thanks again I am learning a lot from you. Please could you tell me what hook I need for the second part? I need a hook where I can distinguish which field is newly created and only alter settings on that one. – AdamS Jul 23 '17 at 16:17
  • 1
    @Neograph734 Thanks for the advice. My original question was not fully answered and I was trying to indicate which parts were answered and which not. I have now moved that information into the question as you suggest, so hopefully it's clearer now. – AdamS Jul 23 '17 at 16:23
  • 1
    @AdamS, this is the presave hook for the form mode i've mentioned in the first comment. When the field config form gets submitted, it will update the default form mode config entity. And this is the same for the body field added by new content types (second part of your question). So this hook would take care of both parts, UI and non UI. And for the diff part see Berdir's comment. – 4k4 Jul 23 '17 at 16:40

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.