diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index 2d1b7dc..6519b97 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -229,6 +229,13 @@ field.formatter.settings.string: type: boolean label: 'Link to the entity' +field.formatter.settings.language: + type: field.formatter.settings.string + mapping: + native_language: + type: boolean + label: 'Display in native language' + field.formatter.settings.number_decimal: type: mapping label: 'Number decimal display format settings' diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php index d936b89..2d814e4 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php @@ -8,8 +8,9 @@ namespace Drupal\Core\Field\Plugin\Field\FieldFormatter; use Drupal\Component\Utility\String; -use Drupal\Core\Field\FormatterBase; +use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Field\FieldItemListInterface; +use Drupal\Core\Form\FormStateInterface; /** * Plugin implementation of the 'language' formatter. @@ -22,19 +23,53 @@ * } * ) */ -class LanguageFormatter extends FormatterBase { +class LanguageFormatter extends StringFormatter { /** * {@inheritdoc} */ - public function viewElements(FieldItemListInterface $items) { - $elements = array(); + public static function defaultSettings() { + $settings = parent::defaultSettings(); + $settings['native_language'] = FALSE; + return $settings; + } - foreach ($items as $delta => $item) { - $elements[$delta] = array('#markup' => $item->language ? String::checkPlain($item->language->getName()) : ''); + /** + * {@inheritdoc} + */ + public function settingsForm(array $form, FormStateInterface $form_state) { + $form = parent::settingsForm($form, $form_state); + $form['native_language'] = array( + '#title' => $this->t('Display in native language'), + '#type' => 'checkbox', + '#default_value' => $this->getSetting('native_language'), + ); + return $form; + } + + /** + * {@inheritdoc} + */ + public function settingsSummary() { + $summary = parent::settingsSummary(); + if ($this->getSetting('native_language')) { + $additional_summary = $this->t('Displayed in native language'); + if (!empty($summary['#markup'])) { + $summary['#markup'] .= '; ' . $additional_summary; + } + else { + $summary['#markup'] = $additional_summary; + } } + return $summary; + } - return $elements; + /** + * {@inheritdoc} + */ + protected function viewValue(FieldItemInterface $item) { + $languages = $languages = $this->getSetting('native_language') ? \Drupal::languageManager()->getNativeLanguages() : \Drupal::languageManager()->getLanguages(); + return $item->language ? String::checkPlain($languages[$item->language->getId()]->getName()) : ''; } } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php index ec9b79d..5949528 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php @@ -10,6 +10,7 @@ use Drupal\Component\Utility\String; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\Field\FieldItemInterface; use Drupal\Core\Field\FormatterBase; use Drupal\Core\Field\FieldItemListInterface; use Drupal\Core\Form\FormStateInterface; @@ -127,7 +128,7 @@ public function viewElements(FieldItemListInterface $items) { foreach ($items as $delta => $item) { // The text value has no text format assigned to it, so the user input // should equal the output, including newlines. - $string = nl2br(String::checkPlain($item->value)); + $string = $this->viewValue($item); if ($url) { $elements[$delta] = [ @@ -144,4 +145,17 @@ public function viewElements(FieldItemListInterface $items) { return $elements; } + /** + * Generate the output appropriate for one field item. + * + * @param \Drupal\Core\Field\FieldItemInterface $item + * One field item. + * + * @return string + * The textual output generated. + */ + protected function viewValue(FieldItemInterface $item) { + return nl2br(String::checkPlain($item->value)); + } + } diff --git a/core/modules/node/config/schema/node.views.schema.yml b/core/modules/node/config/schema/node.views.schema.yml index b1d24d9..a8e4cfa 100644 --- a/core/modules/node/config/schema/node.views.schema.yml +++ b/core/modules/node/config/schema/node.views.schema.yml @@ -93,14 +93,6 @@ views.argument_validator.node: type: string label: 'Filter value format' -views.field.node_language: - type: views.field.node - label: 'Node language' - mapping: - native_language: - type: boolean - label: 'Native language' - views.field.node: type: views_field label: 'Node' diff --git a/core/modules/node/src/NodeViewsData.php b/core/modules/node/src/NodeViewsData.php index ca2bb26..d7f97c5 100644 --- a/core/modules/node/src/NodeViewsData.php +++ b/core/modules/node/src/NodeViewsData.php @@ -40,7 +40,6 @@ public function getViewsData() { $data['node_field_data']['type']['argument']['id'] = 'node_type'; $data['node_field_data']['langcode']['help'] = t('The language of the content or translation.'); - $data['node_field_data']['langcode']['field']['id'] = 'node_language'; $data['node_field_data']['status']['field']['output formats'] = [ 'published-notpublished' => array(t('Published'), t('Not published')), @@ -290,7 +289,6 @@ public function getViewsData() { ) + $data['node_revision']['vid']; $data['node_revision']['langcode']['help'] = t('The language the original content is in.'); - $data['node_revision']['langcode']['field']['id'] = 'node_language'; $data['node_revision']['revision_log']['field']['id'] = 'xss'; @@ -312,7 +310,6 @@ public function getViewsData() { $data['node_field_revision']['title']['field']['id'] = 'node_revision'; $data['node_field_revision']['langcode']['help'] = t('The language of the content or translation.'); - $data['node_field_revision']['langcode']['field']['id'] = 'node_language'; $data['node_revision']['link_to_revision'] = array( 'field' => array( diff --git a/core/modules/node/src/Plugin/views/field/Language.php b/core/modules/node/src/Plugin/views/field/Language.php deleted file mode 100644 index 10acf52..0000000 --- a/core/modules/node/src/Plugin/views/field/Language.php +++ /dev/null @@ -1,52 +0,0 @@ - FALSE); - - return $options; - } - - public function buildOptionsForm(&$form, FormStateInterface $form_state) { - parent::buildOptionsForm($form, $form_state); - $form['native_language'] = array( - '#title' => $this->t('Native language'), - '#type' => 'checkbox', - '#default_value' => $this->options['native_language'], - '#description' => $this->t('If enabled, the native name of the language will be displayed'), - ); - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - // @todo: Drupal Core dropped native language until config translation is - // ready, see http://drupal.org/node/1616594. - $value = $this->getValue($values); - $language = \Drupal::languageManager()->getLanguage($value); - $value = $language ? $language->getName() : ''; - return $this->renderLink($value, $values); - } - -} diff --git a/core/modules/node/src/Tests/Views/NodeLanguageTest.php b/core/modules/node/src/Tests/Views/NodeLanguageTest.php index 0195b44..ac33a59 100644 --- a/core/modules/node/src/Tests/Views/NodeLanguageTest.php +++ b/core/modules/node/src/Tests/Views/NodeLanguageTest.php @@ -226,4 +226,53 @@ public function testLanguages() { } } } + + /** + * Tests native name display in language field. + */ + public function testNativeLanguageField() { + $this->assertLanguageNames(); + + // Modify test view to display native language names and set translations. + $config = $this->config('views.view.test_language'); + $config->set('display.default.display_options.fields.langcode.settings.native_language', TRUE); + $config->save(); + \Drupal::languageManager()->getLanguageConfigOverride('fr', 'language.entity.fr')->set('label', 'Français')->save(); + \Drupal::languageManager()->getLanguageConfigOverride('es', 'language.entity.es')->set('label', 'Español')->save(); + $this->assertLanguageNames(TRUE); + + // Modify test view to use the views built-in language field and test that. + $config = $this->config('views.view.test_language'); + $config->set('display.default.display_options.fields.langcode.native_language', FALSE); + $config->clear('display.default.display_options.fields.langcode.settings'); + $config->clear('display.default.display_options.fields.langcode.type'); + $config->set('display.default.display_options.fields.langcode.plugin_id', 'language'); + $config->save(); + $this->assertLanguageNames(); + $config->set('display.default.display_options.fields.langcode.native_language', TRUE)->save(); + $this->assertLanguageNames(TRUE); + } + + /** + * Assert the presence of language names in their English or native forms. + * + * @param bool $native + * (optional) Whether to assert the language name in its native form. + */ + protected function assertLanguageNames($native = FALSE) { + $this->drupalGet('test-language'); + if ($native) { + $this->assertText('Français', 'French language shown translated.'); + $this->assertText('Español', 'Spanish language shown translated.'); + $this->assertNoText('French', 'French language not shown in English.'); + $this->assertNoText('Spanish', 'Spanish language not shown in English.'); + } + else { + $this->assertNoText('Français', 'French language not shown translated.'); + $this->assertNoText('Español', 'Spanish language not shown translated.'); + $this->assertText('French', 'French language shown in English.'); + $this->assertText('Spanish', 'Spanish language shown in English.'); + } + } + } diff --git a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml index 462d371..6909f44 100644 --- a/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml +++ b/core/modules/node/tests/modules/node_test_views/test_views/views.view.test_language.yml @@ -159,11 +159,12 @@ display: hide_empty: false empty_zero: false hide_alter_empty: true - link_to_node: false - native_language: false - plugin_id: node_language + plugin_id: field entity_type: node entity_field: langcode + settings: + native_language: false + type: language filters: status: value: true diff --git a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml index d64639e..cf80f28 100644 --- a/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml +++ b/core/modules/taxonomy/config/schema/taxonomy.views.schema.yml @@ -83,10 +83,6 @@ views.argument_default.taxonomy_tid: type: string label: 'Multiple-value handling' -views.field.taxonomy_term_language: - type: views.field.taxonomy - label: 'Taxonomy language' - views.field.term_link_edit: type: views_field label: 'Taxonomy language' diff --git a/core/modules/taxonomy/src/Plugin/views/field/Language.php b/core/modules/taxonomy/src/Plugin/views/field/Language.php deleted file mode 100644 index 3fbc0b8..0000000 --- a/core/modules/taxonomy/src/Plugin/views/field/Language.php +++ /dev/null @@ -1,30 +0,0 @@ -getValue($values); - $language = \Drupal::languageManager()->getLanguage($value); - $value = $language ? $language->getName() : ''; - - return $this->renderLink($this->sanitizeValue($value), $values); - } - -} diff --git a/core/modules/taxonomy/src/TermViewsData.php b/core/modules/taxonomy/src/TermViewsData.php index 4b4e578..ca88036 100644 --- a/core/modules/taxonomy/src/TermViewsData.php +++ b/core/modules/taxonomy/src/TermViewsData.php @@ -100,8 +100,6 @@ public function getViewsData() { $data['taxonomy_term_field_data']['description__value']['field']['click sortable'] = FALSE; - $data['taxonomy_term_field_data']['langcode']['field']['id'] = 'taxonomy_term_language'; - $data['taxonomy_term_field_data']['changed']['title'] = t('Updated date'); $data['taxonomy_term_field_data']['changed']['help'] = t('The date the term was last updated.'); diff --git a/core/modules/user/config/schema/user.views.schema.yml b/core/modules/user/config/schema/user.views.schema.yml index e1b83f3..46cb281 100644 --- a/core/modules/user/config/schema/user.views.schema.yml +++ b/core/modules/user/config/schema/user.views.schema.yml @@ -67,10 +67,6 @@ views_field_user: type: boolean label: 'Link this field to its user' -views.field.user_language: - type: views_field_user - label: 'User language' - views.field.user_link: type: views_field label: 'User link' diff --git a/core/modules/user/src/Plugin/views/field/Language.php b/core/modules/user/src/Plugin/views/field/Language.php deleted file mode 100644 index bf5abaa..0000000 --- a/core/modules/user/src/Plugin/views/field/Language.php +++ /dev/null @@ -1,51 +0,0 @@ -options['link_to_user'])) { - $uid = $this->getValue($values, 'uid'); - if ($this->view->getUser()->hasPermission('access user profiles') && $uid) { - $this->options['alter']['make_link'] = TRUE; - $this->options['alter']['path'] = 'user/' . $uid; - } - } - if (empty($data)) { - $lang = \Drupal::languageManager()->getDefaultLanguage(); - } - else { - $lang = \Drupal::languageManager()->getLanguages(); - $lang = $lang[$data]; - } - - return $this->sanitizeValue($lang->getName()); - } - - /** - * {@inheritdoc} - */ - public function render(ResultRow $values) { - $value = $this->getValue($values); - return $this->renderLink($this->sanitizeValue($value), $values); - } - -} diff --git a/core/modules/user/src/UserViewsData.php b/core/modules/user/src/UserViewsData.php index acf2100..3c46c35 100644 --- a/core/modules/user/src/UserViewsData.php +++ b/core/modules/user/src/UserViewsData.php @@ -88,7 +88,6 @@ public function getViewsData() { $data['users_field_data']['mail']['help'] = t('Email address for a given user. This field is normally not shown to users, so be cautious when using it.'); $data['users_field_data']['mail']['field']['id'] = 'user_mail'; - $data['users']['langcode']['id'] = 'user_language'; $data['users']['langcode']['help'] = t('Original language of the user information'); $data['users_field_data']['langcode']['help'] = t('Language of the translation of user information'); diff --git a/core/modules/views/config/schema/views.field.schema.yml b/core/modules/views/config/schema/views.field.schema.yml index c515361..8a28f38 100644 --- a/core/modules/views/config/schema/views.field.schema.yml +++ b/core/modules/views/config/schema/views.field.schema.yml @@ -178,3 +178,7 @@ views.field.xss: views.field.language: type: views_field label: 'Language' + mapping: + native_language: + type: boolean + label: 'Display in native language' diff --git a/core/modules/views/src/EntityViewsData.php b/core/modules/views/src/EntityViewsData.php index cb30422..91ad27c 100644 --- a/core/modules/views/src/EntityViewsData.php +++ b/core/modules/views/src/EntityViewsData.php @@ -300,7 +300,7 @@ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $co break; case 'language': - $views_field['field']['id'] = 'language'; + $views_field['field']['id'] = 'field'; $views_field['argument']['id'] = 'language'; $views_field['filter']['id'] = 'language'; $views_field['sort']['id'] = 'standard'; diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php index 05f6335..93e36c5 100644 --- a/core/modules/views/src/Plugin/views/field/Field.php +++ b/core/modules/views/src/Plugin/views/field/Field.php @@ -8,7 +8,7 @@ namespace Drupal\views\Plugin\views\field; use Drupal\Component\Utility\SafeMarkup; -use Drupal\Component\Utility\Xss; +use Drupal\Component\Utility\Xss as UtilityXss; use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityManagerInterface; use Drupal\Core\Entity\EntityStorageInterface; @@ -918,7 +918,7 @@ protected function addSelfTokens(&$tokens, $item) { (is_object($item['raw']) ? (array)$item['raw'] : NULL); } if (isset($raw) && isset($raw[$id]) && is_scalar($raw[$id])) { - $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = Xss::filterAdmin($raw[$id]); + $tokens['{{ ' . $this->options['id'] . '-' . $id . ' }}'] = UtilityXss::filterAdmin($raw[$id]); } else { // Make sure that empty values are replaced as well. diff --git a/core/modules/views/src/Plugin/views/field/LanguageField.php b/core/modules/views/src/Plugin/views/field/LanguageField.php index 2933ae7..bbc28ef 100644 --- a/core/modules/views/src/Plugin/views/field/LanguageField.php +++ b/core/modules/views/src/Plugin/views/field/LanguageField.php @@ -19,6 +19,9 @@ */ class LanguageField extends FieldPluginBase { + /** + * {@inheritdoc} + */ protected function defineOptions() { $options = parent::defineOptions(); $options['native_language'] = array('default' => FALSE); @@ -26,13 +29,15 @@ protected function defineOptions() { return $options; } + /** + * {@inheritdoc} + */ public function buildOptionsForm(&$form, FormStateInterface $form_state) { parent::buildOptionsForm($form, $form_state); $form['native_language'] = array( - '#title' => $this->t('Native language'), + '#title' => $this->t('Display in native language'), '#type' => 'checkbox', '#default_value' => $this->options['native_language'], - '#description' => $this->t('If enabled, the native name of the language will be displayed'), ); } @@ -40,11 +45,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { * {@inheritdoc} */ public function render(ResultRow $values) { - // @todo: Drupal Core dropped native language until config translation is - // ready, see http://drupal.org/node/1616594. $value = $this->getValue($values); - $language = \Drupal::languageManager()->getLanguage($value); - return $language ? $language->getName() : ''; + $languages = $this->options['native_language'] ? \Drupal::languageManager()->getNativeLanguages() : \Drupal::languageManager()->getLanguages(); + return isset($languages[$value]) ? $languages[$value]->getName() : ''; } } diff --git a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php index c1aac0f..bee18f2 100644 --- a/core/modules/views/tests/src/Unit/EntityViewsDataTest.php +++ b/core/modules/views/tests/src/Unit/EntityViewsDataTest.php @@ -705,7 +705,7 @@ protected function assertNumericField($data) { * The views data to check. */ protected function assertLanguageField($data) { - $this->assertEquals('language', $data['field']['id']); + $this->assertEquals('field', $data['field']['id']); $this->assertEquals('language', $data['filter']['id']); $this->assertEquals('language', $data['argument']['id']); $this->assertEquals('standard', $data['sort']['id']);