class TextFormat
Same name in this branch
- 11.x core/modules/config_translation/src/FormElement/TextFormat.php \Drupal\config_translation\FormElement\TextFormat
Same name and namespace in other branches
- 9 core/modules/config_translation/src/FormElement/TextFormat.php \Drupal\config_translation\FormElement\TextFormat
- 9 core/modules/filter/src/Element/TextFormat.php \Drupal\filter\Element\TextFormat
- 8.9.x core/modules/config_translation/src/FormElement/TextFormat.php \Drupal\config_translation\FormElement\TextFormat
- 8.9.x core/modules/filter/src/Element/TextFormat.php \Drupal\filter\Element\TextFormat
- 10 core/modules/config_translation/src/FormElement/TextFormat.php \Drupal\config_translation\FormElement\TextFormat
- 10 core/modules/filter/src/Element/TextFormat.php \Drupal\filter\Element\TextFormat
Provides a text format render element.
Properties:
@property $base_type The form element #type to use for the 'value' element. 'textarea' by default. @property $format (optional) The text format ID to preselect. If omitted, the default format for the current user will be used. @property $allowed_formats (optional) An array of text format IDs that are available for this element. If omitted, all text formats that the current user has access to will be allowed.
Usage Example:
$form['body'] = [
'#type' => 'text_format',
'#title' => 'Body',
'#format' => 'full_html',
'#default_value' => '<p>The quick brown fox jumped over the lazy dog.</p>',
];
Attributes
#[RenderElement('text_format')]
Hierarchy
- class \Drupal\Component\Plugin\PluginBase extends \Drupal\Component\Plugin\PluginInspectionInterface, \Drupal\Component\Plugin\DerivativeInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses \Drupal\Core\StringTranslation\StringTranslationTrait, \Drupal\Core\DependencyInjection\DependencySerializationTrait, \Drupal\Core\Messenger\MessengerTrait implements \Drupal\Component\Plugin\PluginBase
- class \Drupal\Core\Render\Element\RenderElementBase extends \Drupal\Core\Render\Element\ElementInterface, \Drupal\Core\Plugin\ContainerFactoryPluginInterface implements \Drupal\Core\Plugin\PluginBase
- class \Drupal\filter\Element\TextFormat implements \Drupal\Core\Render\Element\RenderElementBase
- class \Drupal\Core\Render\Element\RenderElementBase extends \Drupal\Core\Render\Element\ElementInterface, \Drupal\Core\Plugin\ContainerFactoryPluginInterface implements \Drupal\Core\Plugin\PluginBase
- class \Drupal\Core\Plugin\PluginBase uses \Drupal\Core\StringTranslation\StringTranslationTrait, \Drupal\Core\DependencyInjection\DependencySerializationTrait, \Drupal\Core\Messenger\MessengerTrait implements \Drupal\Component\Plugin\PluginBase
Expanded class hierarchy of TextFormat
See also
\Drupal\Core\Render\Element\Textarea
1 file declares its use of TextFormat
- TextfieldWidget.php in core/
modules/ text/ src/ Plugin/ Field/ FieldWidget/ TextfieldWidget.php
4 string references to 'TextFormat'
- ClaroPreRender::trustedCallbacks in core/
themes/ claro/ src/ ClaroPreRender.php - Lists the trusted callbacks provided by the implementing class.
- claro_element_info_alter in core/
themes/ claro/ claro.theme - Implements hook_element_info_alter().
- OliveroPreRender::trustedCallbacks in core/
themes/ olivero/ src/ OliveroPreRender.php - Lists the trusted callbacks provided by the implementing class.
- olivero_element_info_alter in core/
themes/ olivero/ olivero.theme - Implements hook_element_info_alter().
7 #type uses of TextFormat
- FilterTestFormatForm::buildForm in core/
modules/ filter/ tests/ filter_test/ src/ Form/ FilterTestFormatForm.php - Form constructor.
- FormTestDisabledElementsForm::buildForm in core/
modules/ system/ tests/ modules/ form_test/ src/ Form/ FormTestDisabledElementsForm.php - Form constructor.
- InputRequired::buildOptionsForm in core/
modules/ views/ src/ Plugin/ views/ exposed_form/ InputRequired.php - Provide a form to edit options for this plugin.
- JavascriptStatesForm::buildForm in core/
modules/ system/ tests/ modules/ form_test/ src/ Form/ JavascriptStatesForm.php - Form constructor.
- Text::buildOptionsForm in core/
modules/ views/ src/ Plugin/ views/ area/ Text.php - Provide a form to edit options for this plugin.
File
-
core/
modules/ filter/ src/ Element/ TextFormat.php, line 39
Namespace
Drupal\filter\ElementView source
class TextFormat extends RenderElementBase {
/**
* {@inheritdoc}
*/
public function getInfo() {
return [
'#process' => [
[
static::class,
'processFormat',
],
],
'#base_type' => 'textarea',
'#theme_wrappers' => [
'text_format_wrapper',
],
];
}
/**
* Expands an element into a base element with text format selector attached.
*
* The form element will be expanded into two separate form elements, one
* holding the original element, and the other holding the text format
* selector:
* - value: Holds the original element, having its #type changed to the value
* of #base_type or 'textarea' by default.
* - format: Holds the text format details and the text format selection,
* using the text format ID specified in #format or the user's default
* format by default, if NULL.
*
* The resulting value for the element will be an array holding the value and
* the format. For example, the value for the body element will be:
* @code
* $values = $form_state->getValue('body');
* $values['value'] = 'foo';
* $values['format'] = 'foo';
* @endcode
*
* @param array $element
* The form element to process. See main class documentation for properties.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
* @param array $complete_form
* The complete form structure.
*
* @return array
* The form element.
*/
public static function processFormat(&$element, FormStateInterface $form_state, &$complete_form) {
$user = static::currentUser();
// Ensure that children appear as subkeys of this element.
$element['#tree'] = TRUE;
$keys_not_to_copy = [
// Make \Drupal::formBuilder()->doBuildForm() regenerate child properties.
'#parents',
'#id',
'#name',
// Do not copy this #process function to prevent
// \Drupal::formBuilder()->doBuildForm() from recursing infinitely.
'#process',
// Ensure #pre_render functions will be run.
'#pre_render',
// Description is handled by theme_text_format_wrapper().
'#description',
// Ensure proper ordering of children.
'#weight',
// Properties already processed for the parent element.
'#prefix',
'#suffix',
'#attached',
'#processed',
'#theme_wrappers',
];
// Move this element into sub-element 'value'.
unset($element['value']);
foreach (Element::properties($element) as $key) {
if (!in_array($key, $keys_not_to_copy)) {
$element['value'][$key] = $element[$key];
}
}
$element['value']['#type'] = $element['#base_type'];
$element['value'] += static::elementInfo()->getInfo($element['#base_type']);
// Make sure the #default_value key is set, so we can use it below.
$element['value'] += [
'#default_value' => '',
];
// Turn original element into a text format wrapper.
$element['#attached']['library'][] = 'filter/drupal.filter';
// Setup child container for the text format widget.
$element['format'] = [
'#type' => 'container',
'#theme_wrappers' => [
'container__text_format_filter_wrapper',
],
'#attributes' => [
'class' => [
'js-filter-wrapper',
],
],
];
// Get a list of formats that the current user has access to.
$formats = filter_formats($user);
// Allow the list of formats to be restricted.
if (isset($element['#allowed_formats'])) {
// We do not add the fallback format here to allow the use-case of forcing
// certain text formats to be used for certain text areas. In case the
// fallback format is supposed to be allowed as well, it must be added to
// $element['#allowed_formats'] explicitly.
$formats = array_intersect_key($formats, array_flip($element['#allowed_formats']));
}
if (!isset($element['#format']) && !empty($formats)) {
// If no text format was selected, use the allowed format with the highest
// weight. This is equivalent to calling filter_default_format().
$element['#format'] = reset($formats)->id();
}
// If #allowed_formats is set, the list of formats must not be modified in
// any way. Otherwise, however, if all of the following conditions are true,
// remove the fallback format from the list of formats:
// 1. The 'always_show_fallback_choice' filter setting has not been
// activated.
// 2. Multiple text formats are available.
// 3. The fallback format is not the default format.
// The 'always_show_fallback_choice' filter setting is a hidden setting that
// has no UI. It defaults to FALSE.
$config = static::configFactory()->get('filter.settings');
if (!isset($element['#allowed_formats']) && !$config->get('always_show_fallback_choice')) {
$fallback_format = $config->get('fallback_format');
if ($element['#format'] !== $fallback_format && count($formats) > 1) {
unset($formats[$fallback_format]);
}
}
// If the value element has #states set, copy it to the format element.
if (isset($element['value']['#states'])) {
$element['format']['#states'] = $element['value']['#states'];
}
// Prepare text format guidelines.
$element['format']['guidelines'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'js-filter-guidelines',
],
],
'#theme_wrappers' => [
'container__text_format_filter_guidelines',
],
'#weight' => 20,
];
$options = [];
foreach ($formats as $format) {
$options[$format->id()] = $format->label();
$element['format']['guidelines'][$format->id()] = [
'#theme' => 'filter_guidelines',
'#format' => $format,
];
}
$element['format']['format'] = [
'#type' => 'select',
'#title' => t('Text format'),
'#options' => $options,
'#default_value' => $element['#format'],
'#access' => count($formats) > 1,
'#weight' => 10,
'#attributes' => [
'class' => [
'js-filter-list',
],
],
'#parents' => array_merge($element['#parents'], [
'format',
]),
];
$element['format']['help'] = [
'#type' => 'container',
'#theme_wrappers' => [
'container__text_format_filter_help',
],
'about' => [
'#type' => 'link',
'#title' => t('About text formats'),
'#url' => new Url('filter.tips_all'),
'#attributes' => [
'target' => '_blank',
],
],
'#weight' => 0,
];
$all_formats = filter_formats();
$format_exists = isset($all_formats[$element['#format']]);
$format_allowed = !isset($element['#allowed_formats']) || in_array($element['#format'], $element['#allowed_formats']);
$user_has_access = isset($formats[$element['#format']]);
$user_is_admin = $user->hasPermission('administer filters');
// If the stored format does not exist or if it is not among the allowed
// formats for this textarea, administrators have to assign a new format.
if ((!$format_exists || !$format_allowed) && $user_is_admin) {
$element['format']['format']['#required'] = TRUE;
$element['format']['format']['#default_value'] = NULL;
// Force access to the format selector (it may have been denied above if
// the user only has access to a single format).
$element['format']['format']['#access'] = TRUE;
}
elseif (!$user_has_access || !$format_exists) {
// Overload default values into #value to make them unalterable.
$element['value']['#value'] = $element['value']['#default_value'];
$element['format']['format']['#value'] = $element['format']['format']['#default_value'];
// Prepend #pre_render callback to replace field value with user notice
// prior to rendering.
$element['value'] += [
'#pre_render' => [],
];
array_unshift($element['value']['#pre_render'], [
static::class,
'accessDeniedCallback',
]);
// Cosmetic adjustments.
if (isset($element['value']['#rows'])) {
$element['value']['#rows'] = 3;
}
$element['value']['#disabled'] = TRUE;
$element['value']['#resizable'] = 'none';
// Hide the text format selector and any other child element (such as text
// field's summary).
foreach (Element::children($element) as $key) {
if ($key != 'value') {
$element[$key]['#access'] = FALSE;
}
}
}
return $element;
}
/**
* Render API callback: Hides the field value of 'text_format' elements.
*
* To not break form processing and previews if a user does not have access to
* a stored text format, the expanded form elements in
* \Drupal\filter\Element\TextFormat::processFormat() are forced to take over
* the stored #default_values for 'value' and 'format'. However, to prevent
* the unfiltered, original #value from being displayed to the user, we
* replace it with a friendly notice here.
*
* @param array $element
* The render array to add the access denied message to.
*
* @return array
* The updated render array.
*/
public static function accessDeniedCallback(array $element) {
$element['#value'] = t('This field has been disabled because you do not have sufficient permissions to edit it.');
return $element;
}
/**
* Wraps the current user.
*
* \Drupal\Core\Session\AccountInterface
*/
protected static function currentUser() {
return \Drupal::currentUser();
}
/**
* Wraps the config factory.
*
* @return \Drupal\Core\Config\ConfigFactoryInterface
* The configuration factory service.
*/
protected static function configFactory() {
return \Drupal::configFactory();
}
/**
* Wraps the element info service.
*
* @return \Drupal\Core\Render\ElementInfoManagerInterface
* The element info service.
*/
protected static function elementInfo() {
return \Drupal::service('element_info');
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title | Overrides |
---|---|---|---|---|---|
PluginInspectionInterface::getPluginDefinition | public | function | Gets the definition of the plugin implementation. | 7 | |
PluginInspectionInterface::getPluginId | public | function | Gets the plugin ID of the plugin instance. | 3 | |
RenderElementBase::$renderParent | protected | property | The parent element. | ||
RenderElementBase::$renderParentName | protected | property | The parent key. | ||
RenderElementBase::$storage | protected | property | The storage. | ||
RenderElementBase::addChild | public | function | Adds a child render element. | Overrides ElementInterface::addChild | |
RenderElementBase::changeType | public | function | Change the type of the element. | Overrides ElementInterface::changeType | |
RenderElementBase::create | public static | function | Creates an instance of the plugin. | Overrides ContainerFactoryPluginInterface::create | |
RenderElementBase::createChild | public | function | Creates a render object and attaches it to the current render object. | Overrides ElementInterface::createChild | |
RenderElementBase::elementInfoManager | protected | function | Returns the element info manager. | ||
RenderElementBase::getChild | public | function | Gets a child. | Overrides ElementInterface::getChild | |
RenderElementBase::getChildren | public | function | Returns child elements. | Overrides ElementInterface::getChildren | |
RenderElementBase::initializeInternalStorage | public | function | Initialize storage. | Overrides ElementInterface::initializeInternalStorage | |
RenderElementBase::preRenderAjaxForm | public static | function | Adds Ajax information about an element to communicate with JavaScript. | 2 | |
RenderElementBase::preRenderGroup | public static | function | Adds members of this group as actual elements for rendering. | 2 | |
RenderElementBase::processAjaxForm | public static | function | Form element processing handler for the #ajax form property. | 3 | |
RenderElementBase::processGroup | public static | function | Arranges elements into groups. | 2 | |
RenderElementBase::removeChild | public | function | Removes a child. | Overrides ElementInterface::removeChild | |
RenderElementBase::setAttributes | public static | function | Sets a form element's class attribute. | Overrides ElementInterface::setAttributes | 2 |
RenderElementBase::setType | protected | function | Set type on initialize. | ||
RenderElementBase::toRenderable | public | function | Returns a render array. | Overrides ElementInterface::toRenderable | |
RenderElementBase::__construct | public | function | Constructs a new render element object. | ||
RenderElementBase::__get | public | function | Magic method: gets a property value. | ||
RenderElementBase::__isset | public | function | Magic method: checks if a property value is set. | ||
RenderElementBase::__set | public | function | Magic method: Sets a property value. | ||
RenderElementBase::__sleep | public | function | |||
RenderElementBase::__unset | public | function | Magic method: unsets a property value. | ||
RenderElementBase::__wakeup | public | function | |||
TextFormat::accessDeniedCallback | public static | function | Render API callback: Hides the field value of 'text_format' elements. | ||
TextFormat::configFactory | protected static | function | Wraps the config factory. | ||
TextFormat::currentUser | protected static | function | Wraps the current user. | ||
TextFormat::elementInfo | protected static | function | Wraps the element info service. | ||
TextFormat::getInfo | public | function | Returns the element properties for this element. | Overrides ElementInterface::getInfo | |
TextFormat::processFormat | public static | function | Expands an element into a base element with text format selector attached. |
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.