mirror of
https://we.phorge.it/source/phorge.git
synced 2024-12-23 22:10:55 +01:00
Update Phabricator to work with more modular translations
Summary: Ref T7152. Ref T1139. This updates Phabricator so third-party libraries can translate their own stuff. Also: - Hide "All Caps" when not in development mode, since some users have found this a little confusing. - With other changes, adds a "Raw Strings" mode (development mode only). - Add an example silly translation to make sure the serious business flag works. - Add a basic British English translation. - Simplify handling of translation overrides. Test Plan: - Flipped serious business / development on and off and saw silly/development translations drop off. - Switched to "All Caps" and saw all caps. - Switched to Very English, Wow! - Switched to British english and saw "colour". Reviewers: btrahan Reviewed By: btrahan Subscribers: epriestley Maniphest Tasks: T7152, T1139 Differential Revision: https://secure.phabricator.com/D11747
This commit is contained in:
parent
187836b8a9
commit
d4680a7e4e
14 changed files with 137 additions and 149 deletions
|
@ -1245,7 +1245,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorActionView' => 'view/layout/PhabricatorActionView.php',
|
||||
'PhabricatorActivitySettingsPanel' => 'applications/settings/panel/PhabricatorActivitySettingsPanel.php',
|
||||
'PhabricatorAdministratorsPolicyRule' => 'applications/policy/rule/PhabricatorAdministratorsPolicyRule.php',
|
||||
'PhabricatorAllCapsTranslation' => 'infrastructure/internationalization/translation/PhabricatorAllCapsTranslation.php',
|
||||
'PhabricatorAlmanacApplication' => 'applications/almanac/application/PhabricatorAlmanacApplication.php',
|
||||
'PhabricatorAmazonAuthProvider' => 'applications/auth/provider/PhabricatorAmazonAuthProvider.php',
|
||||
'PhabricatorAnchorView' => 'view/layout/PhabricatorAnchorView.php',
|
||||
|
@ -1414,7 +1413,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAutoEventListener' => 'infrastructure/events/PhabricatorAutoEventListener.php',
|
||||
'PhabricatorBarePageUIExample' => 'applications/uiexample/examples/PhabricatorBarePageUIExample.php',
|
||||
'PhabricatorBarePageView' => 'view/page/PhabricatorBarePageView.php',
|
||||
'PhabricatorBaseEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBaseEnglishTranslation.php',
|
||||
'PhabricatorBaseProtocolAdapter' => 'infrastructure/daemon/bot/adapter/PhabricatorBaseProtocolAdapter.php',
|
||||
'PhabricatorBaseURISetupCheck' => 'applications/config/check/PhabricatorBaseURISetupCheck.php',
|
||||
'PhabricatorBcryptPasswordHasher' => 'infrastructure/util/password/PhabricatorBcryptPasswordHasher.php',
|
||||
|
@ -1435,6 +1433,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBotTarget' => 'infrastructure/daemon/bot/target/PhabricatorBotTarget.php',
|
||||
'PhabricatorBotUser' => 'infrastructure/daemon/bot/target/PhabricatorBotUser.php',
|
||||
'PhabricatorBotWhatsNewHandler' => 'infrastructure/daemon/bot/handler/PhabricatorBotWhatsNewHandler.php',
|
||||
'PhabricatorBritishEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorBritishEnglishTranslation.php',
|
||||
'PhabricatorBuiltinPatchList' => 'infrastructure/storage/patch/PhabricatorBuiltinPatchList.php',
|
||||
'PhabricatorBusyUIExample' => 'applications/uiexample/examples/PhabricatorBusyUIExample.php',
|
||||
'PhabricatorCacheDAO' => 'applications/cache/storage/PhabricatorCacheDAO.php',
|
||||
|
@ -1717,7 +1716,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEmbedFileRemarkupRule' => 'applications/files/markup/PhabricatorEmbedFileRemarkupRule.php',
|
||||
'PhabricatorEmojiRemarkupRule' => 'applications/macro/markup/PhabricatorEmojiRemarkupRule.php',
|
||||
'PhabricatorEmptyQueryException' => 'infrastructure/query/PhabricatorEmptyQueryException.php',
|
||||
'PhabricatorEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorEnglishTranslation.php',
|
||||
'PhabricatorEnv' => 'infrastructure/env/PhabricatorEnv.php',
|
||||
'PhabricatorEnvTestCase' => 'infrastructure/env/__tests__/PhabricatorEnvTestCase.php',
|
||||
'PhabricatorEvent' => 'infrastructure/events/PhabricatorEvent.php',
|
||||
|
@ -2563,7 +2561,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorTransactions' => 'applications/transactions/constants/PhabricatorTransactions.php',
|
||||
'PhabricatorTransactionsApplication' => 'applications/transactions/application/PhabricatorTransactionsApplication.php',
|
||||
'PhabricatorTransformedFile' => 'applications/files/storage/PhabricatorTransformedFile.php',
|
||||
'PhabricatorTranslation' => 'infrastructure/internationalization/translation/PhabricatorTranslation.php',
|
||||
'PhabricatorTranslationsConfigOptions' => 'applications/config/option/PhabricatorTranslationsConfigOptions.php',
|
||||
'PhabricatorTriggerAction' => 'infrastructure/daemon/workers/action/PhabricatorTriggerAction.php',
|
||||
'PhabricatorTriggerClock' => 'infrastructure/daemon/workers/clock/PhabricatorTriggerClock.php',
|
||||
|
@ -2587,6 +2584,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUIExample' => 'applications/uiexample/examples/PhabricatorUIExample.php',
|
||||
'PhabricatorUIExampleRenderController' => 'applications/uiexample/controller/PhabricatorUIExampleRenderController.php',
|
||||
'PhabricatorUIExamplesApplication' => 'applications/uiexample/application/PhabricatorUIExamplesApplication.php',
|
||||
'PhabricatorUSEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorUSEnglishTranslation.php',
|
||||
'PhabricatorUnitsTestCase' => 'view/__tests__/PhabricatorUnitsTestCase.php',
|
||||
'PhabricatorUnsubscribedFromObjectEdgeType' => 'applications/transactions/edges/PhabricatorUnsubscribedFromObjectEdgeType.php',
|
||||
'PhabricatorUser' => 'applications/people/storage/PhabricatorUser.php',
|
||||
|
@ -2618,6 +2616,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUserTransaction' => 'applications/people/storage/PhabricatorUserTransaction.php',
|
||||
'PhabricatorUsersPolicyRule' => 'applications/policy/rule/PhabricatorUsersPolicyRule.php',
|
||||
'PhabricatorVCSResponse' => 'applications/repository/response/PhabricatorVCSResponse.php',
|
||||
'PhabricatorVeryWowEnglishTranslation' => 'infrastructure/internationalization/translation/PhabricatorVeryWowEnglishTranslation.php',
|
||||
'PhabricatorWatcherHasObjectEdgeType' => 'applications/transactions/edges/PhabricatorWatcherHasObjectEdgeType.php',
|
||||
'PhabricatorWordPressAuthProvider' => 'applications/auth/provider/PhabricatorWordPressAuthProvider.php',
|
||||
'PhabricatorWorker' => 'infrastructure/daemon/workers/PhabricatorWorker.php',
|
||||
|
@ -4472,7 +4471,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorActionView' => 'AphrontView',
|
||||
'PhabricatorActivitySettingsPanel' => 'PhabricatorSettingsPanel',
|
||||
'PhabricatorAdministratorsPolicyRule' => 'PhabricatorPolicyRule',
|
||||
'PhabricatorAllCapsTranslation' => 'PhabricatorTranslation',
|
||||
'PhabricatorAlmanacApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorAmazonAuthProvider' => 'PhabricatorOAuth2AuthProvider',
|
||||
'PhabricatorAnchorView' => 'AphrontView',
|
||||
|
@ -4658,7 +4656,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorAutoEventListener' => 'PhabricatorEventListener',
|
||||
'PhabricatorBarePageUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorBarePageView' => 'AphrontPageView',
|
||||
'PhabricatorBaseEnglishTranslation' => 'PhabricatorTranslation',
|
||||
'PhabricatorBaseURISetupCheck' => 'PhabricatorSetupCheck',
|
||||
'PhabricatorBcryptPasswordHasher' => 'PhabricatorPasswordHasher',
|
||||
'PhabricatorBinariesSetupCheck' => 'PhabricatorSetupCheck',
|
||||
|
@ -4675,6 +4672,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorBotSymbolHandler' => 'PhabricatorBotHandler',
|
||||
'PhabricatorBotUser' => 'PhabricatorBotTarget',
|
||||
'PhabricatorBotWhatsNewHandler' => 'PhabricatorBotHandler',
|
||||
'PhabricatorBritishEnglishTranslation' => 'PhutilTranslation',
|
||||
'PhabricatorBuiltinPatchList' => 'PhabricatorSQLPatchList',
|
||||
'PhabricatorBusyUIExample' => 'PhabricatorUIExample',
|
||||
'PhabricatorCacheDAO' => 'PhabricatorLiskDAO',
|
||||
|
@ -4986,7 +4984,6 @@ phutil_register_library_map(array(
|
|||
'PhabricatorEmbedFileRemarkupRule' => 'PhabricatorObjectRemarkupRule',
|
||||
'PhabricatorEmojiRemarkupRule' => 'PhutilRemarkupRule',
|
||||
'PhabricatorEmptyQueryException' => 'Exception',
|
||||
'PhabricatorEnglishTranslation' => 'PhabricatorBaseEnglishTranslation',
|
||||
'PhabricatorEnvTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorEvent' => 'PhutilEvent',
|
||||
'PhabricatorEventListener' => 'PhutilEventListener',
|
||||
|
@ -5910,6 +5907,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUIConfigOptions' => 'PhabricatorApplicationConfigOptions',
|
||||
'PhabricatorUIExampleRenderController' => 'PhabricatorController',
|
||||
'PhabricatorUIExamplesApplication' => 'PhabricatorApplication',
|
||||
'PhabricatorUSEnglishTranslation' => 'PhutilTranslation',
|
||||
'PhabricatorUnitsTestCase' => 'PhabricatorTestCase',
|
||||
'PhabricatorUnsubscribedFromObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorUser' => array(
|
||||
|
@ -5954,6 +5952,7 @@ phutil_register_library_map(array(
|
|||
'PhabricatorUserTransaction' => 'PhabricatorApplicationTransaction',
|
||||
'PhabricatorUsersPolicyRule' => 'PhabricatorPolicyRule',
|
||||
'PhabricatorVCSResponse' => 'AphrontResponse',
|
||||
'PhabricatorVeryWowEnglishTranslation' => 'PhutilTranslation',
|
||||
'PhabricatorWatcherHasObjectEdgeType' => 'PhabricatorEdgeType',
|
||||
'PhabricatorWordPressAuthProvider' => 'PhabricatorOAuth2AuthProvider',
|
||||
'PhabricatorWorkerActiveTask' => 'PhabricatorWorkerTask',
|
||||
|
|
|
@ -96,13 +96,9 @@ abstract class PhabricatorController extends AphrontController {
|
|||
$request->setUser($user);
|
||||
}
|
||||
|
||||
$translation = $user->getTranslation();
|
||||
if ($translation &&
|
||||
$translation != PhabricatorEnv::getEnvConfig('translation.provider')) {
|
||||
$translation = newv($translation, array());
|
||||
PhutilTranslator::getInstance()
|
||||
->setLanguage($translation->getLanguage())
|
||||
->addTranslations($translation->getCleanTranslations());
|
||||
$locale_code = $user->getTranslation();
|
||||
if ($locale_code) {
|
||||
PhabricatorEnv::setLocaleCode($locale_code);
|
||||
}
|
||||
|
||||
$preferences = $user->loadPreferences();
|
||||
|
|
|
@ -203,6 +203,9 @@ final class PhabricatorExtraConfigSetupCheck extends PhabricatorSetupCheck {
|
|||
'the server as the user you want it to run under.'),
|
||||
'notification.debug' => pht(
|
||||
'Notifications no longer have a dedicated debugging mode.'),
|
||||
'translation.provider' => pht(
|
||||
'The translation implementation has changed and providers are no '.
|
||||
'longer used or supported.'),
|
||||
);
|
||||
|
||||
return $ancient_config;
|
||||
|
|
|
@ -21,19 +21,6 @@ final class PhabricatorTranslationsConfigOptions
|
|||
|
||||
public function getOptions() {
|
||||
return array(
|
||||
$this->newOption(
|
||||
'translation.provider',
|
||||
'class',
|
||||
'PhabricatorEnglishTranslation')
|
||||
->setBaseClass('PhabricatorTranslation')
|
||||
->setSummary(pht('Translation class that should be used for strings.'))
|
||||
->setDescription(
|
||||
pht(
|
||||
'This allows customizing texts used in Phabricator. The class '.
|
||||
'must extend PhabricatorTranslation.'))
|
||||
->addExample('PhabricatorEnglishTranslation', pht('Valid Setting')),
|
||||
// TODO: This should be dict<string,string> I think, but that doesn't
|
||||
// exist yet.
|
||||
$this->newOption('translation.override', 'wild', array())
|
||||
->setSummary(pht('Override translations.'))
|
||||
->setDescription(
|
||||
|
|
|
@ -190,19 +190,6 @@ final class PhabricatorUser
|
|||
return '@'.$this->getUsername();
|
||||
}
|
||||
|
||||
public function getTranslation() {
|
||||
try {
|
||||
if ($this->translation &&
|
||||
class_exists($this->translation) &&
|
||||
is_subclass_of($this->translation, 'PhabricatorTranslation')) {
|
||||
return $this->translation;
|
||||
}
|
||||
} catch (PhutilMissingSymbolException $ex) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isLoggedIn() {
|
||||
return !($this->getPHID() === null);
|
||||
}
|
||||
|
|
|
@ -64,20 +64,28 @@ final class PhabricatorAccountSettingsPanel extends PhabricatorSettingsPanel {
|
|||
PhutilPerson::SEX_FEMALE => $label_her,
|
||||
);
|
||||
|
||||
$locales = PhutilLocale::loadAllLocales();
|
||||
$is_serious = PhabricatorEnv::getEnvConfig('phabricator.serious-business');
|
||||
$is_dev = PhabricatorEnv::getEnvConfig('phabricator.developer-mode');
|
||||
|
||||
$translations = array();
|
||||
$symbols = id(new PhutilSymbolLoader())
|
||||
->setType('class')
|
||||
->setAncestorClass('PhabricatorTranslation')
|
||||
->setConcreteOnly(true)
|
||||
->selectAndLoadSymbols();
|
||||
foreach ($symbols as $symbol) {
|
||||
$class = $symbol['name'];
|
||||
$translations[$class] = newv($class, array())->getName();
|
||||
foreach ($locales as $locale) {
|
||||
if ($is_serious && $locale->isSillyLocale()) {
|
||||
// Omit silly locales on serious business installs.
|
||||
continue;
|
||||
}
|
||||
if (!$is_dev && $locale->isTestLocale()) {
|
||||
// Omit test locales on installs which aren't in development mode.
|
||||
continue;
|
||||
}
|
||||
$translations[$locale->getLocaleCode()] = $locale->getLocaleName();
|
||||
}
|
||||
|
||||
asort($translations);
|
||||
$default = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||
// TODO: Implement "locale.default" and use it here.
|
||||
$default = 'en_US';
|
||||
$translations = array(
|
||||
'' => pht('Server Default (%s)', $default->getName()),
|
||||
'' => pht('Server Default: %s', $locales[$default]->getLocaleName()),
|
||||
) + $translations;
|
||||
|
||||
$form = new AphrontFormView();
|
||||
|
|
|
@ -1,33 +1,33 @@
|
|||
@title Internationalization
|
||||
@group developer
|
||||
|
||||
What is required from developers to get Phabricator translatable.
|
||||
Describes Phabricator translation and localization.
|
||||
|
||||
= API =
|
||||
Overview
|
||||
========
|
||||
|
||||
Translator API is provided by libphutil. It gives us
|
||||
@{class@libphutil:PhutilTranslator} class and global @{function@libphutil:pht}
|
||||
function built on top of it.
|
||||
Phabricator partially supports internationalization, but many of the tools
|
||||
are missing or in a prototype state.
|
||||
|
||||
Developers are supposed to call @{function@libphutil:pht} on all strings that
|
||||
require translation.
|
||||
This document very briefly summarizes some of what exists today.
|
||||
|
||||
Phabricator provides translations for this translator through
|
||||
@{class:PhabricatorTranslation} class.
|
||||
Writing Translatable Code
|
||||
========
|
||||
|
||||
= Adding a New Translation =
|
||||
Strings are marked for translation with @{function@libphutil:pht}.
|
||||
|
||||
Adding a translation which uses the same language rules as some already existing
|
||||
translation is relatively simple: Just extend @{class:PhabricatorTranslation}
|
||||
and you will be able to specify this class in the global configuration
|
||||
'translation.provider' and users will be able to select it in their preferences.
|
||||
Adding a New Locale
|
||||
=========
|
||||
|
||||
= Adding a New Language =
|
||||
To add a new locale, subclass @{class:PhutilLocale}.
|
||||
|
||||
Adding a language involves all steps as adding a translation plus specifying the
|
||||
language rules in @{method@libphutil:PhutilTranslator::chooseVariant}.
|
||||
Translating Strings
|
||||
========
|
||||
|
||||
= Singular and Plural =
|
||||
To translate strings, subclass @{class:PhutilTranslation}.
|
||||
|
||||
Singular and Plural
|
||||
========
|
||||
|
||||
Different languages have various rules for using singular and plural. All you
|
||||
need to do is to call @{function@libphutil:pht} with a text that is suitable for
|
||||
|
@ -46,7 +46,8 @@ Translators will translate this text for all different forms the language uses:
|
|||
The ugly identifier passed to @{function@libphutil:pht} will remain in the text
|
||||
only if the translation doesn't exist.
|
||||
|
||||
= Male and Female =
|
||||
Male and Female
|
||||
========
|
||||
|
||||
Different languages use different words for talking about males, females and
|
||||
unknown genders. Callsites have to call @{function@libphutil:pht} passing
|
||||
|
|
33
src/infrastructure/env/PhabricatorEnv.php
vendored
33
src/infrastructure/env/PhabricatorEnv.php
vendored
|
@ -55,6 +55,7 @@ final class PhabricatorEnv {
|
|||
private static $overrideSource;
|
||||
private static $requestBaseURI;
|
||||
private static $cache;
|
||||
private static $localeCode;
|
||||
|
||||
/**
|
||||
* @phutil-external-symbol class PhabricatorStartup
|
||||
|
@ -123,10 +124,34 @@ final class PhabricatorEnv {
|
|||
|
||||
PhabricatorEventEngine::initialize();
|
||||
|
||||
$translation = PhabricatorEnv::newObjectFromConfig('translation.provider');
|
||||
PhutilTranslator::getInstance()
|
||||
->setLanguage($translation->getLanguage())
|
||||
->addTranslations($translation->getCleanTranslations());
|
||||
// TODO: Add a "locale.default" config option once we have some reasonable
|
||||
// defaults which aren't silly nonsense.
|
||||
self::setLocaleCode('en_US');
|
||||
}
|
||||
|
||||
public static function setLocaleCode($locale_code) {
|
||||
if ($locale_code == self::$localeCode) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
$locale = PhutilLocale::loadLocale($locale_code);
|
||||
$translations = PhutilTranslation::getTranslationMapForLocale(
|
||||
$locale_code);
|
||||
|
||||
$override = PhabricatorEnv::getEnvConfig('translation.override');
|
||||
if (!is_array($override)) {
|
||||
$override = array();
|
||||
}
|
||||
|
||||
PhutilTranslator::getInstance()
|
||||
->setLocale($locale)
|
||||
->setTranslations($override + $translations);
|
||||
|
||||
self::$localeCode = $locale_code;
|
||||
} catch (Exception $ex) {
|
||||
// Just ignore this; the user likely has an out-of-date locale code.
|
||||
}
|
||||
}
|
||||
|
||||
private static function buildConfigurationSourceStack() {
|
||||
|
|
|
@ -1,18 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorAllCapsTranslation
|
||||
extends PhabricatorTranslation {
|
||||
|
||||
final public function getLanguage() {
|
||||
return 'en-ac';
|
||||
}
|
||||
|
||||
public function getName() {
|
||||
return 'All Caps';
|
||||
}
|
||||
|
||||
public function getTranslations() {
|
||||
return array();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,31 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorBritishEnglishTranslation
|
||||
extends PhutilTranslation {
|
||||
|
||||
public function getLocaleCode() {
|
||||
return 'en_GB';
|
||||
}
|
||||
|
||||
protected function getTranslations() {
|
||||
return array(
|
||||
'%s set this project\'s color to %s.' =>
|
||||
'%s set this project\'s colour to %s.',
|
||||
'Basic Colors' =>
|
||||
'Basic Colours',
|
||||
'Choose Icon and Color...' =>
|
||||
'Choose Icon and Colour...',
|
||||
'Choose Background Color' =>
|
||||
'Choose Background Colour',
|
||||
'Color' => 'Colour',
|
||||
'Colors' => 'Colours',
|
||||
'Colors and Transforms' => 'Colours and Transforms',
|
||||
'Configure the Phabricator UI, including colors.' =>
|
||||
'Configure the Phabricator UI, including colours.',
|
||||
'Flag Color' => 'Flag Colour',
|
||||
'Sets the color of the main header.' =>
|
||||
'Sets the colour of the main header.',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,16 +0,0 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorEnglishTranslation
|
||||
extends PhabricatorBaseEnglishTranslation {
|
||||
|
||||
public function getName() {
|
||||
return 'English';
|
||||
}
|
||||
|
||||
public function getTranslations() {
|
||||
return
|
||||
PhabricatorEnv::getEnvConfig('translation.override') +
|
||||
parent::getTranslations();
|
||||
}
|
||||
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorTranslation {
|
||||
|
||||
abstract public function getLanguage();
|
||||
abstract public function getName();
|
||||
abstract public function getTranslations();
|
||||
|
||||
|
||||
/**
|
||||
* Return the cleaned translation array.
|
||||
*
|
||||
* @return dict<string, wild> Translation map with empty translations removed.
|
||||
*/
|
||||
public function getCleanTranslations() {
|
||||
return $this->clean($this->getTranslations());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Removes NULL-valued translation keys from the translation map, to prevent
|
||||
* echoing out empty strings.
|
||||
*
|
||||
* @param dict<string, wild> Translation map, with empty translations.
|
||||
* @return dict<string, wild> Map with empty translations removed.
|
||||
*/
|
||||
protected function clean(array $translation_array) {
|
||||
foreach ($translation_array as $key => $translation_string) {
|
||||
if ($translation_string === null) {
|
||||
unset($translation_array[$key]);
|
||||
}
|
||||
}
|
||||
|
||||
return $translation_array;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,13 +1,13 @@
|
|||
<?php
|
||||
|
||||
abstract class PhabricatorBaseEnglishTranslation
|
||||
extends PhabricatorTranslation {
|
||||
final class PhabricatorUSEnglishTranslation
|
||||
extends PhutilTranslation {
|
||||
|
||||
final public function getLanguage() {
|
||||
return 'en';
|
||||
public function getLocaleCode() {
|
||||
return 'en_US';
|
||||
}
|
||||
|
||||
public function getTranslations() {
|
||||
protected function getTranslations() {
|
||||
return array(
|
||||
'No daemon(s) with id(s) "%s" exist!' => array(
|
||||
'No daemon with id %s exists!',
|
|
@ -0,0 +1,22 @@
|
|||
<?php
|
||||
|
||||
final class PhabricatorVeryWowEnglishTranslation
|
||||
extends PhutilTranslation {
|
||||
|
||||
public function getLocaleCode() {
|
||||
return 'en_W*';
|
||||
}
|
||||
|
||||
protected function getTranslations() {
|
||||
return array(
|
||||
'Search' => 'Search! Wow!',
|
||||
'Review Code' => 'Wow! Code Review! Wow!',
|
||||
'Tasks and Bugs' => 'Much Bug! Very Bad!',
|
||||
'Cancel' => 'Nope!',
|
||||
'Advanced Search' => 'Much Search!',
|
||||
'No search results.' => 'No results! Wow!',
|
||||
'Send Message' => 'Bark! Bark Bark!',
|
||||
);
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue