PHP / JavaScript Translations - Quick and Dirty
Sun, 30 October 2016
Translator.php
<?php $translations = array( 'animals' => 'The :speed: :color: :animal: jumped over the lazy :otheranimal:', 'plural' => '{1,1}I like :color:||{2,5}I like :color:\\\\'s' ); class Translator { /** * @var array */ private $strings = array(); /** * @param array $strings */ public function __construct(array $strings) { $this->strings = $strings; } /** * Translate a single key, giving params and a plural number * @param string $key * @param array $params (optional) default array * @param integer $pluralNumber * @return string */ public function _($key, array $params = array(), $pluralNumber = 0) { if (!array_key_exists($key, $this->strings)) { return $key; } // Identify language and fallback here. $single = $this->strings[$key]; $single = $this->getPluralFromNumber($single, $pluralNumber); $keys = array_keys($params); $vals = array_values($params); foreach ($keys as $position => $keyValue) { $keys[$position] = ':' . $keyValue . ':'; } $single = str_replace($keys, $vals, $single); return $single; } /** * Get the string if a plural is identified * @param string $string * @param integer $number * @return string */ private function getPluralFromNumber($string, $number) { // Check if pluralised if (preg_match('/^{[0-9]+,[0-9]+}/', $string)) { $pluralPieces = explode('||', $string); foreach ($pluralPieces as $pluralPiece) { preg_match('/^{[0-9]+,[0-9]+}/', $pluralPiece, $matches); if (!empty($matches)) { $limits = explode(',', $matches[0]); $lower = trim($limits[0]); $upper = trim($limits[1]); if ($lower <= $number && $upper >= $number) { $final = strstr($pluralPiece, '}'); $final = trim($final, '}'); break; } } unset($matches); } } else { $final = $string; } return $final; } }
test_translator.php
<?php include 'Translator.php'; $translator = new Translator($translations); echo $translator->_( 'animals', array( 'speed' => 'quick', 'color' => 'brown', 'animal' => 'fox', 'otheranimal' => 'dog' ) ); echo '<br>' . PHP_EOL; $quantity = 1; echo $translator->_( 'plural', array( 'color' => 'red', ), $quantity ); echo '<br>' . PHP_EOL; echo $translator->_( 'nonexistentkey' );
Translator.phtml
<?php include 'Translator.php'; ?> <!DOCTYPE unspecified PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> </head> <body> <script type="text/javascript"> var translations = <?php echo json_encode($translations); ?>; var Translator = function() { var strings = translations; this._ = function(key, params, number) { // Handle undefined keys if (typeof translations[key] == 'undefined') { return key; } var string = translations[key]; string = getPluralFromNumber(string, number); if (typeof params == 'object') { for (var property in params) { string = string.replace(':' + property + ':', params[property]); } } return string; }; var getPluralFromNumber = function(string, number) { if (typeof number == 'undefined') { return string; } number = parseInt(number); var pattern = new RegExp(/^{[0-9]+,[0-9]+}/); if (pattern.test(string)) { var pluralPieces = string.split('||'); for (var i=0;i<pluralPieces.length;i++) { var pluralPiece = pluralPieces[i]; var matches = pluralPiece.match(/^{[0-9]+,[0-9]+}/); if (matches.length > 0) { var regexLength = matches[0].length; var limits = matches[0].split(','); var lower = parseInt(limits[0].replace('{','')); var upper = parseInt(limits[1].replace('}','')); if (lower <= number && upper >= number) { string = pluralPiece.substring(regexLength); } } } } return string; }; }; var a = new Translator(); console.log(a._('plural', {color:'red'}, 1)); console.log(a._('animals',{speed: 'quick', color: 'brown', animal:'fox', otheranimal:'dog'})); console.log(a._('nonexistentkey')); setTimeout(function(){ window.location = window.location.href; },2000); </script> </body> </html>