Skip to content

Commit 4f678fe

Browse files
committed
Switch to gettext/gettext w/domain-support
1 parent e464c39 commit 4f678fe

4 files changed

Lines changed: 103 additions & 23 deletions

File tree

composer.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@
3131
"robrichards/xmlseclibs": "~2.0",
3232
"whitehat101/apr1-md5": "~1.0",
3333
"twig/twig": "~1.0",
34-
"twig/extensions": "^1.3",
3534
"gettext/gettext": "^3.5"
3635
},
3736
"require-dev": {

lib/SimpleSAML/Locale/Localization.php

Lines changed: 88 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@
99

1010
namespace SimpleSAML\Locale;
1111

12+
use Gettext\Translations;
13+
use Gettext\Translator;
14+
1215
class Localization
1316
{
1417

@@ -22,13 +25,24 @@ class Localization
2225
/**
2326
* The default gettext domain.
2427
*/
25-
private $domain = 'ssp';
28+
const DEFAULT_DOMAIN = 'ssp';
29+
30+
/**
31+
* Default 1i18n backend
32+
*/
33+
const DEFAULT_I18NBACKEND = 'twig.gettextgettext';
2634

2735
/*
28-
* The locale directory
36+
* The default locale directory
2937
*/
3038
private $localeDir;
3139

40+
/*
41+
* Where specific domains are stored
42+
*/
43+
private $localeDomainMap = array();
44+
45+
3246
/**
3347
* Constructor
3448
*
@@ -39,40 +53,95 @@ public function __construct(\SimpleSAML_Configuration $configuration)
3953
$this->configuration = $configuration;
4054
$this->localeDir = $this->configuration->resolvePath('locales');
4155
$this->language = new Language($configuration);
56+
$this->langcode = $this->language->getPosixLanguage($this->language->getLanguage());
4257
$this->i18nBackend = $this->configuration->getString('language.i18n.backend', null);
4358
$this->setupL10N();
4459
}
4560

61+
/*
62+
* Add a new translation domain
63+
* (We're assuming that each domain only exists in one place)
64+
*
65+
* @param string $localeDir Location of translations
66+
* @param string $domain Domain at location
67+
*/
68+
private function addDomain($localeDir, $domain)
69+
{
70+
$this->localeDomainMap[$domain] = $localeDir;
71+
}
72+
73+
74+
/**
75+
* Load translation domain from Gettext/Gettext using .po
76+
*
77+
* @param string $domain Name of domain
78+
*/
79+
private function loadGettextGettextFromPO($domain = self::DEFAULT_DOMAIN) {
80+
$langcode = explode('_', $this->langcode)[0];
81+
$localeDir = $this->localeDomainMap[$domain];
82+
$poPath = $localeDir.'/'.$langcode.'/LC_MESSAGES/'.$domain.'.po';
83+
$translations = Translations::fromPoFile($poPath);
84+
$t = new Translator();
85+
$t->loadTranslations($translations);
86+
$t->register();
87+
}
88+
89+
90+
/**
91+
* Test to check if backend is set to default
92+
*
93+
* (if false: backend unset/there's an error)
94+
*/
95+
public function isI18NBackendDefault()
96+
{
97+
if ($this->i18nBackend === $this::DEFAULT_I18NBACKEND) {
98+
return true;
99+
}
100+
return false;
101+
}
102+
103+
104+
/**
105+
* Set up L18N if configured or fallback to old system
106+
*/
46107
private function setupL10N() {
47108
// use old system
48-
if (is_null($this->i18nBackend)) {
109+
if (! $this->isI18NBackendDefault()) {
110+
\SimpleSAML\Logger::debug("Localization: using old system");
49111
return;
50112
}
51-
$encoding = "UTF-8";
52-
$langcode = $this->language->getPosixLanguage($this->language->getLanguage());
53-
// use gettext and Twig.I18n
54-
if ($this->i18nBackend == 'twig.i18n') {
55-
putenv('LC_ALL='.$langcode);
56-
setlocale(LC_ALL, $langcode);
57-
bindtextdomain($this->domain, $this->localeDir);
58-
bind_textdomain_codeset($this->domain, $encoding);
59-
}
113+
// setup default domain
114+
$this->addDomain($this->localeDir, self::DEFAULT_DOMAIN);
115+
$this->activateDomain(self::DEFAULT_DOMAIN);
60116
}
61117

62118

119+
/**
120+
* Set which translation domain to use
121+
*
122+
* @param string $domain Name of domain
123+
*/
63124
public function activateDomain($domain)
64125
{
65-
if ($this->i18nBackend == 'twig.i18n') {
66-
textdomain($domain);
67-
}
126+
\SimpleSAML\Logger::debug("Localization: activate domain");
127+
$this->loadGettextGettextFromPO($domain);
128+
$this->currentDomain = $domain;
68129
}
69130

131+
/**
132+
* Get current translation domain
133+
*/
134+
public function getCurrentDomain()
135+
{
136+
return $this->currentDomain ? $this->currentDomain : self::DEFAULT_DOMAIN;
137+
}
70138

139+
/**
140+
* Go back to default translation domain
141+
*/
71142
public function restoreDefaultDomain()
72143
{
73-
if ($this->i18nBackend == 'twig.i18n') {
74-
textdomain($this->domain);
75-
}
144+
$this->loadGettextGettextFromPO(self::DEFAULT_DOMAIN);
145+
$this->currentDomain = self::DEFAULT_DOMAIN;
76146
}
77147
}
78-

lib/SimpleSAML/XHTML/Template.php

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
* @author Andreas Åkre Solberg, UNINETT AS. <andreas.solberg@uninett.no>
88
* @package SimpleSAMLphp
99
*/
10+
11+
1012
class SimpleSAML_XHTML_Template
1113
{
1214

@@ -154,9 +156,15 @@ private function setupTwig()
154156
}
155157

156158
$twig = new \Twig_Environment($loader, array('cache' => $cache, 'auto_reload' => $auto_reload));
157-
if ($this->localization->i18nBackend == 'twig.i18n') {
158-
$this->localization->activateDomain('ssp');
159-
$twig->addExtension(new \Twig_Extensions_Extension_I18n());
159+
// set up translation
160+
if ($this->localization->i18nBackend == 'twig.gettextgettext') {
161+
/* if something like pull request #166 is ever merged with
162+
* twig.extensions.i18n, use the line below:
163+
* $twig->addExtension(new \Twig_Extensions_Extension_I18n('__', 'n__'));
164+
* instead of the two lines after this comment
165+
*/
166+
$twig->addFilter(new Twig_SimpleFilter('trans', '__'));
167+
$twig->addTokenParser(new \SimpleSAML_Twig_TokenParser_Trans());
160168
}
161169
return $twig;
162170
}
@@ -264,6 +272,7 @@ private function generateLanguageBar()
264272
*/
265273
private function twigDefaultContext()
266274
{
275+
$this->data['localeBackend'] = $this->configuration->getString('language.i18n.backend', 'ssp');
267276
$this->data['currentLanguage'] = $this->translator->getLanguage()->getLanguage();
268277
// show language bar by default
269278
if (!isset($this->data['hideLanguageBar'])) {

templates/sandbox.twig

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,10 @@
22
{% block content %}
33
<p>This page exists as a sandbox to play with twig without affecting anything else. The template is in ./templates.</p>
44
<p>{{ sometext }}</p>
5+
<h2>And now for some localization</h2>
6+
<p>Locale backend in use: {{ localeBackend }}</p>
57
<p>Original: Hello, Untranslated World!</p>
68
<p>Translated: {% trans 'Hello, Untranslated World!' %}</p>
9+
<p>Filtertrans-test: {{ 'Hello, Untranslated World!'|trans }}</p>
710
<p>Current locale set: {{ currentLanguage }}</p>
811
{% endblock content %}

0 commit comments

Comments
 (0)