-
Notifications
You must be signed in to change notification settings - Fork 237
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Auto translate using Translation Engine #284
base: 2.x
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi,
I tested this pull request as we're looking into using this for our own project.
Summary
It works mostly fine, but it has trouble with
- translating texts where the key is different from the associated English text, as it translates the key instead of the value
- Single quotes inside calls to
__()
: __('Don't mess up my translation') becomesDon\\'t mess up my translation
instead ofDon't mess up my translation
as well as some smaller issues.
Longer version
How did I test the package?
- Install the
timoye/laravel-translation
auto-translate branch with Composer. - Create a language with missing translations.
- Run
php artisan translation:auto-translate [languageCode]
and check if it captures all keys.
How did I compare translations?
- Sort both
en.json
and<new language>.json
using a tool like JSON sorter. - Paste both in DiffNow or a similar tool and check for new or deleted lines and how it translates each line.
Note
I did not compare thelang/<languageCode>/<...>.php
files.
Results
Neutral
- It skips keys in
en.json
that are not used in the code. This is because it uses the translatable texts from the source code instead of fromen.json
!
Buggy or problematic for my use case
- Instead of translating the value in
en.json
, it translates the key from the source code. This causes issues if the key is not equal to the translatable text!
- Calls to
__()
with PHP code inside are not recognized (and therefore skipped); for example (changed up a bit to remove project details):
__('The user :user has been updated', ['user' => $user->name]), __($user->gender == 'female' ? 'Please take a look at her profile.' : 'Please take a look at his profile.', ['user' => e($user->name)]), __('Proceed to profile page'), subroute('profile.index'));
This is the only one I found in my project, so it's not the most pressing issue.
- Unlike the other package I tried using, it does not completely ignore texts with quotes. However, because it extracts them from the source code, quotes are double-escaped:
__('Don\'t mess up my translation')
becomes the keyDon\\'t mess up my translation
, instead ofDon't mess up my translation
(backslashes are not needed here, as JSON uses double quotes instead of single quotes).
Good
- Texts with newlines in the key and/or value, for example,
"Preferably, as long as there are mentors of the same\n gender available": "Preferably, as long as there are mentors of the same\n gender available"
, are handled correctly (unliketanmuhittin/laravel-google-translate
). Although in my translation, it uses\r\n
in the key (and\n
in the translation). This may be Windows-specific. - Texts with double quotes in the key/value are handled correctly (unlike the other package I tried using):
becomes
"You are not allowed to send a message to the user with user id \":id\".": "You are not allowed to send a message to the user with user id \":id\".",
"You are not allowed to send a message to the user with user id \":id\".": "Non è consentito inviare un messaggio all'utente con ID utente \":id\".",
Note
I only checked the JSON; files inlang/<languageCode>/*.php
have not been checked.
src/Drivers/Translation.php
Outdated
foreach ($groups as $group => $translations) { | ||
foreach ($translations as $key => $value) { | ||
if (in_array($value,["",null])){ | ||
$new_value=$this->getGoogleTranslate($language,$key); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
W.r.t. the issue I identified earlier,
Instead of translating the value in en.json, it translates the key from the source code. This causes issues if the key is not equal to the translatable text!
I fixed this function to pass the value from the source language instead:
/**
* Loop through all the keys and get translated text from Google Translate
*
* @param $language
*/
public function translateLanguage($language){
$translations = $this->getSourceLanguageTranslationsWith($language);
foreach ($translations as $type => $groups) {
foreach ($groups as $group => $translations) {
foreach ($translations as $key => $value) {
$sourceLanguageValue = $value[$this->sourceLanguage];
$targetLanguageValue = $value[$language];
if (in_array($targetLanguageValue,["",null])){
$new_value=$this->getGoogleTranslate($language,$sourceLanguageValue);
if (Str::contains($group, 'single')) {
$this->addSingleTranslation($language, $group, $key,$new_value);
} else {
$this->addGroupTranslation($language, $group, $key,$new_value);
}
}
}
}
}
}
It now works correctly
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've created a pull request for your auto-translate branch to fix this, please check it out!
This resolves the issue where, instead of translating the value in the language file of the source language (e.g. en.json), it translates the key from the source code. This causes issues if the key is not equal to the translatable text!
…tion auto-translate value instead of key
Instead of defaulting to 'auto' and relying on Google guessing this correctly.
getSourceLanguageTranslationsWith() only takes strings from the language files, not from the application source code. If you call auto-translate with a language parameter, it'll add missing keys to the target language, but not to the source language files. We work around this by falling back to the key if no value is set in the source language.
…_empty_-_using_auto_translate_branch_as_a_base Fall back to key if source language is empty
@@ -78,7 +78,7 @@ public function autoTranslate($language = false) | |||
* @throws \ErrorException | |||
*/ | |||
public function getGoogleTranslate($language,$token){ | |||
$tr = new GoogleTranslate($language, $this->sourceLanguage); | |||
$tr = new GoogleTranslate($language); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It isn't strictly necessary to pass the source language, but it's my understanding that if you don't, Google Translate will try to guess the source language (it's set to auto
). That can sometimes lead to wrong results if two languages have the same word with a different meaning, e.g. the word 'brand' means fire in Dutch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh I see. that is correct.
I didn't look at that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No problem. Thanks for your part of writing this pull request
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It is my pleasure.
It was quite helpful to me and I thought to let others use it also
translation:auto-translate
This command will scan your project (using the paths supplied in the configuration file) and create all of the missing translation keys. This can be run for all languages or a single language.
It will then translate all the tokens using Google Translate for FREE!
You can edit these auto translated texts using the User interface