Issue #2395613 by dawehner: Make it possible to configure the output of a boolean field on the formatter level

8.0.x
Alex Pott 2015-02-02 11:09:18 +00:00
parent c8ec0cd3ab
commit d2ff08e0dc
3 changed files with 253 additions and 2 deletions

View File

@ -222,6 +222,19 @@ field.widget.settings.checkbox:
type: boolean
label: 'Use field label instead of the "On value" as label'
field.formatter.settings.boolean:
type: mapping
mapping:
format:
type: string
label: 'Output format'
format_custom_false:
type: string
label: 'Custom output for FALSE'
format_custom_true:
type: string
label: 'Custom output for TRUE'
field.formatter.settings.string:
type: mapping
mapping:

View File

@ -9,6 +9,7 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
/**
* Plugin implementation of the 'boolean' formatter.
@ -23,14 +24,107 @@ use Drupal\Core\Field\FieldItemListInterface;
*/
class BooleanFormatter extends FormatterBase {
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
$settings = [];
// Fall back to field settings by default.
$settings['format'] = 'default';
$settings['format_custom_false'] = '';
$settings['format_custom_true'] = '';
return $settings;
}
/**
* Gets the available format options.
*
* @return array|string
* A list of output formats. Each entry is keyed by the machine name of the
* format. The value is an array, of which the first item is the result for
* boolean TRUE, the second is for boolean FALSE. The value can be also an
* array, but this is just the case for the custom format.
*/
protected function getOutputFormats() {
$formats = [
'default' => [$this->getFieldSetting('on_label'), $this->getFieldSetting('off_label')],
'yes-no' => [$this->t('Yes'), $this->t('No')],
'true-false' => [$this->t('True'), $this->t('False')],
'on-off' => [$this->t('On'), $this->t('Off')],
'enabled-disabled' => [$this->t('Enabled'), $this->t('Disabled')],
'boolean' => [1, 0],
'unicode-yes-no' => ['✔', '✖'],
'custom' => $this->t('Custom'),
];
return $formats;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$formats = [];
foreach ($this->getOutputFormats() as $format_name => $format) {
if (is_array($format)) {
$formats[$format_name] = implode(' / ', $format);
}
else {
$formats[$format_name] = $format;
}
}
$form['format'] = [
'#type' => 'select',
'#title' => $this->t('Output format'),
'#default_value' => $this->getSetting('format'),
'#options' => $formats,
];
$form['format_custom_true'] = [
'#type' => 'textfield',
'#title' => $this->t('Custom output for TRUE'),
'#default_value' => $this->getSetting('format_custom_true'),
'#states' => [
'visible' => [
'select[name="fields[field_boolean][settings_edit_form][settings][format]"]' => ['value' => 'custom'],
],
],
];
$form['format_custom_false'] = [
'#type' => 'textfield',
'#title' => $this->t('Custom output for FALSE'),
'#default_value' => $this->getSetting('format_custom_false'),
'#states' => [
'visible' => [
'select[name="fields[field_boolean][settings_edit_form][settings][format]"]' => ['value' => 'custom'],
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
$elements = array();
$elements = [];
$formats = $this->getOutputFormats();
foreach ($items as $delta => $item) {
$elements[$delta] = array('#markup' => $item->value ? $this->getFieldSetting('on_label') : $this->getFieldSetting('off_label'));
$format = $this->getSetting('format');
if ($format == 'custom') {
$elements[$delta] = ['#markup' => $item->value ? $this->getSetting('format_custom_true') : $this->getSetting('format_custom_false')];
}
else {
$elements[$delta] = ['#markup' => $item->value ? $formats[$format][0] : $formats[$format][1]];
}
}
return $elements;

View File

@ -0,0 +1,144 @@
<?php
/**
* @file
* Contains \Drupal\field\Tests\Boolean\BooleanFormatterTest.
*/
namespace Drupal\field\Tests\Boolean;
use Drupal\Component\Utility\Unicode;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\entity_test\Entity\EntityTest;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Drupal\simpletest\KernelTestBase;
/**
* Tests the boolean formatter.
*
* @group field
*/
class BooleanFormatterTest extends KernelTestBase {
/**
* Modules to enable.
*
* @var array
*/
public static $modules = ['field', 'text', 'entity_test', 'user'];
/**
* @var string
*/
protected $entityType;
/**
* @var string
*/
protected $bundle;
/**
* @var string
*/
protected $fieldName;
/**
* @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface
*/
protected $display;
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$this->installConfig(['field']);
$this->installEntitySchema('entity_test');
$this->entityType = 'entity_test';
$this->bundle = $this->entityType;
$this->fieldName = Unicode::strtolower($this->randomMachineName());
$field_storage = FieldStorageConfig::create([
'field_name' => $this->fieldName,
'entity_type' => $this->entityType,
'type' => 'boolean',
]);
$field_storage->save();
$instance = FieldConfig::create([
'field_storage' => $field_storage,
'bundle' => $this->bundle,
'label' => $this->randomMachineName(),
]);
$instance->save();
$this->display = entity_get_display($this->entityType, $this->bundle, 'default')
->setComponent($this->fieldName, [
'type' => 'boolean',
'settings' => [],
]);
$this->display->save();
}
/**
* Renders fields of a given entity with a given display.
*
* @param \Drupal\Core\Entity\FieldableEntityInterface $entity
* The entity object with attached fields to render.
* @param \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
* The display to render the fields in.
*
* @return string
* The rendered entity fields.
*/
protected function renderEntityFields(FieldableEntityInterface $entity, EntityViewDisplayInterface $display) {
$content = $display->build($entity);
$content = $this->render($content);
return $content;
}
/**
* Tests boolean formatter output.
*/
public function testBooleanFormatter() {
$data = [];
$data[] = [0, [], 'Off'];
$data[] = [1, [], 'On'];
$format = ['format' => 'enabled-disabled'];
$data[] = [0, $format, 'Disabled'];
$data[] = [1, $format, 'Enabled'];
$format = ['format' => 'unicode-yes-no'];
$data[] = [1, $format, '✔'];
$data[] = [0, $format, '✖'];
$format = [
'format' => 'custom',
'format_custom_false' => 'FALSE',
'format_custom_true' => 'TRUE'
];
$data[] = [0, $format, 'FALSE'];
$data[] = [1, $format, 'TRUE'];
foreach ($data as $test_data) {
list($value, $settings, $expected) = $test_data;
$component = $this->display->getComponent($this->fieldName);
$component['settings'] = $settings;
$this->display->setComponent($this->fieldName, $component);
$entity = EntityTest::create([]);
$entity->{$this->fieldName}->value = $value;
// Verify that all HTML is escaped and newlines are retained.
$this->renderEntityFields($entity, $this->display);
$this->assertRaw($expected);
}
}
}