Update to drupal 8.0.0-rc1. For more information, see https://www.drupal.org/node/2582663

This commit is contained in:
Greg Anderson 2015-10-08 11:40:12 -07:00
parent eb34d130a8
commit f32e58e4b1
8476 changed files with 211648 additions and 170042 deletions

View file

@ -1,7 +1,11 @@
id: locale
module: locale
label: 'Translation'
langcode: en
status: true
dependencies:
module:
- locale
id: locale
label: Translation
module: locale
routes:
- route_name: locale.translate_page
tips:
@ -11,7 +15,6 @@ tips:
label: 'User interface translation'
body: 'This page allows you to translate the user interface or modify existing translations. If you have installed your site initially in English, you must first add another language on the <a href="[site:url]/admin/config/regional/language">Languages page</a>, in order to use this page.'
weight: 1
locale-language:
id: locale-language
plugin: text
@ -20,16 +23,14 @@ tips:
weight: 2
attributes:
data-id: edit-langcode
locale-search:
id: locale-search
plugin: text
label: 'Search'
label: Search
body: 'Enter the specific word or sentence you want to translate, you can also write just a part of a word.'
weight: 3
attributes:
data-id: edit-string
locale-filter:
id: locale-filter
plugin: text
@ -38,7 +39,6 @@ tips:
weight: 4
attributes:
data-id: edit-translation
locale-submit:
id: locale-submit
plugin: text
@ -47,16 +47,14 @@ tips:
weight: 5
attributes:
data-id: edit-submit
locale-translate:
id: locale-translate
plugin: text
label: 'Translate'
label: Translate
body: 'You can write your own translation in the text fields of the right column. Try to figure out in which context the text will be used in order to translate it in the appropriate way.'
weight: 6
attributes:
data-class: js-form-type-textarea
locale-validate:
id: locale-validate
plugin: text
@ -65,13 +63,9 @@ tips:
weight: 7
attributes:
data-id: edit-submit--2
locale-continue:
id: locale-continue
plugin: text
label: 'Continuing on'
body: 'The translations you have made here will be used on your site''s user interface. If you want to use them on another site or modify them on an external translation editor, you can <a href="[site:url]/admin/config/regional/translate/export">export them</a> to a .po file and <a href="[site:url]/admin/config/regional/translate/import">import them</a> later.'
weight: 8
dependencies:
module:
- locale

View file

@ -81,12 +81,6 @@
.expanded .locale-translation-update__wrapper {
background: transparent url(../../../misc/menu-expanded.png) left .6em no-repeat;
}
#locale-translation-status-form .label {
color: #1d1d1d;
font-size: 1.15em;
font-weight: bold;
}
#locale-translation-status-form .description {
cursor: pointer;
}
@ -123,6 +117,14 @@
font-size: 0.9em;
color: #666;
}
.locale-translation-update__details ul {
margin: 0;
padding: 0;
}
.locale-translation-update__details li {
margin: 0 0 0.25em 1.5em;
padding: 0;
}
@media screen and (max-width: 40em) {
#locale-translation-status-form th.title {
width: 20%;

View file

@ -36,7 +36,7 @@
$row.addClass('changed');
// Add an asterisk only once if row changed.
if ($rowToMark.length) {
$rowToMark.find('td:first-child .form-item').append(marker);
$rowToMark.find('td:first-child .js-form-item').append(marker);
}
});
}

View file

@ -99,7 +99,7 @@ function locale_translation_batch_status_finished($success, $results) {
if ($success) {
if (isset($results['failed_files'])) {
if (\Drupal::moduleHandler()->moduleExists('dblog') && \Drupal::currentUser()->hasPermission('access site reports')) {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be checked. <a href="@url">See the log</a> for details.', '@count translation files could not be checked. <a href="@url">See the log</a> for details.', array('@url' => \Drupal::url('dblog.overview')));
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be checked. <a href=":url">See the log</a> for details.', '@count translation files could not be checked. <a href=":url">See the log</a> for details.', array(':url' => \Drupal::url('dblog.overview')));
}
else {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation files could not be checked. See the log for details.', '@count translation files could not be checked. See the log for details.');

View file

@ -220,7 +220,7 @@ function locale_translate_batch_import($file, array $options, array &$context) {
// https://www.drupal.org/node/1089472.
$context['finished'] = min(0.95, $report['seek'] / filesize($file->uri));
if (isset($options['message'])) {
$context['message'] = t('!message (@percent%).', array('!message' => $options['message'], '@percent' => (int) ($context['finished'] * 100)));
$context['message'] = t('@message (@percent%).', array('@message' => $options['message'], '@percent' => (int) ($context['finished'] * 100)));
}
else {
$context['message'] = t('Importing translation file: %filename (@percent%).', array('%filename' => $file->filename, '@percent' => (int) ($context['finished'] * 100)));
@ -367,7 +367,7 @@ function locale_translate_batch_finished($success, array $results) {
$additions = $updates = $deletes = $skips = $config = 0;
if (isset($results['failed_files'])) {
if (\Drupal::moduleHandler()->moduleExists('dblog') && \Drupal::currentUser()->hasPermission('access site reports')) {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be imported. <a href="@url">See the log</a> for details.', '@count translation files could not be imported. <a href="@url">See the log</a> for details.', array('@url' => \Drupal::url('dblog.overview')));
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be imported. <a href=":url">See the log</a> for details.', '@count translation files could not be imported. <a href=":url">See the log</a> for details.', array(':url' => \Drupal::url('dblog.overview')));
}
else {
$message = \Drupal::translation()->formatPlural(count($results['failed_files']), 'One translation file could not be imported. See the log for details.', '@count translation files could not be imported. See the log for details.');
@ -398,7 +398,7 @@ function locale_translate_batch_finished($success, array $results) {
if ($skips) {
if (\Drupal::moduleHandler()->moduleExists('dblog') && \Drupal::currentUser()->hasPermission('access site reports')) {
$message = \Drupal::translation()->formatPlural($skips, 'One translation string was skipped because of disallowed or malformed HTML. <a href="@url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. <a href="@url">See the log</a> for details.', array('@url' => \Drupal::url('dblog.overview')));
$message = \Drupal::translation()->formatPlural($skips, 'One translation string was skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', array(':url' => \Drupal::url('dblog.overview')));
}
else {
$message = \Drupal::translation()->formatPlural($skips, 'One translation string was skipped because of disallowed or malformed HTML. See the log for details.', '@count translation strings were skipped because of disallowed or malformed HTML. See the log for details.');

View file

@ -44,11 +44,6 @@ function locale_translation_flush_projects() {
* - "status": Project status, 1 = enabled.
*/
function locale_translation_build_projects() {
// This function depends on Update module. We degrade gracefully.
if (!\Drupal::moduleHandler()->moduleExists('update')) {
return array();
}
// Get the project list based on .info.yml files.
$projects = locale_translation_project_list();
@ -57,33 +52,18 @@ function locale_translation_build_projects() {
$default_server = locale_translation_default_translation_server();
// If project is a dev release, or core, find the latest available release.
$project_updates = update_get_available(TRUE);
foreach ($projects as $name => $data) {
if (isset($project_updates[$name]['releases']) && $project_updates[$name]['project_status'] != 'not-fetched') {
// Find out if a dev version is installed.
if (preg_match("/^\d+\.x-(\d+)\..*-dev$/", $data['info']['version'], $matches) ||
preg_match("/^(\d+)\.\d+\.\d+.*-dev$/", $data['info']['version'], $matches)) {
// Find a suitable release to use as alternative translation.
foreach ($project_updates[$name]['releases'] as $project_release) {
// The first release with the same major release number which is not a
// dev release is the one. Releases are sorted the most recent first.
// For example the major release number for a contrib module
// 8.x-2.x-dev is "2", for core 8.1.0-dev is "8".
// @todo https://www.drupal.org/node/1774024 Make a helper function.
if ($project_release['version_major'] == $matches[1] &&
(!isset($project_release['version_extra']) || $project_release['version_extra'] != 'dev')) {
$release = $project_release;
break;
}
}
// For dev releases, remove the '-dev' part and trust the translation server
// to fall back to the latest stable release for that branch.
if (isset($data['info']['version']) && strpos($data['info']['version'], '-dev')) {
if (preg_match("/^(\d+\.x-\d+\.).*$/", $data['info']['version'], $matches)) {
// Example matches: 8.x-1.x-dev, 8.x-1.0-alpha1+5-dev => 8.x-1.x
$data['info']['version'] = $matches[1] . 'x';
}
if (!empty($release['version'])) {
$data['info']['version'] = $release['version'];
elseif (preg_match("/^(\d+\.\d+\.).*$/", $data['info']['version'], $matches)) {
// Example match: 8.0.0-dev => 8.0.x (Drupal core)
$data['info']['version'] = $matches[1] . 'x';
}
unset($release);
}
// For every project store information.
@ -96,6 +76,7 @@ function locale_translation_build_projects() {
'server_pattern' => isset($data['info']['interface translation server pattern']) && $data['info']['interface translation server pattern'] ? $data['info']['interface translation server pattern'] : $default_server['pattern'],
'status' => !empty($data['project_status']) ? 1 : 0,
);
$project = (object) $data;
$projects[$name] = $project;
@ -117,8 +98,6 @@ function locale_translation_build_projects() {
function locale_translation_project_list() {
$projects = &drupal_static(__FUNCTION__, array());
if (empty($projects)) {
module_load_include('compare.inc', 'update');
$config = \Drupal::config('locale.settings');
$projects = array();
$additional_whitelist = array(

View file

@ -264,7 +264,7 @@ function locale_requirements($phase) {
'title' => 'Translation update status',
'value' => \Drupal::l(t('Updates available'), new Url('locale.translate_status')),
'severity' => REQUIREMENT_WARNING,
'description' => t('Updates available for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $available_updates), '@updates' => \Drupal::url('locale.translate_status'))),
'description' => t('Updates available for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $available_updates), ':updates' => \Drupal::url('locale.translate_status'))),
);
}
else {
@ -272,7 +272,7 @@ function locale_requirements($phase) {
'title' => 'Translation update status',
'value' => t('Missing translations'),
'severity' => REQUIREMENT_INFO,
'description' => t('Missing translations for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $untranslated), '@updates' => \Drupal::url('locale.translate_status'))),
'description' => t('Missing translations for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', array('@languages' => implode(', ', $untranslated), ':updates' => \Drupal::url('locale.translate_status'))),
);
}
}
@ -289,7 +289,7 @@ function locale_requirements($phase) {
'title' => 'Translation update status',
'value' => \Drupal::l(t('Can not determine status'), new Url('locale.translate_status')),
'severity' => REQUIREMENT_WARNING,
'description' => t('No translation status is available. See the <a href="@updates">Available translation updates</a> page for more information.', array('@updates' => \Drupal::url('locale.translate_status'))),
'description' => t('No translation status is available. See the <a href=":updates">Available translation updates</a> page for more information.', array(':updates' => \Drupal::url('locale.translate_status'))),
);
}
}

View file

@ -1,6 +1,6 @@
locale.translate_page:
title: 'User interface translation'
description: 'Translate the built-in user interface.'
description: 'Configure the import of translation files, and add or customize interface translations.'
route_name: locale.translate_page
parent: system.admin_config_regional
weight: 15

View file

@ -20,7 +20,7 @@ use Drupal\Core\Cache\Cache;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\Language;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\StringTranslation\TranslationWrapper;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\Language\LanguageInterface;
use Drupal\language\ConfigurableLanguageInterface;
use Drupal\Component\Utility\Crypt;
@ -149,28 +149,30 @@ function locale_help($route_name, RouteMatchInterface $route_match) {
case 'help.page.locale':
$output = '';
$output .= '<h3>' . t('About') . '</h3>';
$output .= '<p>' . t('The Interface Translation module allows you to translate interface text (<em>strings</em>) into different languages, and to switch between them for the display of interface text. It uses the functionality provided by the <a href="!language">Language module</a>. For more information, see the <a href="!doc-url">online documentation for the Interface Translation module</a>.', array('!doc-url' => 'https://www.drupal.org/documentation/modules/locale/', '!language' => \Drupal::url('help.page', array('name' => 'language')))) . '</p>';
$output .= '<p>' . t('The Interface Translation module allows you to translate interface text (<em>strings</em>) into different languages, and to switch between them for the display of interface text. It uses the functionality provided by the <a href=":language">Language module</a>. For more information, see the <a href=":doc-url">online documentation for the Interface Translation module</a>.', array(':doc-url' => 'https://www.drupal.org/documentation/modules/locale/', ':language' => \Drupal::url('help.page', array('name' => 'language')))) . '</p>';
$output .= '<h3>' . t('Uses') . '</h3>';
$output .= '<dl>';
$output .= '<dt>' . t('Importing translation files') . '</dt>';
$output .= '<dd>' . t('Translation files with translated interface text are imported automatically when languages are added on the <a href="!languages">Languages</a> page, or when modules or themes are enabled. On the <a href="!locale-settings">Settings</a> page, the <em>Translation source</em> can be restricted to local files only, or to include the <a href="!server">Drupal translation server</a>. Although modules and themes may not be fully translated in all languages, new translations become available frequently. You can specify whether and how often to check for translation file updates and whether to overwrite existing translations on the <a href="!locale-settings">Settings</a> page. You can also manually import a translation file on the <a title="User interface translation import" href="!import">Import</a> page.', array('!import' => \Drupal::url('locale.translate_import'), '!locale-settings' => \Drupal::url('locale.settings'), '!languages' => \Drupal::url('entity.configurable_language.collection'), '!server' => 'https://localize.drupal.org')) . '</dd>';
$output .= '<dd>' . t('Translation files with translated interface text are imported automatically when languages are added on the <a href=":languages">Languages</a> page, or when modules or themes are enabled. On the <a href=":locale-settings">Interface translation settings</a> page, the <em>Translation source</em> can be restricted to local files only, or to include the <a href=":server">Drupal translation server</a>. Although modules and themes may not be fully translated in all languages, new translations become available frequently. You can specify whether and how often to check for translation file updates and whether to overwrite existing translations on the <a href=":locale-settings">Interface translation settings</a> page. You can also manually import a translation file on the <a href=":import">Interface translation import</a> page.', array(':import' => \Drupal::url('locale.translate_import'), ':locale-settings' => \Drupal::url('locale.settings'), ':languages' => \Drupal::url('entity.configurable_language.collection'), ':server' => 'https://localize.drupal.org')) . '</dd>';
$output .= '<dt>' . t('Checking the translation status') . '</dt>';
$output .= '<dd>' . t('You can check how much of the interface on your site is translated into which language on the <a href="!languages">Languages</a> page. On the <a href="!translation-updates">Available translation updates</a> page, you can check whether interface translation updates are available on the <a href="!server">Drupal translation server</a>.', array('!languages' => \Drupal::url('entity.configurable_language.collection'), '!translation-updates' => \Drupal::url('locale.translate_status'), '!server' => 'https://localize.drupal.org')) . '<dd>';
$output .= '<dd>' . t('You can check how much of the interface on your site is translated into which language on the <a href=":languages">Languages</a> page. On the <a href=":translation-updates">Available translation updates</a> page, you can check whether interface translation updates are available on the <a href=":server">Drupal translation server</a>.', array(':languages' => \Drupal::url('entity.configurable_language.collection'), ':translation-updates' => \Drupal::url('locale.translate_status'), ':server' => 'https://localize.drupal.org')) . '<dd>';
$output .= '<dt>' . t('Translating individual strings') . '</dt>';
$output .= '<dd>' . t('You can translate individual strings directly on the <a href="!translate">User interface translation</a> page, or download the currently-used translation file for a specific language on the <a title="User interface translation export" href="!export">Export</a> page. Once you have edited the translation file, you can then import it again on the <a title="User interface translation import" href="!import">Import</a> page.', array('!translate' => \Drupal::url('locale.translate_page'), '!export' => \Drupal::url('locale.translate_export'), '!import' => \Drupal::url('locale.translate_import'))) . '</dd>';
$output .= '<dd>' . t('You can translate individual strings directly on the <a href=":translate">User interface translation</a> page, or download the currently-used translation file for a specific language on the <a href=":export">Interface translation export</a> page. Once you have edited the translation file, you can then import it again on the <a href=":import">Interface translation import</a> page.', array(':translate' => \Drupal::url('locale.translate_page'), ':export' => \Drupal::url('locale.translate_export'), ':import' => \Drupal::url('locale.translate_import'))) . '</dd>';
$output .= '<dt>' . t('Overriding default English strings') . '</dt>';
$output .= '<dd>' . t('If translation is enabled for English, you can <em>override</em> the default English interface text strings in your site with other English text strings on the <a href=":translate">User interface translation</a> page. Translation is off by default for English, but you can turn it on by visiting the <em>Edit language</em> page for <em>English</em> from the <a href=":languages">Languages</a> page.', array(':translate' => \Drupal::url('locale.translate_page'), ':languages' => \Drupal::url('entity.configurable_language.collection'))) . '</dd>';
$output .= '</dl>';
return $output;
case 'entity.configurable_language.collection':
return '<p>' . t('Interface translations are automatically imported when a language is added, or when new modules or themes are enabled. The report <a href="!update">Available translation updates</a> shows the status. Interface text can be customized in the <a href="!translate">user interface translation</a> page.', array('!update' => \Drupal::url('locale.translate_status'), '!translate' => \Drupal::url('locale.translate_page'))) . '</p>';
return '<p>' . t('Interface translations are automatically imported when a language is added, or when new modules or themes are enabled. The report <a href=":update">Available translation updates</a> shows the status. Interface text can be customized in the <a href=":translate">user interface translation</a> page.', array(':update' => \Drupal::url('locale.translate_status'), ':translate' => \Drupal::url('locale.translate_page'))) . '</p>';
case 'locale.translate_page':
$output = '<p>' . t('This page allows a translator to search for specific translated and untranslated strings, and is used when creating or editing translations. (Note: Because translation tasks involve many strings, it may be more convenient to <a title="User interface translation export" href="!export">export</a> strings for offline editing in a desktop Gettext translation editor.) Searches may be limited to strings in a specific language.', array('!export' => \Drupal::url('locale.translate_export'))) . '</p>';
$output = '<p>' . t('This page allows a translator to search for specific translated and untranslated strings, and is used when creating or editing translations. (Note: Because translation tasks involve many strings, it may be more convenient to <a title="User interface translation export" href=":export">export</a> strings for offline editing in a desktop Gettext translation editor.) Searches may be limited to strings in a specific language.', array(':export' => \Drupal::url('locale.translate_export'))) . '</p>';
return $output;
case 'locale.translate_import':
$output = '<p>' . t('Translation files are automatically downloaded and imported when <a title="Languages" href="!language">languages</a> are added, or when modules or themes are enabled.', array('!language' => \Drupal::url('entity.configurable_language.collection'))) . '</p>';
$output .= '<p>' . t('This page allows translators to manually import translated strings contained in a Gettext Portable Object (.po) file. Manual import may be used for customized translations or for the translation of custom modules and themes. To customize translations you can download a translation file from the <a href="!url">Drupal translation server</a> or <a title="User interface translation export" href="!export">export</a> translations from the site, customize the translations using a Gettext translation editor, and import the result using this page.', array('!url' => 'https://localize.drupal.org', '!export' => \Drupal::url('locale.translate_export'))) . '</p>';
$output = '<p>' . t('Translation files are automatically downloaded and imported when <a title="Languages" href=":language">languages</a> are added, or when modules or themes are enabled.', array(':language' => \Drupal::url('entity.configurable_language.collection'))) . '</p>';
$output .= '<p>' . t('This page allows translators to manually import translated strings contained in a Gettext Portable Object (.po) file. Manual import may be used for customized translations or for the translation of custom modules and themes. To customize translations you can download a translation file from the <a href=":url">Drupal translation server</a> or <a title="User interface translation export" href=":export">export</a> translations from the site, customize the translations using a Gettext translation editor, and import the result using this page.', array(':url' => 'https://localize.drupal.org', ':export' => \Drupal::url('locale.translate_export'))) . '</p>';
$output .= '<p>' . t('Note that importing large .po files may take several minutes.') . '</p>';
return $output;
@ -276,8 +278,6 @@ function locale_translatable_language_list() {
function locale_get_plural($count, $langcode = NULL) {
$language_interface = \Drupal::languageManager()->getCurrentLanguage();
// Used to locally cache the plural formulas for all languages.
$plural_formulas = &drupal_static(__FUNCTION__, array());
// Used to store precomputed plural indexes corresponding to numbers
// individually for each language.
$plural_indexes = &drupal_static(__FUNCTION__ . ':plurals', array());
@ -286,18 +286,17 @@ function locale_get_plural($count, $langcode = NULL) {
if (!isset($plural_indexes[$langcode][$count])) {
// Retrieve and statically cache the plural formulas for all languages.
if (empty($plural_formulas)) {
$plural_formulas = \Drupal::state()->get('locale.translation.plurals') ?: array();
}
$plural_formulas = \Drupal::service('locale.plural.formula')->getFormula($langcode);
// If there is a plural formula for the language, evaluate it for the given
// $count and statically cache the result for the combination of language
// and count, since the result will always be identical.
if (!empty($plural_formulas[$langcode])) {
if (!empty($plural_formulas)) {
// Plural formulas are stored as an array for 0-199. 100 is the highest
// modulo used but storing 0-99 is not enough because below 100 we often
// find exceptions (1, 2, etc).
$index = $count > 199 ? 100 + ($count % 100) : $count;
$plural_indexes[$langcode][$count] = isset($plural_formulas[$langcode]['formula'][$index]) ? $plural_formulas[$langcode]['formula'][$index] : $plural_formulas[$langcode]['formula']['default'];
$plural_indexes[$langcode][$count] = isset($plural_formulas[$index]) ? $plural_formulas[$index] : $plural_formulas['default'];
}
// In case there is no plural formula for English (no imported translation
// for English), use a default formula.
@ -641,7 +640,7 @@ function locale_form_language_admin_overview_form_alter(&$form, FormStateInterfa
}
}
array_splice($form['languages']['#header'], -1, 0, t('Interface translation'));
array_splice($form['languages']['#header'], -1, 0, ['translation-interface' => t('Interface translation')]);
foreach ($languages as $langcode => $language) {
$stats[$langcode] += array(
@ -1272,9 +1271,9 @@ function _locale_rebuild_js($langcode = NULL) {
'strings' => $translations,
);
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
if (!empty($locale_plurals[$language->getId()]['formula'])) {
$data['pluralFormula'] = $locale_plurals[$language->getId()]['formula'];
$locale_plurals = \Drupal::service('locale.plural.formula')->getFormula($language->getId());
if ($locale_plurals) {
$data['pluralFormula'] = $locale_plurals;
}
$data = 'window.drupalTranslations = ' . Json::encode($data) . ';';

View file

@ -52,52 +52,9 @@ function locale_translation_manual_status() {
* @see \Drupal\locale\Form\TranslationStatusForm
*/
function template_preprocess_locale_translation_update_info(array &$variables) {
$details = array();
// Build output for available updates.
if (isset($variables['updates'])) {
$releases = array();
if ($variables['updates']) {
foreach ($variables['updates'] as $update) {
$modules[] = $update['name'];
$releases[] = SafeMarkup::format('@module (@date)', array(
'@module' => $update['name'],
'@date' => format_date($update['timestamp'], 'html_date'),
));
}
$variables['modules'] = $modules;
}
$details['available_updates_list'] = array(
'#theme' => 'item_list',
'#items' => $releases,
);
foreach ($variables['updates'] as $update) {
$variables['modules'][] = $update['name'];
}
// Build output for updates not found.
if (isset($variables['not_found'])) {
$releases = array();
$variables['missing_updates_status'] = \Drupal::translation()->formatPlural(count($variables['not_found']), 'Missing translations for one project', 'Missing translations for @count projects');
if ($variables['not_found']) {
foreach ($variables['not_found'] as $update) {
$version = $update['version'] ? $update['version'] : t('no version');
$releases[] = SafeMarkup::format('@module (@version). !info', array(
'@module' => $update['name'],
'@version' => $version,
'!info' => $update['info'],
));
}
}
$details['missing_updates_list'] = array(
'#theme' => 'item_list',
'#items' => $releases,
);
// Prefix the missing updates list if there is an available updates lists
// before it.
if (!empty($details['available_updates_list']['#items'])) {
$details['missing_updates_list']['#prefix'] = t('Missing translations for:');
}
}
$variables['details'] = $details;
}
/**

View file

@ -2,7 +2,7 @@ locale.settings:
path: '/admin/config/regional/translate/settings'
defaults:
_form: 'Drupal\locale\Form\LocaleSettingsForm'
_title: 'Settings'
_title: 'Interface translation settings'
requirements:
_permission: 'translate interface'
@ -25,7 +25,7 @@ locale.translate_import:
path: '/admin/config/regional/translate/import'
defaults:
_form: '\Drupal\locale\Form\ImportForm'
_title: 'Import'
_title: 'Interface translation import'
requirements:
_permission: 'translate interface'
@ -33,7 +33,7 @@ locale.translate_export:
path: '/admin/config/regional/translate/export'
defaults:
_form: '\Drupal\locale\Form\ExportForm'
_title: 'Export'
_title: 'Interface translation export'
requirements:
_permission: 'translate interface'

View file

@ -14,6 +14,9 @@ services:
locale.project:
class: Drupal\locale\LocaleProjectStorage
arguments: ['@keyvalue']
locale.plural.formula:
class: Drupal\locale\PluralFormula
arguments: ['@language_manager', '@state']
string_translator.locale.lookup:
class: Drupal\locale\LocaleTranslation
arguments: ['@locale.storage', '@cache.default', '@lock', '@config.factory', '@language_manager', '@request_stack']

View file

@ -60,7 +60,7 @@ function locale_translation_get_projects(array $project_names = array()) {
$row_count = \Drupal::service('locale.project')->countProjects();
// https://www.drupal.org/node/1777106 is a follow-up issue to make the
// check for possible out-of-date project information more robust.
if ($row_count == 0 && \Drupal::moduleHandler()->moduleExists('update')) {
if ($row_count == 0) {
module_load_include('compare.inc', 'locale');
// At least the core project should be in the database, so we build the
// data if none are found.

View file

@ -94,8 +94,8 @@ class ImportForm extends FormBase {
else {
$default = key($existing_languages);
$language_options = array(
$this->t('Existing languages') => $existing_languages,
$this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
(string) $this->t('Existing languages') => $existing_languages,
(string) $this->t('Languages not yet added') => $this->languageManager->getStandardLanguageListWithoutConfigured(),
);
}

View file

@ -43,14 +43,14 @@ class LocaleSettingsForm extends ConfigFormBase {
'7' => $this->t('Weekly'),
'30' => $this->t('Monthly'),
),
'#description' => $this->t('Select how frequently you want to check for new interface translations for your currently installed modules and themes. <a href="@url">Check updates now</a>.', array('@url' => $this->url('locale.check_translation'))),
'#description' => $this->t('Select how frequently you want to check for new interface translations for your currently installed modules and themes. <a href=":url">Check updates now</a>.', array(':url' => $this->url('locale.check_translation'))),
);
if ($directory = $config->get('translation.path')) {
$description = $this->t('Translation files are stored locally in the %path directory. You can change this directory on the <a href="@url">File system</a> configuration page.', array('%path' => $directory, '@url' => $this->url('system.file_system_settings')));
$description = $this->t('Translation files are stored locally in the %path directory. You can change this directory on the <a href=":url">File system</a> configuration page.', array('%path' => $directory, ':url' => $this->url('system.file_system_settings')));
}
else {
$description = $this->t('Translation files will not be stored locally. Change the Interface translation directory on the <a href="@url">File system configuration</a> page.', array('@url' => $this->url('system.file_system_settings')));
$description = $this->t('Translation files will not be stored locally. Change the Interface translation directory on the <a href=":url">File system configuration</a> page.', array(':url' => $this->url('system.file_system_settings')));
}
$form['#translation_directory'] = $directory;
$form['use_source'] = array(
@ -95,7 +95,7 @@ class LocaleSettingsForm extends ConfigFormBase {
parent::validateForm($form, $form_state);
if (empty($form['#translation_directory']) && $form_state->getValue('use_source') == LOCALE_TRANSLATION_USE_SOURCE_LOCAL) {
$form_state->setErrorByName('use_source', $this->t('You have selected local translation source, but no <a href="@url">Interface translation directory</a> was configured.', array('@url' => $this->url('system.file_system_settings'))));
$form_state->setErrorByName('use_source', $this->t('You have selected local translation source, but no <a href=":url">Interface translation directory</a> was configured.', array(':url' => $this->url('system.file_system_settings'))));
}
}

View file

@ -90,7 +90,6 @@ class TranslationStatusForm extends FormBase {
}
$options[$langcode] = array(
'title' => array(
'class' => array('label'),
'data' => array(
'#title' => $title,
'#plain_text' => $title,
@ -133,16 +132,16 @@ class TranslationStatusForm extends FormBase {
);
if (!$languages) {
$empty = $this->t('No translatable languages available. <a href="@add_language">Add a language</a> first.', array(
'@add_language' => $this->url('entity.configurable_language.collection'),
$empty = $this->t('No translatable languages available. <a href=":add_language">Add a language</a> first.', array(
':add_language' => $this->url('entity.configurable_language.collection'),
));
}
elseif ($status) {
$empty = $this->t('All translations up to date.');
}
else {
$empty = $this->t('No translation status available. <a href="@check">Check manually</a>.', array(
'@check' => $this->url('locale.check_translation'),
$empty = $this->t('No translation status available. <a href=":check">Check manually</a>.', array(
':check' => $this->url('locale.check_translation'),
));
}
@ -233,9 +232,6 @@ class TranslationStatusForm extends FormBase {
* This method will produce debug information including the respective path(s)
* based on this setting.
*
* Translations for development versions are never fetched, so the debug info
* for that is a fixed message.
*
* @param array $project_info
* An array which is the project information of the source.
*
@ -246,9 +242,6 @@ class TranslationStatusForm extends FormBase {
$remote_path = isset($project_info->files['remote']->uri) ? $project_info->files['remote']->uri : FALSE;
$local_path = isset($project_info->files['local']->uri) ? $project_info->files['local']->uri : FALSE;
if (strpos($project_info->version, 'dev') !== FALSE) {
return $this->t('No translation files are provided for development releases.');
}
if (locale_translation_use_remote_source() && $remote_path && $local_path) {
return $this->t('File not found at %remote_path nor at %local_path', array(
'%remote_path' => $remote_path,

View file

@ -12,7 +12,7 @@ use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\InstallStorage;
use Drupal\Core\Config\StorageInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\StringTranslation\TranslationWrapper;
use Drupal\Core\StringTranslation\TranslatableMarkup;
use Drupal\Core\TypedData\TraversableTypedDataInterface;
use Drupal\Core\TypedData\TypedDataInterface;
use Drupal\language\ConfigurableLanguageManagerInterface;
@ -122,13 +122,14 @@ class LocaleConfigManager {
}
/**
* Gets array of translation wrappers for translatable configuration.
* Gets array of translated strings for Locale translatable configuration.
*
* @param string $name
* Configuration object name.
*
* @return array
* Array of translatable elements of the default configuration in $name.
* Array of Locale translatable elements of the default configuration in
* $name.
*/
public function getTranslatableDefaultConfig($name) {
if ($this->isSupported($name)) {
@ -150,11 +151,11 @@ class LocaleConfigManager {
* @param \Drupal\Core\TypedData\TypedDataInterface $element
* Typed configuration element.
*
* @return array|\Drupal\Core\StringTranslation\TranslationWrapper
* @return array|\Drupal\Core\StringTranslation\TranslatableMarkup
* A nested array matching the exact structure under $element with only the
* elements that are translatable wrapped into a TranslationWrapper. If the
* elements that are translatable wrapped into a TranslatableMarkup. If the
* provided $element is not traversable, the return value is a single
* TranslationWrapper.
* TranslatableMarkup.
*/
protected function getTranslatableData(TypedDataInterface $element) {
$translatable = array();
@ -167,13 +168,16 @@ class LocaleConfigManager {
}
}
else {
// Something is only translatable by Locale if there is a string in the
// first place.
$value = $element->getValue();
$definition = $element->getDataDefinition();
if (!empty($definition['translatable'])) {
if (!empty($definition['translatable']) && $value !== '' && $value !== NULL) {
$options = array();
if (isset($definition['translation context'])) {
$options['context'] = $definition['translation context'];
}
return new TranslationWrapper($element->getValue(), array(), $options);
return new TranslatableMarkup($value, array(), $options);
}
}
return $translatable;
@ -191,10 +195,10 @@ class LocaleConfigManager {
* The configuration name.
* @param array $active
* The active configuration data.
* @param array|\Drupal\Core\StringTranslation\TranslationWrapper[] $translatable
* @param array|\Drupal\Core\StringTranslation\TranslatableMarkup[] $translatable
* The translatable array structure. A nested array matching the exact
* structure under of the default configuration for $name with only the
* elements that are translatable wrapped into a TranslationWrapper.
* elements that are translatable wrapped into a TranslatableMarkup.
* @see self::getTranslatableData().
* @param string $langcode
* The language code to process the array with.
@ -559,33 +563,27 @@ class LocaleConfigManager {
foreach ($langcodes as $langcode) {
$processed = $this->processTranslatableData($name, $active, $translatable, $langcode);
// If the language code is not the same as the active storage
// language, we should update the configuration override.
if ($langcode != $active_langcode) {
// If the language code is not the same as the active storage
// language, we should update a configuration override.
$override = $this->languageManager->getLanguageConfigOverride($langcode, $name);
// Filter out locale managed configuration keys so that translations
// removed from Locale will be reflected in the config override.
$data = $this->filterOverride($override->get(), $translatable);
if (!empty($processed)) {
// Update translation data in configuration override.
$this->saveTranslationOverride($name, $langcode, $processed);
// Merge in the Locale managed translations with existing data.
$data = NestedArray::mergeDeepArray(array($data, $processed), TRUE);
}
if (empty($data) && !$override->isNew()) {
// The configuration override contains Locale overrides that no
// longer exist.
$this->deleteTranslationOverride($name, $langcode);
$count++;
}
else {
$override = $this->languageManager->getLanguageConfigOverride($langcode, $name);
if (!$override->isNew()) {
$data = $this->filterOverride($override->get(), $translatable);
if (empty($data)) {
// Delete language override if there is no data left at all.
// This means all prior translations in the override were locale
// managed.
$this->deleteTranslationOverride($name, $langcode);
$count++;
}
else {
// If there were translatable elements besides locale managed
// items, save with only those, and remove the ones managed
// by locale only.
$this->saveTranslationOverride($name, $langcode, $data);
$count++;
}
}
elseif (!empty($data)) {
// Update translation data in configuration override.
$this->saveTranslationOverride($name, $langcode, $data);
$count++;
}
}
elseif (locale_is_translatable($langcode)) {

View file

@ -133,7 +133,7 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
* The configuration name.
* @param array $config
* The active configuration data or override data.
* @param array|\Drupal\Core\StringTranslation\TranslationWrapper[] $translatable
* @param array|\Drupal\Core\StringTranslation\TranslatableMarkup[] $translatable
* The translatable array structure.
* @see \Drupal\locale\LocaleConfigManager::getTranslatableData()
* @param string $langcode
@ -169,9 +169,9 @@ class LocaleConfigSubscriber implements EventSubscriberInterface {
*
* @param string $name
* The configuration name.
* @param array|\Drupal\Core\StringTranslation\TranslationWrapper $translatable
* Either a possibly nested array with TranslationWrapper objects at the
* leaf items or a TranslationWrapper object directly.
* @param array|\Drupal\Core\StringTranslation\TranslatableMarkup $translatable
* Either a possibly nested array with TranslatableMarkup objects at the
* leaf items or a TranslatableMarkup object directly.
* @param array|string $reference_config
* Either a possibly nested array with strings at the leaf items or a string
* directly. Only those $translatable items that are also present in

View file

@ -0,0 +1,116 @@
<?php
/**
* @file
* Contains \Drupal\locale\PluralFormula.
*/
namespace Drupal\locale;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\State\StateInterface;
/**
* Manages the storage of plural formula per language in state.
*
* @see \Drupal\locale\PoDatabaseWriter::setHeader()
*/
class PluralFormula implements PluralFormulaInterface {
/**
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* @var \Drupal\Core\State\StateInterface
*/
protected $state;
/**
* The plural formula and count keyed by langcode.
*
* For example the structure looks like this:
* @code
* [
* 'de' => [
* 'plurals' => 2,
* 'formula' => [
* // @todo
* ]
* ],
* ]
* @endcode
* @var []
*/
protected $formulae;
/**
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* @param \Drupal\Core\State\StateInterface $state
*/
public function __construct(LanguageManagerInterface $language_manager, StateInterface $state) {
$this->languageManager = $language_manager;
$this->state = $state;
}
/**
* {@inheritdoc}
*/
public function setPluralFormula($langcode, $plural_count, array $formula) {
// Ensure that the formulae are loaded.
$this->loadFormulae();
$this->formulae[$langcode] = [
'plurals' => $plural_count,
'formula' => $formula,
];
$this->state->set('locale.translation.formulae', $this->formulae);
return $this;
}
/**
* {@inheritdoc}
*/
public function getNumberOfPlurals($langcode = NULL) {
// Ensure that the formulae are loaded.
$this->loadFormulae();
// Set the langcode to use.
$langcode = $langcode ?: $this->languageManager->getCurrentLanguage()->getId();
// We assume 2 plurals if there is no explicit information yet.
if (!isset($this->formulae[$langcode]['plurals'])) {
return 2;
}
return $this->formulae[$langcode]['plurals'];
}
/**
* {@inheritdoc}
*/
public function getFormula($langcode) {
$this->loadFormulae();
return isset($this->formulae[$langcode]['formula']) ? $this->formulae[$langcode]['formula'] : FALSE;
}
/**
* Loads the formulae and stores them on the PluralFormula object if not set.
*
* @return []
*/
protected function loadFormulae() {
if (!isset($this->formulae)) {
$this->formulae = $this->state->get('locale.translation.formulae', []);
}
}
/**
* {@inheritdoc}
*/
public function reset() {
$this->formulae = NULL;
return $this;
}
}

View file

@ -0,0 +1,59 @@
<?php
/**
* @file
* Contains \Drupal\locale\PluralFormulaInterface.
*/
namespace Drupal\locale;
/**
* An interface for a service providing plural formulae.
*/
interface PluralFormulaInterface {
/**
* @param string $langcode
* The language code to get the formula for.
* @param int $plural_count
* The number of plural forms.
* @param array $formula
* An array of formulae.
*
* @return self
* The PluralFormula object.
*/
public function setPluralFormula($langcode, $plural_count, array $formula);
/**
* Returns the number of plurals supported by a given language.
*
* @param null|string $langcode
* (optional) The language code. If not provided, the current language
* will be used.
*
* @return int
* Number of plural variants supported by the given language.
*/
public function getNumberOfPlurals($langcode = NULL);
/**
* Gets the plural formula for a langcode.
*
* @param string $langcode
* The language code to get the formula for.
*
* @return array
* An array of formulae.
*/
public function getFormula($langcode);
/**
* Resets the static formulae cache.
*
* @return self
* The PluralFormula object.
*/
public function reset();
}

View file

@ -175,11 +175,7 @@ class PoDatabaseWriter implements PoWriterInterface {
$plural = $header->getPluralForms();
if (isset($plural) && $p = $header->parsePluralForms($plural)) {
list($nplurals, $formula) = $p;
$locale_plurals[$langcode] = array(
'plurals' => $nplurals,
'formula' => $formula,
);
\Drupal::state()->set('locale.translation.plurals', $locale_plurals);
\Drupal::service('locale.plural.formula')->setPluralFormula($langcode, $nplurals, $formula);
}
}
}

View file

@ -7,6 +7,7 @@
namespace Drupal\locale\Tests;
use Drupal\locale\Locale;
use Drupal\simpletest\WebTestBase;
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\Core\Url;
@ -23,26 +24,14 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('language', 'update', 'locale_test_translate');
/**
* {@inheritdoc}
*/
protected function setUp() {
parent::setUp();
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'administer permissions'));
$this->drupalLogin($admin_user);
// Update module should not go out to d.o to check for updates. We override
// the url to an invalid update source. No update data will be found.
$this->config('update.settings')->set('fetch.url', (string) Url::fromRoute('<front>')->setAbsolute()->toString())->save();
}
public static $modules = array('language', 'locale_test_translate');
/**
* Test update changes configuration translations if enabled after language.
*/
public function testConfigTranslationImport() {
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'administer permissions'));
$this->drupalLogin($admin_user);
// Add a language. The Afrikaans translation file of locale_test_translate
// (test.af.po) has been prepared with a configuration translation.
@ -81,4 +70,156 @@ class LocaleConfigTranslationImportTest extends WebTestBase {
$this->assertEqual($override->get('message'), 'Ons is tans besig met onderhoud op @site. Wees asseblief geduldig, ons sal binnekort weer terug wees.');
}
/**
* Test update changes configuration translations if enabled after language.
*/
public function testConfigTranslationModuleInstall() {
// Enable locale, block and config_translation modules.
$this->container->get('module_installer')->install(['block', 'config_translation']);
$this->resetAll();
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'administer permissions', 'translate configuration'));
$this->drupalLogin($admin_user);
// Enable import of translations. By default this is disabled for automated
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->save();
// Add predefined language.
$this->drupalPostForm('admin/config/regional/language/add', ['predefined_langcode' => 'af'], t('Add language'));
// Add the system branding block to the page.
$this->drupalPlaceBlock('system_branding_block', array('region' => 'header', 'id' => 'site-branding'));
$this->drupalPostForm('admin/config/system/site-information', ['site_slogan' => 'Test site slogan'], 'Save configuration');
$this->drupalPostForm('admin/config/system/site-information/translate/af/edit', ['translation[config_names][system.site][slogan]' => 'Test site slogan in Afrikaans'], 'Save translation');
// Get the front page and ensure that the translated configuration appears.
$this->drupalGet('af');
$this->assertText('Test site slogan in Afrikaans');
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$this->assertEqual('Locale can translate Afrikaans', $override->get('translatable_default_with_translation'));
// Update test configuration.
$override
->set('translatable_no_default', 'This translation is preserved')
->set('translatable_default_with_translation', 'This translation is preserved')
->set('translatable_default_with_no_translation', 'This translation is preserved')
->save();
// Install any module.
$this->drupalPostForm('admin/modules', ['modules[Core][dblog][enable]' => 'dblog'], t('Install'));
$this->assertText('Module Database Logging has been enabled.');
// Get the front page and ensure that the translated configuration still
// appears.
$this->drupalGet('af');
$this->assertText('Test site slogan in Afrikaans');
$this->rebuildContainer();
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$expected = [
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_translation' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
];
$this->assertEqual($expected, $override->get());
}
/**
* Test removing a string from Locale deletes configuration translations.
*/
function testLocaleRemovalAndConfigOverrideDelete() {
// Enable the locale module.
$this->container->get('module_installer')->install(['locale']);
$this->resetAll();
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'administer permissions', 'translate interface'));
$this->drupalLogin($admin_user);
// Enable import of translations. By default this is disabled for automated
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->save();
// Add predefined language.
$this->drupalPostForm('admin/config/regional/language/add', ['predefined_langcode' => 'af'], t('Add language'));
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$this->assertEqual(['translatable_default_with_translation' => 'Locale can translate Afrikaans'], $override->get());
// Remove the string from translation to simulate a Locale removal. Note
// that is no current way of doing this in the UI.
$locale_storage = \Drupal::service('locale.storage');
$string = $locale_storage->findString(array('source' => 'Locale can translate'));
\Drupal::service('locale.storage')->delete($string);
// Force a rebuild of config translations.
$count = Locale::config()->updateConfigTranslations(['locale_test_translate.settings'], ['af']);
$this->assertEqual($count, 1, 'Correct count of updated translations');
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$this->assertEqual([], $override->get());
$this->assertTrue($override->isNew(), 'The configuration override was deleted when the Locale string was deleted.');
}
/**
* Test removing a string from Locale changes configuration translations.
*/
function testLocaleRemovalAndConfigOverridePreserve() {
// Enable the locale module.
$this->container->get('module_installer')->install(['locale']);
$this->resetAll();
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer site configuration', 'administer languages', 'access administration pages', 'administer permissions', 'translate interface'));
$this->drupalLogin($admin_user);
// Enable import of translations. By default this is disabled for automated
// tests.
$this->config('locale.settings')
->set('translation.import_enabled', TRUE)
->save();
// Add predefined language.
$this->drupalPostForm('admin/config/regional/language/add', ['predefined_langcode' => 'af'], t('Add language'));
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
// Update test configuration.
$override
->set('translatable_no_default', 'This translation is preserved')
->set('translatable_default_with_no_translation', 'This translation is preserved')
->save();
$expected = [
'translatable_default_with_translation' => 'Locale can translate Afrikaans',
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
];
$this->assertEqual($expected, $override->get());
// Set the translated string to empty.
$search = array(
'string' => 'Locale can translate',
'langcode' => 'af',
'translation' => 'all',
);
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$textareas = $this->xpath('//textarea');
$textarea = current($textareas);
$lid = (string) $textarea[0]['name'];
$edit = array(
$lid => '',
);
$this->drupalPostForm('admin/config/regional/translate', $edit, t('Save translations'));
$override = \Drupal::languageManager()->getLanguageConfigOverride('af', 'locale_test_translate.settings');
$expected = [
'translatable_no_default' => 'This translation is preserved',
'translatable_default_with_no_translation' => 'This translation is preserved'
];
$this->assertEqual($expected, $override->get());
}
}

View file

@ -76,8 +76,8 @@ class LocaleImportFunctionalTest extends WebTestBase {
$this->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array('%number' => 8, '%update' => 0, '%delete' => 0)), 'The translation file was successfully imported.');
// This import should have saved plural forms to have 2 variants.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 2, 'Plural number initialized.');
$locale_plurals = \Drupal::service('locale.plural.formula')->getNumberOfPlurals('fr');
$this->assertEqual(2, $locale_plurals, 'Plural number initialized.');
// Ensure we were redirected correctly.
$this->assertUrl(\Drupal::url('locale.translate_page', [], ['absolute' => TRUE]), [], 'Correct page redirection.');
@ -90,7 +90,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
// The import should have created 1 string and rejected 2.
$this->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array('%number' => 1, '%update' => 0, '%delete' => 0)), 'The translation file was successfully imported.');
$skip_message = \Drupal::translation()->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href="@url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. See the log for details.', array('@url' => \Drupal::url('dblog.overview')));
$skip_message = \Drupal::translation()->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. See the log for details.', array(':url' => \Drupal::url('dblog.overview')));
$this->assertRaw($skip_message, 'Unsafe strings were skipped.');
// Repeat the process with a user that can access site reports, and this
@ -102,7 +102,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
'langcode' => 'fr',
));
$skip_message = \Drupal::translation()->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href="@url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. <a href="@url">See the log</a> for details.', array('@url' => \Drupal::url('dblog.overview')));
$skip_message = \Drupal::translation()->formatPlural(2, 'One translation string was skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', '@count translation strings were skipped because of disallowed or malformed HTML. <a href=":url">See the log</a> for details.', array(':url' => \Drupal::url('dblog.overview')));
$this->assertRaw($skip_message, 'Unsafe strings were skipped.');
// Check empty files import with a user that cannot access site reports..
@ -122,7 +122,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
'langcode' => 'fr',
));
// The import should have created 0 string and rejected 0.
$this->assertRaw(t('One translation file could not be imported. <a href="@url">See the log</a> for details.', array('@url' => \Drupal::url('dblog.overview'))), 'The empty translation file import reported no translations imported.');
$this->assertRaw(t('One translation file could not be imported. <a href=":url">See the log</a> for details.', array(':url' => \Drupal::url('dblog.overview'))), 'The empty translation file import reported no translations imported.');
// Try importing a .po file which doesn't exist.
$name = $this->randomMachineName(16);
@ -151,8 +151,8 @@ class LocaleImportFunctionalTest extends WebTestBase {
$this->assertText(t('No strings available.'), 'String not overwritten by imported string.');
// This import should not have changed number of plural forms.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 2, 'Plural numbers untouched.');
$locale_plurals = \Drupal::service('locale.plural.formula')->getNumberOfPlurals('fr');
$this->assertEqual(2, $locale_plurals, 'Plural numbers untouched.');
// Try importing a .po file with overriding strings, and ensure existing
// strings are overwritten.
@ -172,8 +172,8 @@ class LocaleImportFunctionalTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/translate', $search, t('Filter'));
$this->assertNoText(t('No strings available.'), 'String overwritten by imported string.');
// This import should have changed number of plural forms.
$locale_plurals = \Drupal::state()->get('locale.translation.plurals') ?: array();
$this->assert($locale_plurals['fr']['plurals'] == 3, 'Plural numbers changed.');
$locale_plurals = \Drupal::service('locale.plural.formula')->reset()->getNumberOfPlurals('fr');
$this->assertEqual(3, $locale_plurals, 'Plural numbers changed.');
// Importing a .po file and mark its strings as customized strings.
$this->importPoFile($this->getCustomPoFile(), array(
@ -238,8 +238,10 @@ class LocaleImportFunctionalTest extends WebTestBase {
'langcode' => 'hr',
));
$this->assertIdentical(t('May', array(), array('langcode' => 'hr', 'context' => 'Long month name')), 'Svibanj', 'Long month name context is working.');
$this->assertIdentical(t('May', array(), array('langcode' => 'hr')), 'Svi.', 'Default context is working.');
// We cast the return value of t() to string so as to retrieve the
// translated value, rendered as a string.
$this->assertIdentical((string) t('May', array(), array('langcode' => 'hr', 'context' => 'Long month name')), 'Svibanj', 'Long month name context is working.');
$this->assertIdentical((string) t('May', array(), array('langcode' => 'hr')), 'Svi.', 'Default context is working.');
}
/**
@ -254,7 +256,7 @@ class LocaleImportFunctionalTest extends WebTestBase {
));
$this->assertRaw(t('One translation file imported. %number translations were added, %update translations were updated and %delete translations were removed.', array('%number' => 1, '%update' => 0, '%delete' => 0)), 'The translation file was successfully imported.');
$this->assertIdentical(t('Operations', array(), array('langcode' => $langcode)), 'Műveletek', 'String imported and translated.');
$this->assertIdentical((string) t('Operations', array(), array('langcode' => $langcode)), 'Műveletek', 'String imported and translated.');
// Try importing a .po file.
$this->importPoFile($this->getPoFileWithEmptyMsgstr(), array(

View file

@ -23,7 +23,7 @@ class LocaleJavascriptTranslationTest extends WebTestBase {
*
* @var array
*/
public static $modules = array('locale');
public static $modules = array('locale', 'locale_test');
public function testFileParsing() {
$filename = drupal_get_path('module', 'locale') . '/tests/locale_test.js';

View file

@ -7,6 +7,7 @@
namespace Drupal\locale\Tests;
use Drupal\Core\StringTranslation\PluralTranslatableMarkup;
use Drupal\simpletest\WebTestBase;
/**
@ -130,12 +131,15 @@ class LocalePluralFormatTest extends WebTestBase {
// expected index as per the logic for translation lookups.
$expected_plural_index = ($count == 1) ? 0 : $expected_plural_index;
$expected_plural_string = str_replace('@count', $count, $plural_strings[$langcode][$expected_plural_index]);
$this->assertIdentical(\Drupal::translation()->formatPlural($count, '1 hour', '@count hours', array(), array('langcode' => $langcode)), $expected_plural_string, 'Plural translation of 1 hours / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
// DO NOT use translation to pass into formatPluralTranslated() this
// way. It is designed to be used with *already* translated text like
// settings from configuration. We use PHP translation here just because
// we have the expected result data in that format.
$this->assertIdentical(\Drupal::translation()->formatPluralTranslated($count, \Drupal::translation()->translate('1 hour' . LOCALE_PLURAL_DELIMITER . '@count hours', array(), array('langcode' => $langcode)), array(), array('langcode' => $langcode)), $expected_plural_string, 'Translated plural lookup of 1 hours / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
$this->assertIdentical(\Drupal::translation()->formatPlural($count, '1 hour', '@count hours', array(), array('langcode' => $langcode))->render(), $expected_plural_string, 'Plural translation of 1 hours / @count hours for count ' . $count . ' in ' . $langcode . ' is ' . $expected_plural_string);
// DO NOT use translation to pass translated strings into
// PluralTranslatableMarkup::createFromTranslatedString() this way. It
// is designed to be used with *already* translated text like settings
// from configuration. We use PHP translation here just because we have
// the expected result data in that format.
$translated_string = \Drupal::translation()->translate('1 hour' . PluralTranslatableMarkup::DELIMITER . '@count hours', array(), array('langcode' => $langcode));
$plural = PluralTranslatableMarkup::createFromTranslatedString($count, $translated_string, array(), array('langcode' => $langcode));
$this->assertIdentical($plural->render(), $expected_plural_string);
}
}
}
@ -223,7 +227,7 @@ class LocalePluralFormatTest extends WebTestBase {
// langcode here because the language will be English by default and will
// not save our source string for performance optimization if we do not ask
// specifically for a language.
\Drupal::translation()->formatPlural(1, '1 day', '@count days', array(), array('langcode' => 'fr'));
\Drupal::translation()->formatPlural(1, '1 day', '@count days', array(), array('langcode' => 'fr'))->render();
$lid = db_query("SELECT lid FROM {locales_source} WHERE source = :source AND context = ''", array(':source' => "1 day" . LOCALE_PLURAL_DELIMITER . "@count days"))->fetchField();
// Look up editing page for this plural string and check fields.
$search = array(

View file

@ -19,7 +19,7 @@ class LocaleTranslationProjectsTest extends KernelTestBase {
/**
* {@inheritdoc}
*/
public static $modules = ['locale'];
public static $modules = ['locale', 'locale_test'];
/**
* The module handler used in this test.
@ -43,6 +43,7 @@ class LocaleTranslationProjectsTest extends KernelTestBase {
$this->moduleHandler = $this->container->get('module_handler');
$this->projectStorage = $this->container->get('locale.project');
\Drupal::state()->set('locale.remove_core_project', TRUE);
}

View file

@ -64,7 +64,7 @@ class LocaleTranslationUiTest extends WebTestBase {
);
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
// Add string.
t($name, array(), array('langcode' => $langcode));
t($name, array(), array('langcode' => $langcode))->render();
// Reset locale cache.
$this->container->get('string_translation')->reset();
$this->assertRaw('"edit-languages-' . $langcode . '-weight"', 'Language code found.');
@ -237,9 +237,10 @@ class LocaleTranslationUiTest extends WebTestBase {
// Retrieve the source string of the first string available in the
// {locales_source} table and translate it.
$source = db_select('locales_source', 'l')
->fields('l', array('source'))
->condition('l.source', '%.js%', 'LIKE')
$query = db_select('locales_source', 's');
$query->addJoin('INNER', 'locales_location', 'l', 's.lid = l.lid');
$source = $query->fields('s', array('source'))
->condition('l.type', 'javascript')
->range(0, 1)
->execute()
->fetchField();
@ -302,7 +303,7 @@ class LocaleTranslationUiTest extends WebTestBase {
);
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
// Add string.
t($name, array(), array('langcode' => $langcode));
t($name, array(), array('langcode' => $langcode))->render();
// Reset locale cache.
$search = array(
'string' => $name,
@ -361,7 +362,7 @@ class LocaleTranslationUiTest extends WebTestBase {
$this->drupalPostForm('admin/config/regional/language/add', $edit, t('Add custom language'));
// Add string.
t($name, array(), array('langcode' => $langcode));
t($name, array(), array('langcode' => $langcode))->render();
// Reset locale cache.
$this->container->get('string_translation')->reset();
$this->drupalLogout();

View file

@ -50,7 +50,7 @@ abstract class LocaleUpdateBase extends WebTestBase {
*
* @var array
*/
public static $modules = array('update', 'update_test', 'locale', 'locale_test');
public static $modules = array('locale', 'locale_test');
/**
* {@inheritdoc}
@ -58,11 +58,6 @@ abstract class LocaleUpdateBase extends WebTestBase {
protected function setUp() {
parent::setUp();
// Update module should not go out to d.o to check for updates. We override
// the url to the default update_test xml path. But without providing
// a mock xml file, no update data will be found.
$this->config('update.settings')->set('fetch.url', Url::fromRoute('update_test.update_test', [], ['absolute' => TRUE])->toString())->save();
// Setup timestamps to identify old and new translation sources.
$this->timestampOld = REQUEST_TIME - 300;
$this->timestampMedium = REQUEST_TIME - 200;
@ -186,6 +181,7 @@ EOF;
// A flag is set to let the locale_test module replace the project data with
// a set of test projects which match the below project files.
\Drupal::state()->set('locale.test_projects_alter', TRUE);
\Drupal::state()->set('locale.remove_core_project', FALSE);
// Setup the environment.
$public_path = PublicStream::basePath();

View file

@ -0,0 +1,36 @@
<?php
/**
* @file
* Contains \Drupal\locale\Tests\LocaleUpdateDevelopmentReleaseTest.
*/
namespace Drupal\locale\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test for proper version fallback in case of a development release.
*
* @group language
*/
class LocaleUpdateDevelopmentReleaseTest extends WebTestBase {
public static $modules = array('locale', 'locale_test_development_release');
protected function setUp() {
parent::setUp();
module_load_include('compare.inc', 'locale');
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer languages', 'access administration pages', 'translate interface'));
$this->drupalLogin($admin_user);
$this->drupalPostForm('admin/config/regional/language/add', array('predefined_langcode' => 'hu'), t('Add language'));
}
public function testLocaleUpdateDevelopmentRelease() {
$projects = locale_translation_build_projects();
$this->verbose($projects['drupal']->info['version']);
$this->assertEqual($projects['drupal']->info['version'], '8.0.x', 'The branch of the core dev release.');
$this->verbose($projects['contrib']->info['version']);
$this->assertEqual($projects['contrib']->info['version'], '12.x-10.x', 'The branch of the contrib module dev release.');
}
}

View file

@ -7,6 +7,7 @@
namespace Drupal\locale\Tests;
use Drupal\Component\Render\FormattableMarkup;
use Drupal\Component\Utility\SafeMarkup;
/**
@ -45,7 +46,7 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
$this->assertNoText(t('Translation update status'), 'No status message');
$this->drupalGet('admin/reports/translations');
$this->assertRaw(t('No translatable languages available. <a href="@add_language">Add a language</a> first.', array('@add_language' => \Drupal::url('entity.configurable_language.collection'))), 'Language message');
$this->assertRaw(t('No translatable languages available. <a href=":add_language">Add a language</a> first.', array(':add_language' => \Drupal::url('entity.configurable_language.collection'))), 'Language message');
// Add German language.
$this->addLanguage('de');
@ -70,7 +71,7 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
// Check if updates are available for German.
$this->drupalGet('admin/reports/status');
$this->assertText(t('Translation update status'), 'Status message');
$this->assertRaw(t('Updates available for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => t('German'), '@updates' => \Drupal::url('locale.translate_status'))), 'Updates available message');
$this->assertRaw(t('Updates available for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', array('@languages' => t('German'), ':updates' => \Drupal::url('locale.translate_status'))), 'Updates available message');
$this->drupalGet('admin/reports/translations');
$this->assertText(t('Updates for: @modules', array('@modules' => 'Locale test translate')), 'Translations available');
@ -84,11 +85,15 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
// Check if no updates were found.
$this->drupalGet('admin/reports/status');
$this->assertText(t('Translation update status'), 'Status message');
$this->assertRaw(t('Missing translations for: @languages. See the <a href="@updates">Available translation updates</a> page for more information.', array('@languages' => t('German'), '@updates' => \Drupal::url('locale.translate_status'))), 'Missing translations message');
$this->assertRaw(t('Missing translations for: @languages. See the <a href=":updates">Available translation updates</a> page for more information.', array('@languages' => t('German'), ':updates' => \Drupal::url('locale.translate_status'))), 'Missing translations message');
$this->drupalGet('admin/reports/translations');
$this->assertText(t('Missing translations for one project'), 'No translations found');
$this->assertText(SafeMarkup::format('@module (@version). !info', array('@module' => 'Locale test translate', '@version' => '1.3-dev', '!info' => t('No translation files are provided for development releases.'))), 'Release details');
$this->assertText(t('No translation files are provided for development releases.'), 'Release info');
$release_details = new FormattableMarkup('@module (@version). @info', [
'@module' => 'Locale test translate',
'@version' => '1.3-dev',
'@info' => t('File not found at %local_path', array('%local_path' => 'core/modules/locale/tests/test.de.po'))
]);
$this->assertRaw($release_details->__toString(), 'Release details');
// Override Drupal core translation status as 'no translations found'.
$status = locale_translation_get_status();
@ -111,7 +116,7 @@ class LocaleUpdateInterfaceTest extends LocaleUpdateBase {
// Check if translations are available for Drupal core.
$this->drupalGet('admin/reports/translations');
$this->assertText(t('Updates for: !project', array('!project' => t('Drupal core'))), 'Translations found');
$this->assertText(t('Updates for: @project', array('@project' => t('Drupal core'))), 'Translations found');
$this->assertText(SafeMarkup::format('@module (@date)', array('@module' => t('Drupal core'), '@date' => format_date(REQUEST_TIME, 'html_date'))), 'Core translation update');
$update_button = $this->xpath('//input[@type="submit"][@value="' . t('Update translations') . '"]');
$this->assertTrue($update_button, 'Update translations button');

View file

@ -1,83 +0,0 @@
<?php
/**
* @file
* Contains \Drupal\locale\Tests\LocaleUpdateNotDevelopmentReleaseTest.
*/
namespace Drupal\locale\Tests;
use Drupal\simpletest\WebTestBase;
/**
* Test for finding the first available normal core release version,
* in case of core is a development release.
*
* @group language
*/
class LocaleUpdateNotDevelopmentReleaseTest extends WebTestBase {
public static $modules = array('update', 'locale', 'locale_test_not_development_release');
protected function setUp() {
parent::setUp();
module_load_include('compare.inc', 'locale');
$admin_user = $this->drupalCreateUser(array('administer modules', 'administer languages', 'access administration pages', 'translate interface'));
$this->drupalLogin($admin_user);
$this->drupalPostForm('admin/config/regional/language/add', array('predefined_langcode' => 'hu'), t('Add language'));
}
public function testLocaleUpdateNotDevelopmentRelease() {
// Set available Drupal releases for test.
$available = array(
'title' => 'Drupal core',
'short_name' => 'drupal',
'type' => 'project_core',
'api_version' => '8.x',
'project_status' => 'unsupported',
'link' => 'https://www.drupal.org/project/drupal',
'terms' => '',
'releases' => array(
'8.0.0-alpha110' => array(
'name' => 'drupal 8.0.0-alpha110',
'version' => '8.0.0-alpha110',
'tag' => '8.0.0-alpha110',
'version_major' => '8',
'version_minor' => '0',
'version_patch' => '0',
'version_extra' => 'alpha110',
'status' => 'published',
'release_link' => 'https://www.drupal.org/node/2316617',
'download_link' => 'http://ftp.drupal.org/files/projects/drupal-8.0.0-alpha110.tar.gz',
'date' => '1407344628',
'mdhash' => '9d71afdd0ce541f2ff5ca2fbbca00df7',
'filesize' => '9172832',
'files' => '',
'terms' => array(),
),
'8.0.0-alpha100' => array(
'name' => 'drupal 8.0.0-alpha100',
'version' => '8.0.0-alpha100',
'tag' => '8.0.0-alpha100',
'version_major' => '8',
'version_minor' => '0',
'version_patch' => '0',
'version_extra' => 'alpha100',
'status' => 'published',
'release_link' => 'https://www.drupal.org/node/2316617',
'download_link' => 'http://ftp.drupal.org/files/projects/drupal-8.0.0-alpha100.tar.gz',
'date' => '1407344628',
'mdhash' => '9d71afdd0ce541f2ff5ca2fbbca00df7',
'filesize' => '9172832',
'files' => '',
'terms' => array(),
),
),
);
$available['last_fetch'] = REQUEST_TIME;
\Drupal::keyValueExpirable('update_available_releases')->setWithExpire('drupal', $available, 10);
$projects = locale_translation_build_projects();
$this->verbose($projects['drupal']->info['version']);
$this->assertEqual($projects['drupal']->info['version'], '8.0.0-alpha110', 'The first release with the same major release number which is not a development release.');
}
}

View file

@ -20,9 +20,7 @@ class MigrateLocaleConfigsTest extends MigrateDrupal6TestBase {
use SchemaCheckTestTrait;
/**
* Modules to enable.
*
* @var array
* {@inheritdoc}
*/
public static $modules = array('locale', 'language');

View file

@ -6,12 +6,9 @@
* Displays translation status information per language.
*
* Available variables:
* - modules: A list of names of modules that have available translation
* updates.
* - details: Rendered list of the translation details.
* - missing_updates_status: If there are any modules that are missing
* translation updates, this variable will contain text indicating how many
* modules are missing translations.
* - modules: A list of modules names that have available translation updates.
* - updates: A list of available translation updates.
* - not_found: A list of modules missing translation updates.
*
* @see template_preprocess_locale_translation_update_info()
*
@ -23,10 +20,40 @@
{% if modules %}
{% set module_list = modules|safe_join(', ') %}
<span class="locale-translation-update__message">{% trans %}Updates for: {{ module_list }}{% endtrans %}</span>
{% elseif missing_updates_status %}
<span class="locale-translation-update__message">{{ missing_updates_status }}</span>
{% elseif not_found %}
<span class="locale-translation-update__message">
{%- trans -%}
Missing translations for one project
{%- plural not_found|length -%}
Missing translations for @count projects
{%- endtrans -%}
</span>
{% endif %}
{% if details %}
<div class="locale-translation-update__details">{{ details }}</div>
{% if updates or not_found %}
<div class="locale-translation-update__details">
{% if updates %}
<ul>
{% for update in updates %}
<li>{{ update.name }} ({{ update.timestamp|format_date('html_date') }})</li>
{% endfor %}
</ul>
{% endif %}
{% if not_found %}
{#
Prefix the missing updates list if there is an available updates lists
before it.
#}
{% if updates %}
{{ 'Missing translations for:'|t }}
{% endif %}
{% if not_found %}
<ul>
{% for update in not_found %}
<li>{{ update.name }} ({{ update.version|default('no version'|t) }}). {{ update.info }}</li>
{% endfor %}
</ul>
{% endif %}
{% endif %}
</div>
{% endif %}
</div>

View file

@ -45,6 +45,10 @@ function locale_test_locale_translation_projects_alter(&$projects) {
// translation update system will not go out to l.d.o to check.
$projects['drupal']['server_pattern'] = 'translations://';
if (\Drupal::state()->get('locale.remove_core_project')) {
unset($projects['drupal']);
}
if (\Drupal::state()->get('locale.test_projects_alter')) {
// Instead of the default ftp.drupal.org we use the file system of the test

View file

@ -0,0 +1,7 @@
name: 'Locale Test Development Release'
type: module
description: 'Helper module to test the behaviour when the core verison is a development release.'
package: Testing
version: VERSION
core: 8.x
hidden: true

View file

@ -0,0 +1,42 @@
<?php
/**
* @file
* Simulate a Drupal version.
*/
use Drupal\Core\Extension\Extension;
/**
* Implements hook_system_info_alter().
*
* Change the core version number to a development one for testing.
* 8.0.0-alpha102-dev is the simulated version.
*/
function locale_test_development_release_system_info_alter(&$info, Extension $file, $type) {
if (isset($info['package']) && $info['package'] == 'Core') {
$info['version'] = '8.0.0-alpha102-dev';
}
}
/**
* Implements hook_locale_translation_projects_alter().
*
* Add a contrib module with a dev release to list of translatable modules.
*/
function locale_test_development_release_locale_translation_projects_alter(&$projects) {
$projects['contrib'] = [
'name' => 'contrib',
'info' => array(
'name' => 'Contributed module',
'package' => 'Other',
'version' => '12.x-10.4-unstable11+14-dev',
'project' => 'contrib_module',
'datestamp' => '0',
'_info_file_ctime' => 1442933959,
),
'datestamp' => '0',
'project_type' => 'module',
'project_status' => TRUE,
];
}

View file

@ -1,7 +0,0 @@
name: 'Locale Test Not Development Release'
type: module
description: 'The first release with the same major release number which is not a development release.'
package: Testing
version: VERSION
core: 8.x
hidden: true

View file

@ -1,20 +0,0 @@
<?php
/**
* @file
* Simulate a Drupal version.
*/
use Drupal\Core\Extension\Extension;
/**
* Implements hook_system_info_alter().
*
* Change the core version number to a development one for testing.
* 8.0.0-alpha102-dev is the simulated version.
*/
function locale_test_not_development_release_system_info_alter(&$info, Extension $file, $type) {
if (isset($info['package']) && $info['package'] == 'Core') {
$info['version'] = '8.0.0-alpha102-dev';
}
}

View file

@ -0,0 +1,3 @@
translatable_no_default: ''
translatable_default_with_translation: 'Locale can translate'
translatable_default_with_no_translation: 'Locale can not translate'

View file

@ -0,0 +1,10 @@
locale_test_translate.settings:
type: config_object
label: 'Test for locale translations'
mapping:
translatable_no_default:
type: label
translatable_default_with_translation:
type: label
translatable_default_with_no_translation:
type: label

View file

@ -8,3 +8,6 @@ msgstr ""
msgid "@site is currently under maintenance. We should be back shortly. Thank you for your patience."
msgstr "Ons is tans besig met onderhoud op @site. Wees asseblief geduldig, ons sal binnekort weer terug wees."
msgid "Locale can translate"
msgstr "Locale can translate Afrikaans"