Issue #784672 by smustgrave, floretan, lokapujya, joegraduate, jcnventura, AndyF, joelpittet, darvanen, c960657, eiriksm, viappidu, jungle, ravi.shankar, DanielVeza, Meenakshi_j, gordon, raman.b, mohit_aghera, vsujeetkumar, aleevas, vakulrai, bruvers, larowlan, vpeltot, wjaspers, Sonal.Sangale, jan.stoeckler, jofitz, vdsh, minorOffense, LewisNyman, mgifford, Berdir, tstoeckler, Luke.Leber, Hanno, alexpott, andypost, yannickoo, hchonov, quietone, David_Rothstein, fgm, mr.baileys, MaxMendez, mpp: Allow text field to enforce a specific text format

merge-requests/3042/head
Alex Pott 2022-11-29 11:37:35 +00:00
parent e2d4dcfdf2
commit 82576b6002
No known key found for this signature in database
GPG Key ID: BDA67E7EE836E5CE
41 changed files with 403 additions and 30 deletions

View File

@ -94,7 +94,10 @@ function block_content_add_body_field($block_type_id, $label = 'Body') {
'field_storage' => FieldStorageConfig::loadByName('block_content', 'body'),
'bundle' => $block_type_id,
'label' => $label,
'settings' => ['display_summary' => FALSE],
'settings' => [
'display_summary' => FALSE,
'allowed_formats' => [],
],
]);
$field->save();

View File

@ -13,6 +13,7 @@ source:
field_name: body
label: Body
display_summary: false
allowed_formats: { }
ids:
entity_type:
type: string

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -414,7 +414,10 @@ class ConfigTranslationListUiTest extends BrowserTestBase {
'field_storage' => FieldStorageConfig::loadByName('block_content', 'body'),
'bundle' => $block_content_type->id(),
'label' => 'Body',
'settings' => ['display_summary' => FALSE],
'settings' => [
'display_summary' => FALSE,
'allowed_formats' => [],
],
]);
$field->save();

View File

@ -15,3 +15,7 @@ editor.settings.trex:
stumpy_arms:
type: boolean
label: 'Stumpy arms'
field.field_settings.editor_test_text_long:
label: 'Filter test text (formatted, long) settings'
type: field.field_settings.text

View File

@ -11,5 +11,6 @@ description: ''
required: false
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text

View File

@ -11,5 +11,6 @@ description: ''
required: false
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text

View File

@ -11,5 +11,6 @@ description: ''
required: false
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text

View File

@ -9,7 +9,8 @@ description: ''
required: '0'
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text
dependencies:
config:

View File

@ -9,7 +9,8 @@ description: ''
required: '0'
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text
dependencies:
config:

View File

@ -9,7 +9,8 @@ description: ''
required: '0'
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text
dependencies:
config:

View File

@ -82,7 +82,9 @@ abstract class FieldConfigResourceTestBase extends ConfigEntityResourceTestBase
'label' => 'field_llama',
'langcode' => 'en',
'required' => FALSE,
'settings' => [],
'settings' => [
'allowed_formats' => [],
],
'status' => TRUE,
'translatable' => TRUE,
'uuid' => $this->entity->uuid(),

View File

@ -33,7 +33,7 @@ class MigrateFieldInstanceTest extends MigrateDrupal6TestBase {
$field = FieldConfig::load('node.story.field_test');
$this->assertSame('Text Field', $field->label());
// field_test is a text_long field, which have no settings.
$this->assertSame([], $field->getSettings());
$this->assertSame(['allowed_formats' => []], $field->getSettings());
$this->assertSame('text for default value', $entity->field_test->value);
// Test a number field.

View File

@ -16,5 +16,6 @@ required: true
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -119,7 +119,7 @@ class FieldConfigTest extends ConfigEntityResourceTestBase {
'label' => 'field_llama',
'langcode' => 'en',
'required' => FALSE,
'settings' => [],
'settings' => ['allowed_formats' => []],
'status' => TRUE,
'translatable' => TRUE,
'drupal_internal__id' => 'node.camelids.field_llama',

View File

@ -277,7 +277,10 @@ function node_add_body_field(NodeTypeInterface $type, $label = 'Body') {
'field_storage' => $field_storage,
'bundle' => $type->id(),
'label' => $label,
'settings' => ['display_summary' => TRUE],
'settings' => [
'display_summary' => TRUE,
'allowed_formats' => [],
],
]);
$field->save();

View File

@ -17,4 +17,5 @@ default_value: { }
default_value_callback: ''
settings:
display_summary: true
allowed_formats: { }
field_type: text_with_summary

View File

@ -19,6 +19,12 @@ field.storage_settings.text:
field.field_settings.text:
type: mapping
label: 'Text (formatted) settings'
mapping:
allowed_formats:
type: sequence
label: 'Allowed text formats'
sequence:
type: string
field.value.text:
type: mapping
@ -33,11 +39,17 @@ field.value.text:
field.storage_settings.text_long:
label: 'Text (formatted, long) settings'
type: mapping
type: field.field_settings.text
field.field_settings.text_long:
label: 'Text (formatted, long) settings'
type: mapping
mapping:
allowed_formats:
type: sequence
label: 'Allowed text formats'
sequence:
type: string
field.value.text_long:
type: mapping
@ -64,6 +76,11 @@ field.field_settings.text_with_summary:
required_summary:
type: boolean
label: 'Require summary'
allowed_formats:
type: sequence
label: 'Allowed text formats'
sequence:
type: string
field.value.text_with_summary:
type: mapping

View File

@ -0,0 +1,35 @@
<?php
namespace Drupal\text\Plugin\Field\FieldType;
use Drupal\Core\Field\FieldItemList;
use Drupal\Core\Form\FormStateInterface;
/**
* Defines an item list class for text fields.
*/
class TextFieldItemList extends FieldItemList {
/**
* {@inheritdoc}
*/
public function defaultValuesFormValidate(array $element, array &$form, FormStateInterface $form_state) {
if ($allowed_formats = $this->getSetting('allowed_formats')) {
$field_name = $this->definition->getName();
$submitted_values = $form_state->getValue([
'default_value_input',
$field_name,
]);
foreach ($submitted_values as $delta => $value) {
if (!in_array($value['format'], $allowed_formats, TRUE)) {
$form_state->setErrorByName(
"default_value_input][{$field_name}][{$delta}][format",
$this->t("The selected text format is not allowed.")
);
}
}
}
parent::defaultValuesFormValidate($element, $form, $form_state);
}
}

View File

@ -14,7 +14,8 @@ use Drupal\Core\Form\FormStateInterface;
* description = @Translation("This field stores a text with a text format."),
* category = @Translation("Text"),
* default_widget = "text_textfield",
* default_formatter = "text_default"
* default_formatter = "text_default",
* list_class = "\Drupal\text\Plugin\Field\FieldType\TextFieldItemList"
* )
*/
class TextItem extends TextItemBase {

View File

@ -6,6 +6,7 @@ use Drupal\Component\Utility\Random;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemBase;
use Drupal\Core\Field\FieldStorageDefinitionInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\TypedData\DataDefinition;
/**
@ -13,6 +14,62 @@ use Drupal\Core\TypedData\DataDefinition;
*/
abstract class TextItemBase extends FieldItemBase {
/**
* {@inheritdoc}
*/
public static function defaultFieldSettings() {
return ['allowed_formats' => []] + parent::defaultFieldSettings();
}
/**
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$element = parent::fieldSettingsForm($form, $form_state);
$settings = $this->getSettings();
$element['allowed_formats'] = [
'#type' => 'checkboxes',
'#title' => $this->t('Allowed text formats'),
'#options' => $this->get('format')->getPossibleOptions(),
'#default_value' => !empty($settings['allowed_formats']) ? $settings['allowed_formats'] : [],
'#description' => $this->t('Select the allowed text formats. If no formats are selected, all available text formats will be displayed to the user.'),
'#element_validate' => [[static::class, 'validateAllowedFormats']],
];
return $element;
}
/**
* Render API callback: Processes the allowed formats value.
*
* Ensure the element's value is an indexed array of selected format IDs.
* This function is assigned as an #element_validate callback.
*
* @see static::fieldSettingsForm()
*/
public static function validateAllowedFormats(array &$element, FormStateInterface $form_state) {
$value = array_values(array_filter($form_state->getValue($element['#parents'])));
$form_state->setValueForElement($element, $value);
}
/**
* {@inheritdoc}
*/
public static function calculateDependencies(FieldDefinitionInterface $field_definition) {
// Add explicitly allowed formats as config dependencies.
$format_dependencies = [];
$dependencies = parent::calculateDependencies($field_definition);
if (!is_null($field_definition->getSetting('allowed_formats'))) {
$format_dependencies = array_map(function (string $format_id) {
return 'filter.format.' . $format_id;
}, $field_definition->getSetting('allowed_formats'));
}
$config = $dependencies['config'] ?? [];
$dependencies['config'] = array_merge($config, $format_dependencies);
return $dependencies;
}
/**
* {@inheritdoc}
*/
@ -22,7 +79,8 @@ abstract class TextItemBase extends FieldItemBase {
->setRequired(TRUE);
$properties['format'] = DataDefinition::create('filter_format')
->setLabel(t('Text format'));
->setLabel(t('Text format'))
->setSetting('allowed_formats', $field_definition->getSetting('allowed_formats'));
$properties['processed'] = DataDefinition::create('string')
->setLabel(t('Processed text'))

View File

@ -13,7 +13,8 @@ use Drupal\Core\Field\FieldStorageDefinitionInterface;
* description = @Translation("This field stores a long text with a text format."),
* category = @Translation("Text"),
* default_widget = "text_textarea",
* default_formatter = "text_default"
* default_formatter = "text_default",
* list_class = "\Drupal\text\Plugin\Field\FieldType\TextFieldItemList"
* )
*/
class TextLongItem extends TextItemBase {

View File

@ -16,7 +16,8 @@ use Drupal\Core\StringTranslation\TranslatableMarkup;
* description = @Translation("This field stores long text with a format and an optional summary."),
* category = @Translation("Text"),
* default_widget = "text_textarea_with_summary",
* default_formatter = "text_default"
* default_formatter = "text_default",
* list_class = "\Drupal\text\Plugin\Field\FieldType\TextFieldItemList"
* )
*/
class TextWithSummaryItem extends TextItemBase {
@ -87,7 +88,7 @@ class TextWithSummaryItem extends TextItemBase {
* {@inheritdoc}
*/
public function fieldSettingsForm(array $form, FormStateInterface $form_state) {
$element = [];
$element = parent::fieldSettingsForm($form, $form_state);
$settings = $this->getSettings();
$element['display_summary'] = [

View File

@ -34,11 +34,17 @@ class TextareaWidget extends StringTextareaWidget {
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$main_widget = parent::formElement($items, $delta, $element, $form, $form_state);
$allowed_formats = $this->getFieldSetting('allowed_formats');
$element = $main_widget['value'];
$element['#type'] = 'text_format';
$element['#format'] = $items[$delta]->format;
$element['#base_type'] = $main_widget['value']['#type'];
if ($allowed_formats && !$this->isDefaultValueWidget($form_state)) {
$element['#allowed_formats'] = $allowed_formats;
}
return $element;
}

View File

@ -25,11 +25,17 @@ class TextfieldWidget extends StringTextfieldWidget {
*/
public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
$main_widget = parent::formElement($items, $delta, $element, $form, $form_state);
$allowed_formats = $this->getFieldSetting('allowed_formats');
$element = $main_widget['value'];
$element['#type'] = 'text_format';
$element['#format'] = $items[$delta]->format ?? NULL;
$element['#base_type'] = $main_widget['value']['#type'];
if ($allowed_formats && !$this->isDefaultValueWidget($form_state)) {
$element['#allowed_formats'] = $allowed_formats;
}
return $element;
}

View File

@ -7,6 +7,7 @@ use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\filter\Entity\FilterFormat;
use Drupal\filter\Render\FilteredMarkup;
use Drupal\Tests\field\Functional\String\StringFieldTest;
use Drupal\Tests\TestFileCreationTrait;
@ -21,6 +22,11 @@ class TextFieldTest extends StringFieldTest {
getTestFiles as drupalGetTestFiles;
}
/**
* {@inheritdoc}
*/
protected static $modules = ['entity_test', 'file', 'field_ui'];
/**
* A user with relevant administrative privileges.
*
@ -39,7 +45,10 @@ class TextFieldTest extends StringFieldTest {
protected function setUp(): void {
parent::setUp();
$this->adminUser = $this->drupalCreateUser(['administer filters']);
$this->adminUser = $this->drupalCreateUser([
'administer filters',
'administer entity_test fields',
]);
}
// Test fields.
@ -157,13 +166,146 @@ class TextFieldTest extends StringFieldTest {
$this->_testTextfieldWidgetsFormatted('text_long', 'text_textarea');
}
/**
* Test widgets for fields with selected allowed formats.
*/
public function testTextfieldWidgetsAllowedFormats() {
// Create one text format.
$this->drupalLogin($this->adminUser);
$format1 = FilterFormat::create([
'format' => mb_strtolower($this->randomMachineName()),
'name' => $this->randomMachineName(),
]);
$format1->save();
// Create a second text format.
$format2 = FilterFormat::create([
'format' => mb_strtolower($this->randomMachineName()),
'name' => $this->randomMachineName(),
'filters' => [
'filter_html' => [
'status' => 1,
'settings' => [
'allowed_html' => '<strong>',
],
],
],
]);
$format2->save();
// Create a third text format.
$format3 = FilterFormat::create([
'format' => mb_strtolower($this->randomMachineName()),
'name' => $this->randomMachineName(),
]);
$format3->save();
// Grant access to both formats to the user.
$roles = $this->webUser->getRoles();
$rid = $roles[0];
user_role_grant_permissions($rid, [
$format1->getPermissionName(),
$format2->getPermissionName(),
$format3->getPermissionName(),
]);
// Create a field with multiple formats allowed.
$field_name = mb_strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create([
'field_name' => $field_name,
'entity_type' => 'entity_test',
'type' => 'text',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_storage' => $field_storage,
'bundle' => 'entity_test',
'label' => $this->randomMachineName() . '_label',
'settings' => ['allowed_formats' => []],
]);
$field->save();
/** @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface $entity_display_repository */
$entity_display_repository = $this->container->get('entity_display.repository');
$entity_display_repository->getFormDisplay('entity_test', 'entity_test', 'default')
->setComponent($field_name, [
'type' => 'text_textfield',
])
->save();
$entity_display_repository->getViewDisplay('entity_test', 'entity_test', 'full')
->setComponent($field_name)
->save();
// Display the creation form.
$this->drupalLogin($this->webUser);
$this->drupalGet('entity_test/add');
$this->assertSession()->fieldExists("{$field_name}[0][value]", NULL);
$this->assertSession()->optionExists("{$field_name}[0][format]", $format1->id());
$this->assertSession()->optionExists("{$field_name}[0][format]", $format2->id());
$this->assertSession()->optionExists("{$field_name}[0][format]", $format3->id());
$filtered_markup = FilteredMarkup::create('<div><strong><span>Hello World</span></strong></div>');
$edit = [
"{$field_name}[0][value]" => $filtered_markup,
];
$this->submitForm($edit, 'Save');
preg_match('|entity_test/manage/(\d+)|', $this->getUrl(), $match);
$id = $match[1];
$this->assertSession()->pageTextContains('entity_test ' . $id . ' has been created.');
// Display the entity.
$entity = EntityTest::load($id);
$display = $entity_display_repository->getViewDisplay($entity->getEntityTypeId(), $entity->bundle(), 'full');
$content = $display->build($entity);
$rendered_entity = \Drupal::service('renderer')->renderRoot($content);
$this->assertStringContainsString('<div><strong><span>', (string) $rendered_entity);
// Log back in as admin.
$this->drupalLogin($this->adminUser);
// Change field to allow only one format.
$path = "entity_test/structure/entity_test/fields/entity_test.entity_test.$field_name";
$this->drupalGet($path);
$this->submitForm(["settings[allowed_formats][{$format1->id()}]" => $format1->id()], 'Save settings');
$this->drupalGet($path);
// Display the creation form.
$this->drupalLogin($this->webUser);
// We shouldn't have the 'format' selector since only one format is allowed.
$this->drupalGet('entity_test/add');
$this->assertSession()->fieldExists("{$field_name}[0][value]", NULL);
$this->assertSession()->fieldNotExists("{$field_name}[0][format]");
// Retest the entity renders fine even though filter2 is disabled.
$entity = EntityTest::load($id);
$display = $entity_display_repository->getViewDisplay($entity->getEntityTypeId(), $entity->bundle(), 'full');
$content = $display->build($entity);
$rendered_entity = \Drupal::service('renderer')->renderRoot($content);
$this->assertStringContainsString('<div><strong><span>', (string) $rendered_entity);
// Test when 2 of 3 formats are selected.
$field->setSetting('allowed_formats', [$format1->id(), $format2->id()]);
$field->save();
$this->drupalGet('entity_test/add');
// We should see the 'format' selector again.
$this->assertSession()->fieldExists("{$field_name}[0][value]", NULL);
$this->assertSession()->optionExists("{$field_name}[0][format]", $format1->id());
$this->assertSession()->optionExists("{$field_name}[0][format]", $format2->id());
$this->assertSession()->optionNotExists("{$field_name}[0][format]", $format3->id());
// Change field to allow all formats by configuring none as allowed.
$field->setSetting('allowed_formats', []);
$field->save();
$this->drupalGet('entity_test/add');
// We should see the 'format' selector again.
$this->assertSession()->fieldExists("{$field_name}[0][value]", NULL);
$this->assertSession()->optionExists("{$field_name}[0][format]", $format1->id());
$this->assertSession()->optionExists("{$field_name}[0][format]", $format2->id());
$this->assertSession()->optionExists("{$field_name}[0][format]", $format3->id());
}
/**
* Helper function for testTextfieldWidgetsFormatted().
*/
public function _testTextfieldWidgetsFormatted($field_type, $widget_type) {
/** @var \Drupal\Core\Render\RendererInterface $renderer */
$renderer = $this->container->get('renderer');
// Create a field.
$field_name = mb_strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create([

View File

@ -3,6 +3,9 @@
namespace Drupal\Tests\text\Kernel;
use Drupal\Core\Field\BaseFieldDefinition;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\filter\Entity\FilterFormat;
use Drupal\KernelTests\KernelTestBase;
use Drupal\text\Plugin\Field\FieldType\TextItemBase;
@ -16,7 +19,7 @@ class TextItemBaseTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = ['filter', 'text'];
protected static $modules = ['filter', 'text', 'entity_test', 'field'];
/**
* Tests creation of sample values.
@ -57,4 +60,42 @@ class TextItemBaseTest extends KernelTestBase {
];
}
/**
* @covers ::calculateDependencies
*/
public function testCalculateDependencies() {
$format = FilterFormat::create([
'format' => 'test_format',
'name' => 'Test format',
]);
$fieldName = mb_strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create([
'field_name' => $fieldName,
'entity_type' => 'entity_test',
'type' => 'text',
]);
$field_storage->save();
$field = FieldConfig::create([
'field_name' => $fieldName,
'entity_type' => 'entity_test',
'bundle' => 'entity_test',
'settings' => [
'allowed_formats' => [$format->id()],
],
]);
$field->save();
$field->calculateDependencies();
$this->assertEquals([
'module' => [
'entity_test',
'text',
],
'config' => [
"field.storage.entity_test.$fieldName",
'filter.format.test_format',
],
], $field->getDependencies());
}
}

View File

@ -5,6 +5,10 @@
* Contains post update hooks for the text module.
*/
use Drupal\Core\Config\Entity\ConfigEntityUpdater;
use Drupal\field\FieldConfigInterface;
use Drupal\text\Plugin\Field\FieldType\TextItemBase;
/**
* Implements hook_removed_post_updates().
*/
@ -14,3 +18,24 @@ function text_removed_post_updates() {
'text_post_update_add_required_summary_flag_form_display' => '10.0.0',
];
}
/**
* Add allowed_formats setting to existing text fields.
*/
function text_post_update_allowed_formats(&$sandbox = NULL) {
\Drupal::classResolver(ConfigEntityUpdater::class)
->update($sandbox, 'field_config', function (FieldConfigInterface $field_config) {
$class = get_class($field_config);
// Deal only with text fields and descendants.
if (is_a($class, TextItemBase::class, TRUE)) {
// Get the existing allowed_formats setting.
$allowed_formats = $field_config->get('settings.allowed_formats');
if (!is_array($allowed_formats) && empty($allowed_formats)) {
// Save default value if existing value not present.
$field_config->set('settings.allowed_formats', []);
return TRUE;
}
}
return FALSE;
});
}

View File

@ -80,7 +80,10 @@ class ViewEntityDependenciesTest extends ViewsKernelTestBase {
'field_storage' => FieldStorageConfig::loadByName('node', 'body'),
'bundle' => $content_type->id(),
'label' => $this->randomMachineName() . '_body',
'settings' => ['display_summary' => TRUE],
'settings' => [
'display_summary' => TRUE,
'allowed_formats' => [],
],
])->save();
ViewTestData::createTestViews(static::class, ['views_test_config']);

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: false
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -16,5 +16,6 @@ required: false
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -16,5 +16,6 @@ required: false
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -16,5 +16,6 @@ required: true
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -16,5 +16,6 @@ required: true
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: false
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -16,5 +16,6 @@ required: true
translatable: true
default_value: { }
default_value_callback: ''
settings: { }
settings:
allowed_formats: { }
field_type: text_long

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary

View File

@ -19,4 +19,5 @@ default_value_callback: ''
settings:
display_summary: true
required_summary: false
allowed_formats: { }
field_type: text_with_summary