Skip to content

Commit

Permalink
Restored context parameter to i18n, and added to a “comment” key
Browse files Browse the repository at this point in the history
Rolled pluralisation functionality into the i18n::_t() method
Warnings on missing default can now be turned off
  • Loading branch information
Damian Mooyman committed Jan 25, 2017
1 parent 8a07c56 commit de02a3f
Show file tree
Hide file tree
Showing 25 changed files with 658 additions and 227 deletions.
4 changes: 2 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,8 @@
"symfony/yaml": "~2.7",
"embed/embed": "^2.6",
"swiftmailer/swiftmailer": "~5.4",
"symfony/config": "^2.8|^3",
"symfony/translation": "^2.8|^3"
"symfony/config": "^2.8|^3",
"symfony/translation": "^2.8|^3"
},
"require-dev": {
"phpunit/PHPUnit": "~4.8",
Expand Down
32 changes: 14 additions & 18 deletions docs/en/02_Developer_Guides/13_i18n/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,12 @@ It can be used to translate strings in both PHP files and template files. The us
elsewhere in your code.
* **$default:** The original language string to be translated. This should be declared
whenever used, and will get picked up the [text collector](#collecting-text).
* **$string:** (optional) Natural language comment (particularly short phrases and individual words)
are very context dependent. This parameter allows the developer to convey this information
to the translator.
* **$injection::** (optional) An array of injecting variables into the second parameter


## Pluralisation

i18n also supports locale-respective pluralisation rules. Many languages have more than two plural forms,
Expand All @@ -182,8 +186,11 @@ unlike English which has two only; One for the singular, and another for any oth
More information on what forms these plurals can take for various locales can be found on the
[CLDR documentation](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html)

The ability to pluralise strings is provided through the `i18n::pluaralise` method, which is similar to the
`i18n::_t` method, other than that it takes an additional `$count` argument.
The ability to pluralise strings is provided through the `i18n::_t` method when supplied with a
`{count}` argument and `|` pipe-delimiter provided with the default string.

Plural forms can also be explicitly declared via the i18nEntityProvider interface in array-format
with both a 'one' and 'other' key (as per the CLDR for the default `en` language).

For instance, this is an example of how to correctly declare pluralisations for an object

Expand Down Expand Up @@ -234,19 +241,11 @@ Please ensure that any required plurals are exposed via provideI18nEntities.
"Restored {value} successfully",
array('value' => $itemRestored)
);

// Plurals are invoked via a `|` pipe-delimeter with a {count} argument
_t('MyObject.PLURALS', 'An object|{count} objects', [ 'count' => '$count ]);


You can invoke plurals for any object using the new `i18n::pluralise` method.
In addition to array form, you can also pass in a pipe-delimited string as a default
argument for brevity.


:::php
public function pluralise($count)
{
return i18n::pluralise('MyObject.PLURALS', 'An object|{count} objects', $count);
}

#### Usage in Template Files

<div class="hint" markdown='1'>
Expand All @@ -267,11 +266,8 @@ the PHP version of the function.
// Using injection to add variables into the translated strings (note that $Name and $Greeting must be available in the current template scope).
<%t Header.Greeting "Hello {name} {greeting}" name=$Name greeting=$Greeting %>

Pluralisation in templates is available via the global `$pluralise` method.


:::ss
You have $pluralise('i18nTestModule.PLURALS', 'An item|{count} items', $Count) in your cart
// Plurals follow the same convention, required a `|` and `{count}` in the default string
<%t MyObject.PLURALS 'An item|{count} items' count=$Count %>


#### Caching in Template Files with locale switching
Expand Down
42 changes: 15 additions & 27 deletions docs/en/04_Changelogs/4.0.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,10 +219,10 @@ Where your code once used SQLQuery you should now use SQLSelect in all cases, as
In many cases, localisation strings which worked in 3.x will continue to work in 4.0, however certain patterns
have been deprecated and will be removed in 5.0. These include:

- _t calls with a $context parameter, which is ignored.
- _t calls with sprintf-style placeholders (`%s`). Replace with named placeholders instead.
- _t calls with non-associative injection arguments. Please use an associative array for all arguments.
- _t calls which do not include a default value.
- _t calls which do not include a default value will now raise a warning. This can be disabled by setting
the `i18n.missing_default_warning` config to false.

Note: If you attempt to use non-associative injection arguments with named placeholders, the result will
now trigger an exception.
Expand All @@ -232,7 +232,7 @@ The non-associative array return type is deprecated. If returning a default stri
other than itself, it should return an array with the `default` and `module` keys respectively.

Full locale-rule respecting localisation for plural forms is now supported. The default
key for an object plural form is `<fqn>.PLURALS`, and follows CLDR array form for each
key for an object plural form is `<Namespaced\ClassName>.PLURALS`, and follows CLDR array form for each
pluralisation. See [the CLDR chart](http://www.unicode.org/cldr/charts/latest/supplemental/language_plural_rules.html)
for reference.

Expand Down Expand Up @@ -285,32 +285,22 @@ In YML format this will be expressed as the below:
DESCRIPTION: 'This is the description for this section'


You can invoke plurals for any object using the new `i18n::pluralise` method.
In addition to array form, you can also pass in a pipe-delimited string as a default
argument for brevity.
Usage of these pluralised strings is through the existing _t() method,
and require a `|` pipe-delimeter with a {count} argument.


:::php
public function pluralise($count)
{
return i18n::pluralise('MyObject.PLURALS', 'An object|{count} objects', $count);
return _t('MyObject.PLURALS', 'An object|{count} objects', [ 'count' => $count ]);
}

In templates this can also be invoked as below:

Which is equivalent to the below:

:::ss
<%t MyObject.PLURALS 'An item|{count} items' count=$Count %>

:::php
public function pluralise($count)
{
return i18n::pluralise('MyObject.PLURALS', [
'one' => 'An object',
'other' => '{count} objects',
], $count);
}


Note: Template syntax for pluralisation is not yet available.

#### New asset storage mechanism

Expand Down Expand Up @@ -1322,20 +1312,18 @@ handle field-level and form-level messages. This has the following properties:

* Upgrade of i18n to symfony/translation
* Localisation based on language-only (without any specific locale) is now supported
* i18nEntityProvider::provideI18nEntities() Now is expected to return only a single array
* `i18nEntityProvider::provideI18nEntities()` Now is expected to return only a single array
map of key to default values.
* i18n keys for '.PLURAL_NAME' and '.SINGULAR_NAME' have been changed back to FQN class names
for all DataObject subclasses.
* i18n keys for '.PLURAL_NAME' and '.SINGULAR_NAME' have been changed back to use the namespaced class names
for all DataObject subclasses, rather than just the basename without namespace.
* i18n key for locale-respective pluralisation rules added as '.PLURALS'. These can be configured
within yaml in array format as per [ruby i18n pluralization rules](http://guides.rubyonrails.org/i18n.html#pluralization).

#### <a name="overview-i18n-removed"></a>i18n API Removed API

* Zend_Translate removed
* i18n::_t $context parameter deprecated
* i18n::_t Support for sprintf-style `%s` arguments deprecated
* i18n::_t Using non-associative injection with named parameters is now an error
* i18nEntityProvider no longer can collect strings for other modules.
* `Zend_Translate` removed
* `i18n::_t` Support for sprintf-style `%s` arguments deprecated
* `i18n::_t` Using non-associative injection with named parameters is now an error

### <a name="overview-mailer"></a>Email and Mailer

Expand Down
8 changes: 4 additions & 4 deletions lang/en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -744,11 +744,11 @@ en:
other: '{count} Permission Role Codes'
SINGULARNAME: 'Permission Role Code'
SilverStripe\Security\RememberLoginHash:
PLURALNAME: 'Remember Login Hashs'
PLURALNAME: 'Login Hashes'
PLURALS:
one: 'A Remember Login Hash'
other: '{count} Remember Login Hashs'
SINGULARNAME: 'Remember Login Hash'
one: 'A Login Hash'
other: '{count} Login Hashes'
SINGULARNAME: 'Login Hash'
SiteTree:
TABMAIN: Main
TableListField:
Expand Down
26 changes: 18 additions & 8 deletions src/Core/Core.php
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,24 @@ function project()
}

/**
* @see i18n::_t()
*
* @param string $entity
* @param string $string
* @param array $injection
* @return string
*/
function _t($entity, $string = "", $injection = [])
* This is the main translator function. Returns the string defined by $entity according to the
* currently set locale.
*
* Also supports pluralisation of strings. Pass in a `count` argument, as well as a
* default value with `|` pipe-delimited options for each plural form.
*
* @param string $entity Entity that identifies the string. It must be in the form
* "Namespace.Entity" where Namespace will be usually the class name where this
* string is used and Entity identifies the string inside the namespace.
* @param mixed $arg,... Additional arguments are parsed as such:
* - Next string argument is a default. Pass in a `|` pipe-delimeted value with `{count}`
* to do pluralisation.
* - Any other string argument after default is context for i18nTextCollector
* - Any array argument in any order is an injection parameter list. Pass in a `count`
* injection parameter to pluralise.
* @return string
*/
function _t($entity, $arg = null)
{
// Pass args directly to handle deprecation
return call_user_func_array([i18n::class, '_t'], func_get_args());
Expand Down
5 changes: 4 additions & 1 deletion src/Security/RememberLoginHash.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@
*/
class RememberLoginHash extends DataObject
{
private static $singular_name = 'Login Hash';

private static $plural_name = 'Login Hashes';

private static $db = array (
'DeviceID' => 'Varchar(40)',
Expand All @@ -29,7 +32,7 @@ class RememberLoginHash extends DataObject
);

private static $has_one = array (
'Member' => 'SilverStripe\\Security\\Member',
'Member' => Member::class,
);

private static $indexes = array(
Expand Down
4 changes: 2 additions & 2 deletions src/i18n/Messages/MessageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ public function translate($entity, $default, $injection);
*
* @param string $entity Identifier for this message in Namespace.key format
* @param array|string $default Default message with pipe-separated delimiters, or array
* @param int $count Number to pluralise against
* @param array $injection List of injection variables
* @param int $count Number to pluralise against
* @return string Localised string
*/
public function pluralise($entity, $default, $count, $injection);
public function pluralise($entity, $default, $injection, $count);
}
21 changes: 2 additions & 19 deletions src/i18n/Messages/Symfony/ModuleYamlLoader.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use SilverStripe\Core\Config\Configurable;
use SilverStripe\Dev\Debug;
use SilverStripe\i18n\i18n;
use SilverStripe\i18n\Messages\Reader;
use Symfony\Component\Translation\Loader\ArrayLoader;
use Symfony\Component\Translation\PluralizationRules;
Expand All @@ -15,24 +16,6 @@
*/
class ModuleYamlLoader extends ArrayLoader
{
use Configurable;

/**
* Map of rails plurals into symfony standard order
*
* @see PluralizationRules For symfony's implementation of this logic
* @config
* @var array
*/
private static $plurals = [
'zero',
'one',
'two',
'few',
'many',
'other',
];

/**
* Message reader
*
Expand Down Expand Up @@ -123,7 +106,7 @@ protected function normaliseMessages($messages, $locale)
protected function normalisePlurals($key, $map, $locale)
{
$parts = [];
foreach ($this->config()->get('plurals') as $form) {
foreach (i18n::config()->get('plurals') as $form) {
if (isset($map[$form])) {
$parts[] = $map[$form];
}
Expand Down
2 changes: 1 addition & 1 deletion src/i18n/Messages/Symfony/SymfonyMessageProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ public function translate($entity, $default, $injection)
return $result;
}

public function pluralise($entity, $default, $count, $injection)
public function pluralise($entity, $default, $injection, $count)
{
if (is_array($default)) {
$default = $this->normalisePlurals($default);
Expand Down
1 change: 1 addition & 0 deletions src/i18n/Messages/YamlReader.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ protected function normaliseMessages($entities)
}
}
}
ksort($messages);
return $messages;
}
}
Loading

0 comments on commit de02a3f

Please sign in to comment.