Hi.
We need to translate our app, we have more than 4000 strings and while yii2-translate-manager is an awesome extension it doesn’t offer all the features of other online tools, like Weblate. The big things we’re looking after are glossary and translation memory.
I did a quick search, and it looks like the translation files format used by Yii2 is not very common, I couldn’t find any platform accepting it. Also we’d like to stick with the extension above, as it supports translating database tables. Unfortunately, exporting from yii2-translate-manager doesn’t seem an option either, as it uses only JSON and XML with a custom formatting…
Does anyone have experience with other translation services playing nice with yii2-translate-manager, or with yii2 at least?
I added the source language to the 'languages' to be generated by the extractor, but I still need to update the file with the source strings.
Is there some way I can hook to the message/extract command, and adjust the source language file as I need it? I checked the controller source but I haven’t been able to find a way. I cannot even override the controller with a child class, as all methods are protected… I hope I have missed an option.
Otherwise, I need to implement a custom controller/action, but then I must remember to run it every time I run extract.
protected means you can extend from the command class and then use command map to replace the command so when you run message/extract you actually use your new command class.
<?php
/*
* This file is part of the YetOpen Helpers Extension project.
* (c) YetOpen <https://yetopen.com>
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace yetopen\helpers\controllers;
use Yii;
use yii\console\controllers\MessageController as BaseMessageController;
use yii\console\ExitCode;
use yii\helpers\Console;
use yii\helpers\VarDumper;
/**
* MessageController override for creating `sourceLanguage` translation file with keys
* matching message string, to be used in Weblate.
*
* Prerequisites:
* 1. controllerMap > message must be configured to link this class
* 2. app's translation config must include app's `sourceLanguage`
*/
class MessageController extends BaseMessageController
{
/**
* Override of the original method to write a full `sourceLanguage` file in 'msg' => 'msg' format.
* WARNING: the translation config must contain `sourceLanguage` in `languages`.
*
* @param array $messages
* @param string $fileName name of the file to write to
* @param bool $overwrite if existing file should be overwritten without backup
* @param bool $removeUnused if obsolete translations should be removed
* @param bool $sort if translations should be sorted
* @param string $category message category
* @param bool $markUnused if obsolete translations should be marked
* @return int exit code
*/
protected function saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused)
{
// We need to act when the message file we're handling is for app's `sourceLanguage`. At this time we don't have
// the language anywhere but in `$fileName`, which is in `.../{language}/{category}.php` format.
$lastDir = dirname($fileName);
$langFile = substr($lastDir, strrpos($lastDir, DIRECTORY_SEPARATOR) + 1);
// If the request is for a translation file, process it normally
if ($langFile != Yii::$app->sourceLanguage) {
return parent::saveMessagesCategoryToPHP($messages, $fileName, $overwrite, $removeUnused, $sort, $category, $markUnused);
}
// Otherwise write the full lang file (portions of code from original method)
$merged = array_combine($messages, $messages);
ksort($merged);
$array = VarDumper::export($merged);
$content = <<<EOD
<?php
{$this->config['phpFileHeader']}{$this->config['phpDocBlock']}
return $array;
EOD;
if (file_put_contents($fileName, $content, LOCK_EX) === false) {
$this->stdout("sourceLanguage file was NOT saved.\n\n", Console::FG_RED);
return ExitCode::UNSPECIFIED_ERROR;
}
$this->stdout("sourceLanguage file saved.\n\n", Console::FG_GREEN);
return ExitCode::OK;
}
}