This plugins provides:
- Route class for generating and matching urls with language prefix.
- Middleware (dispatcher filter or CakePHP < 3.3) which sets
I18n::locale()
based on language prefix in URL and also provides redirection to appropriate URL with language prefix when accessing site root. - Class for retrieving translation messages stored in database instead of po/mo files.
- Validation class for auto translating validation message.
- A widget to generate select box with list of timezone identifiers.
- CakePHP 3.0+
composer require admad/cakephp-i18n
Load the plugin in config/bootstrap.php
:
// Load the plugin.
Plugin::load('ADmad/I18n');
The I18nRoutes
helps generating routes of style /:lang/:controller/:action
.
For e.g. you can add routes to your routes.php
similar to the ones shown below:
Router::scope('/', function ($routes) {
$routes->connect(
'/:controller',
['action' => 'index'],
['routeClass' => 'ADmad/I18n.I18nRoute']
);
$routes->connect(
'/:controller/:action/*',
[],
['routeClass' => 'ADmad/I18n.I18nRoute']
);
});
Fragment /:lang
will be auto prefixed to the routes which allows matching
URLs like /en/posts
, /en/posts/add
etc. The :lang
element is persisted so
that when generating URLs if you don't provide the lang
key in URL array it
will be automatically added based on current URL.
When connecting the routes you can use lang
key in options to provide regular
expression to match only languages which your app supports. Or your can set
config value I18n.languages
which the route class will use to auto generate
regex for lang
element matching:
Configure::write('I18n.languages', ['en', 'fr', 'de']);
Note: I18nRoute
extends core's DashedRoute
so the URL fragments will be
inflected accordingly.
Create database table using sql file provided in config
folder.
Add code similar to what's shown below in your app's config/bootstrap.php
:
// Configure I18n to use DbMessagesLoader for default domain. You need to do
// this for each domain separately.
I18n::config('default', function ($domain, $locale) {
return new \ADmad\I18n\I18n\DbMessagesLoader(
$domain,
$locale
);
});
Use can use ADmad/I18n.I18n
shell to extract the translation message from your code
files and populate the translations table. Updating the db records with
translations for each language is upto you. Having the messages in a table
instead of files make it much to make a web interface for managing translations.
You can setup the I18nMiddleware
in your src/Application::middleware()
as
shown:
$middlware->add(new \ADmad\I18n\Middlware\I18nMiddleware([
'defaultLanguage' => 'en',
'languages' => [
'en' => ['locale' => 'en_US'],
'fr' => ['locale' => 'fr_FR']
],
]));
The keys of languages
array are the language prefixes you use in your URL.
In your AppView::initialize()
configure the FormHelper
to use TimezoneWidget
.
// src/View/AppView.php
public function initialize()
{
$this->loadHelper('Form', [
'widget' => [
'timezone' => ['ADmad/I18n.Timezone']
]
]);
}
You can generate a select box with timezone identifiers like:
// Generates select box with list of all timezone identifiers grouped by regions.
$this->Form->input('fieldname', ['type' => 'timezone']);
// Generates select box with list of timezone identifiers for specified regions.
$this->Form->input('fieldname', [
'type' => 'timezone',
'options' => [
'Asia' => DateTimeZone::ASIA,
'Europe' => DateTimeZone::EUROPE
]
]);
As shown in example above note that unlike normal select box, options
is now
an associative array of valid timezone regions where the key will be used as
optgroup
in the select box.