diff --git a/core/modules/config_translation/config_translation.module b/core/modules/config_translation/config_translation.module index 0fc1170..0956bd1 100644 --- a/core/modules/config_translation/config_translation.module +++ b/core/modules/config_translation/config_translation.module @@ -153,13 +153,28 @@ function config_translation_entity_operation_alter(array &$operations, EntityInt /** * Implements hook_config_translation_type_info_alter(). + * + * @todo: Convert this hook into a real typed date alter hook. */ function config_translation_config_translation_type_info_alter(&$definitions) { + $map = array( + 'label' => '\Drupal\config_translation\FormElement\Textfield', + 'text' => '\Drupal\config_translation\FormElement\Textarea', + 'date_format' => '\Drupal\config_translation\FormElement\DateFormat', + 'text_with_format' => '\Drupal\config_translation\FormElement\TextFormat', + ); + // Enhance the text and date type definitions with classes to generate proper // form elements in ConfigTranslationFormBase. Other translatable types will // appear as a one line textfield. - $definitions['text']['form_element_class'] = '\Drupal\config_translation\FormElement\Textarea'; - $definitions['date_format']['form_element_class'] = '\Drupal\config_translation\FormElement\DateFormat'; + foreach ($definitions as $type => $definition) { + if (isset($map[$definition['type']])) { + $definitions[$type]['form_element_class'] = $map[$definition['type']]; + } + if (isset($definition['translatable']) && ($definition['translatable'] == TRUE) && !isset($definitions[$type]['form_element_class'])) { + $definitions[$type]['form_element_class'] = '\Drupal\config_translation\FormElement\Textfield'; + } + } } /** diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php index e559ea1..1f89eab 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Form/ConfigTranslationFormBase.php @@ -262,8 +262,19 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d foreach ($schema as $key => $element) { // Make the specific element key, "$base_key.$key". $element_key = implode('.', array_filter(array($base_key, $key))); + $definition = $element->getDefinition() + array('label' => $this->t('N/A')); - if ($element instanceof Element) { + + // Invoke hook_config_translation_type_info_alter() implementations to + // alter the configuration types. + $definitions = array( + $definition['type'] => &$definition, + ); + + $this->moduleHandler->alter('config_translation_type_info', $definitions); + $element_type = $definition['type']; + + if ($element instanceof Element && !isset($definitions[$element_type]['form_element_class'])) { // Build sub-structure and include it with a wrapper in the form // if there are any translatable elements there. $sub_build = $this->buildConfigForm($element, $config_data[$key], $base_config_data[$key], TRUE, $element_key); @@ -296,27 +307,12 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d ) + $sub_build; } } - else { - $definition = $element->getDefinition(); - - // Invoke hook_config_translation_type_info_alter() implementations to - // alter the configuration types. - $definitions = array( - $definition['type'] => &$definition, - ); - $this->moduleHandler->alter('config_translation_type_info', $definitions); - - // Create form element only for translatable items. - if (!isset($definition['translatable']) || !isset($definition['type'])) { - continue; - } - + elseif (isset($definition['form_element_class'])) { $value = $config_data[$key]; $build[$element_key] = array( '#theme' => 'config_translation_manage_form_element', ); $build[$element_key]['source'] = array( - '#markup' => $base_config_data[$key] ? ('' . nl2br($base_config_data[$key] . '')) : t('(Empty)'), '#title' => $this->t( '!label (!source_language)', array( @@ -327,10 +323,10 @@ protected function buildConfigForm(Element $schema, $config_data, $base_config_d '#type' => 'item', ); - $definition += array('form_element_class' => '\Drupal\config_translation\FormElement\Textfield'); - /** @var \Drupal\config_translation\FormElement\ElementInterface $form_element */ $form_element = new $definition['form_element_class'](); + + $build[$element_key]['source']['#markup'] = $form_element->getRenderedSource($base_config_data, $key, $this->sourceLanguage, $this->language); $build[$element_key]['translation'] = $form_element->getFormElement($definition, $this->language, $value); } } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Element.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Element.php index 40a43c2..c0d4c76 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Element.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/Element.php @@ -6,6 +6,7 @@ */ namespace Drupal\config_translation\FormElement; +use Drupal\Core\Language\Language; /** * Defines a base class for form elements. @@ -41,4 +42,11 @@ protected function translationManager() { return $this->translationManager; } + /** + * {@inheritdoc} + */ + public function getRenderedSource($base_config_data, $key, Language $source_language, Language $language) { + return $base_config_data[$key] ? ('' . nl2br($base_config_data[$key] . '')) : t('(Empty)'); + } + } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php index 9072cfc..9b8f543 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/ElementInterface.php @@ -29,4 +29,22 @@ */ public function getFormElement(array $definition, Language $language, $value); + /** + * Returns the rendered source element for a given configuration definition. + * + * @param array|string $base_config_data + * Configuration object of base language, a string when done traversing + * the data building each sub-structure for the form. + * @param $key + * The key in the configuration object. + * @param \Drupal\Core\Language\Language $source_language + * Thee source language of the configuration object. + * @param \Drupal\Core\Language\Language $language + * Language object to display the translation form for. + * + * @return string + * The rendered value in source language. + */ + public function getRenderedSource($base_config_data, $key, Language $source_language, Language $language); + } diff --git a/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php new file mode 100644 index 0000000..a3b7657 --- /dev/null +++ b/core/modules/config_translation/lib/Drupal/config_translation/FormElement/TextFormat.php @@ -0,0 +1,39 @@ + 'text_format', + '#default_value' => $value['value'], + '#format' => $value['format'], + '#title' => $this->t($definition['label']) . ' (' . $language->name . ')', + '#attributes' => array('lang' => $language->id), + ); + return $element; + } + + /** + * {@inheritdoc} + */ + public function getRenderedSource($base_config_data, $key, Language $source_language, Language $language) { + $value = check_markup($base_config_data[$key]['value'], $base_config_data[$key]['format'], $source_language->id); + return $value ? '' . $value . '' : t('(Empty)'); + } + +} diff --git a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php index dfda109..a4b0bab 100644 --- a/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php +++ b/core/modules/config_translation/lib/Drupal/config_translation/Tests/ConfigTranslationUiTest.php @@ -23,7 +23,7 @@ class ConfigTranslationUiTest extends WebTestBase { * * @var array */ - public static $modules = array('contact', 'config_translation', 'config_translation_test', 'views', 'views_ui', 'contextual'); + public static $modules = array('contact', 'config_translation', 'config_translation_test', 'views', 'views_ui', 'contextual', 'filter'); /** * Languages to enable. @@ -671,6 +671,58 @@ public function testThemeDiscovery() { } /** + * Test text_format translation. + */ + public function testTextFormatTranslation() { + $this->drupalLogin($this->admin_user); + $file_storage = new FileStorage($this->configDirectories[CONFIG_ACTIVE_DIRECTORY]); + + $config_parsed = $file_storage->read('config_translation_test.content'); + $config_parsed_compare = array( + 'content' => array( + 'value' => $config_parsed['content']['value'], + 'format' => $config_parsed['content']['format'], + ), + ); + + $expected = array( + 'content' => array( + 'value' => 'Hello World', + 'format' => 'plain_text', + ), + ); + $this->assertEqual($expected, $config_parsed_compare); + + $translation_base_url = 'admin/config/media/file-system/translate'; + $this->drupalGet($translation_base_url); + + // 'Add' link should be present for French translation. + $translation_page_url = "$translation_base_url/fr/add"; + $this->assertLinkByHref($translation_page_url); + + // Make sure original text is present on this page. + $this->drupalGet($translation_page_url); + + // Update translatable fields. + $edit = array( + 'config_names[config_translation_test.content][content][translation][value]' => 'Hello World - FR', + ); + + // Save language specific version of form. + $this->drupalPostForm($translation_page_url, $edit, t('Save translation')); + + // Get translation and check we've got the right value. + $config_parsed = $file_storage->read('locale.config.fr.config_translation_test.content'); + $expected = array( + 'content' => array( + 'value' => 'Hello World - FR', + 'format' => 'plain_text', + ), + ); + $this->assertEqual($expected, $config_parsed); + } + + /** * Gets translation from locale storage. * * @param $config_name diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config/config_translation_test.content.yml b/core/modules/config_translation/tests/modules/config_translation_test/config/config_translation_test.content.yml new file mode 100644 index 0000000..e9139f6 --- /dev/null +++ b/core/modules/config_translation/tests/modules/config_translation_test/config/config_translation_test.content.yml @@ -0,0 +1,7 @@ +id: test +label: 'Test' +uuid: 7ae02896-32ae-4875-9a00-f252939fa849 +langcode: en +content: + value: "Hello World" + format: plain_text diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml b/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml new file mode 100644 index 0000000..369db53 --- /dev/null +++ b/core/modules/config_translation/tests/modules/config_translation_test/config/schema/config_translation_test.schema.yml @@ -0,0 +1,9 @@ +# Schema for the configuration files of the Configuration translation test module. + +config_translation_test.content: + type: mapping + label: 'Content' + mapping: + content: + type: text_with_format + label: 'Test element: Text with format' diff --git a/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml b/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml new file mode 100644 index 0000000..86ce7e0 --- /dev/null +++ b/core/modules/config_translation/tests/modules/config_translation_test/config_translation_test.config_translation.yml @@ -0,0 +1,5 @@ +system.file_system_settings: + title: 'Test config translation' + base_route_name: system.file_system_settings + names: + - config_translation_test.content diff --git a/core/modules/system/config/schema/system.data_types.schema.yml b/core/modules/system/config/schema/system.data_types.schema.yml index ab375b6..644e368 100644 --- a/core/modules/system/config/schema/system.data_types.schema.yml +++ b/core/modules/system/config/schema/system.data_types.schema.yml @@ -84,3 +84,16 @@ filter: status: type: boolean label: 'Enabled' + +# Human readable string that is associated with a format. +text_with_format: + type: mapping + label: 'Text with format' + translatable: true + mapping: + value: + type: text + label: 'Content' + fomrat: + type: string + label: 'Text format'