php-translation / symfony-bundle Goto Github PK
View Code? Open in Web Editor NEWSymfony integration for Translations
License: MIT License
Symfony integration for Translations
License: MIT License
A small summary would be enough:
Files created: 0, translations downloaded: 0
We may ship a small default controller to enable and disable the feature when using the default Activator.
This must be optional (maybe some commented out lines in the routing file?).
When I was trying to sync translations I get this warning:
Warning: array_merge(): Argument #2 is not an array
500 Internal Server Error - ContextErrorException
This happens in: vendor/php-translation/symfony-bundle/Model/SfProfilerMessage.php at line 142:
if (!empty($this->getParameters())) {
// Reduce to only get one value of each parameter, not all the usages.
$meta['parameters'] = array_reduce($this->getParameters(), 'array_merge', []);
}
I'm not sure what is happening in the code there, but getParameters contains an instance of Symfony\Component\VarDumper\Cloner\Data and that causes the problem (dump from $toSave in SymfonyProfilerController:203):
["plmessagescopyright_key"]=>
array(8) {
["locale"]=>
string(2) "pl"
["domain"]=>
string(8) "messages"
["id"]=>
string(13) "copyright_key"
["translation"]=>
string(13) "copyright_key"
["parameters"]=>
array(1) {
[0]=>
object(Symfony\Component\VarDumper\Cloner\Data)#1296 (6) {
["data":"Symfony\Component\VarDumper\Cloner\Data":private]=>
array(2) {
[0]=>
array(1) {
[0]=>
object(Symfony\Component\VarDumper\Cloner\Stub)#1297 (8) {
["type"]=>
string(5) "array"
["class"]=>
string(5) "assoc"
["value"]=>
int(1)
["cut"]=>
int(0)
["handle"]=>
int(0)
["refCount"]=>
int(0)
["position"]=>
int(1)
["attr"]=>
array(0) {
}
}
}
[1]=>
array(1) {
["%date%"]=>
string(4) "2017"
}
}
["position":"Symfony\Component\VarDumper\Cloner\Data":private]=>
int(0)
["key":"Symfony\Component\VarDumper\Cloner\Data":private]=>
int(0)
["maxDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
int(20)
["maxItemsPerDepth":"Symfony\Component\VarDumper\Cloner\Data":private]=>
int(-1)
["useRefHandles":"Symfony\Component\VarDumper\Cloner\Data":private]=>
int(-1)
}
}
["transChoiceNumber"]=>
NULL
["state"]=>
int(1)
["count"]=>
int(1)
}
It would be nice with a feature that automatically adds missing translations to third party services.
See https://github.com/Happyr/TranslationBundle/blob/master/src/Translation/AutoAdder.php
Just an idea, see it as a really low priority feature request:
We have ten translators that all are responsible for one specific locale
. Next to that we have two "super" translators, that are responsible for reviewing the translations of five of these locales
. It would be great if we can notify these translators if we require their action.
Scenario 1: send email about new translations
locales
, and as the CI did send an optional commit message with the push action, that message is included with the emailScenario 2: translator 100% completed translating a locale
dev
email address about thatWhen deploying application with capistrano it fails and throws an exception:
[RuntimeException]
An error occurred when executing the "'cache:clear --no-warmup'" command:
PHP Fatal error: Uncaught LogicException: [PHP-Translation] To integrate with the Symfony profiler you first need to enable it. Please set framework.translator.enabled: true in /***/vendor/php-translation/symfony-bundle/DependencyInjection/CompilerPass/SymfonyProfilerPass.php:33
Exception is thrown because $container
has no definition for translator.data_collector
, and it's not fixed when
framework:
enabled: true
As suggested by @rvanlaak:
The "EditInPlace translator" should be living under Translation\Bundle\Translator
, right?
Same would go for ResponseListener and Twig. Or do we like to keep all these classes in the "feature folder"? What do you thing?
A command that tells you how may new, obsolete and total translation you got.
I noticed that as soon as messages have space - this bundle wrap them with single quotes.
What about to look for \n
and :
inside messages and wrap them with quotes only if found (not sure about possible conflicts with other symbols) - just an idea how to improve it
See: XliffConverter::catalogueToContent(MessageCatalogue $catalogue, $domain)
It does not set that option, and therefore in Symfony's XliffFileDumper \Locale::getDefault()
is used
see:
if (array_key_exists('default_locale', $options)) {
$defaultLocale = $options['default_locale'];
} else {
$defaultLocale = \Locale::getDefault();
}
The XliffConverter should get the default_locale from the configuration and pass that here.
Hi,
"Synchronize all translations" button doesn't work in profiler.
I get the following JS error when I click:
symfonyProfiler.js:43 Uncaught TypeError: Cannot set property 'innerHTML' of undefined at syncAll (symfonyProfiler.js:43) at HTMLAnchorElement.onclick (f8c6e1?panel=translation:1994)
For information I'm using Symfony 3.4.2 and chrome 63
This will make our configuration more type safe.
Unable to find templates to the WebUI
Unable to find template "TranslationBundle:WebUI:base.html.twig" (looked into: /lsv/templates, /lsv/vendor/symfony/twig-bridge/Resources/views/Form) in @Translation/WebUI/index.html.twig at line 1.
Twig configuration
twig:
paths:
- '%kernel.project_dir%/templates'
debug: '%kernel.debug%'
strict_variables: '%kernel.debug%'
form_themes: ['form.html.twig']
form.html.twig is in my src/templates/form.html.twig
and just extends bootstrap_4_layout.html.twig
We need unit tests and tests for the configuration
It seems that only when debug
is enabled, TranslationExtension
is used. The trans
and transchoice
filter then are marked as html safe, so the values will not get encoded anymore.
See https://github.com/php-translation/symfony-bundle/blob/master/Twig/TranslationExtension.php#L28-L29
As result of that, we "forget" to add {{ 'key'|trans|raw }}
, because outputting raw values already happens on dev
. When prod
thereafter is updated, the encoded value just get outputted again:
So in Twig the following:
Translation value: This is a test that is valid until <strong>%date%</strong>
Twig: {{ 'translation_key'|trans({'%date%': date}) }}
Output on debug = true
environments
This is a test that is valid until Wed June 14
Output on debug = false
environments
This is a test that is valid until <strong>Wed June 14</strong>
We expect the output to be the same for any type of environment. The proposed solution would be to not handle is_safe
via the Twig extensions. Are there any reasons why is_safe
should be there?
Hi,
I'm having troubles with the edit in place, wich works well in some pages, and not on others.
For example, i'm having this JS error on one page :
content-tools.min.js:3 Uncaught DOMException: Failed to execute 'setAttribute' on 'Element': 'light-blue"' is not a valid attribute name.
at c.a.Text.c.mount (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:3:20706)
at new c (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:3:12341)
at c._initRegions (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:6:24008)
at c.start (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:6:20300)
at b.<anonymous> (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:6:14355)
at b.ComponentUI.a.dispatchEvent (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:4:24074)
at b.IgnitionUI.b.edit (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:4:27817)
at HTMLDivElement.<anonymous> (http://mywebsite.fr/bundles/translation/js/content-tools.min.js:4:29468)
Searching in code source for light-blue give's me some span, like :
<span class="light-blue">Sorted.</span>
Any idea ?
Thank you for your help
The reason is that bundle does not know that these translations were already sent.
The only way of knowing that is to see if translation exists.
If asset on the remote exists, but was not translated, it will not be downloaded.
I think about accepting this type of response from SaaS so it will not break the whole process, or - to check if asset already exists and ignore it if it does.
From @damienalexandre:
I think it would be better to use the Symfony Serializer and a real object for the create and edit actions.
That way the validation of the object can be handled by the Validator component, and you don't have to handle the JSON decoding errors.
class TranslationMessage
{
private $key;
private $message;
}
Also at the moment you only check that a key exists, but it might still be empty 🙅♂️
And the responses from this API would be great with JsonResponse too 👍
Hi, I'm using the bundle in Sf 3.3-BETA. No problem during installation. But after apply a simple config:
translation:
locales: ['fr', 'en']
symfony_profiler:
enabled: true
configs:
app:
dirs: ["%kernel.root_dir%/Resources/views", "%kernel.root_dir%/../src"]
output_dir: "%kernel.root_dir%/Resources/translations"
excluded_names: ["*TestCase.php", "*Test.php"]
excluded_dirs: [cache, data, logs]
When I want to edit
a missing message in SfProfiler, I catch this error in Network
tab in DevTools (url: http://myapp.dev/app_dev.php/19ed84/translation/edit?message_id=frmessagessearch.form.origin.label
).
Type error: Argument 1 passed to Translation\Bundle\Model\SfProfilerMessage::create() must be of the type array, object given, called in /var/www/vendor/php-translation/symfony-bundle/Controller/SymfonyProfilerController.php on line 160
If you need more information, let me know.
The Content Tools library has some nice new features and just got a new release: https://github.com/GetmeUK/ContentTools/releases/tag/1.6.0
We run 1.3.1 at the moment, I think updating is worth trying to help with #58 #60.
Cannot edit or cancel editing of fallback translations, get an error in Chrome Console:
symfonyProfiler.js:79 Uncaught TypeError: Cannot read property 'getElementsByClassName' of null
at saveEditForm (symfonyProfiler.js:79)
at HTMLInputElement.onclick (f78a96?panel=translation:1)
Steps to reproduce:
I get the following JS error:
Uncaught TypeError: Cannot read property 'getElementsByClassName' of null at saveEditForm (symfonyProfiler.js:79) at HTMLInputElement.onclick (9bf8c4?panel=translation:1)
After investigation it is due to variable 'key' generation.
id attribute in html is generated with including current locale and key in saveEditForm is generated with including fallback source locale.
So, symfonyProfiler.js:79, document.getElementById(key) can't find id because in case of fallback message tab, and contrary to missing transaltions tab, id are differents. So, in that case, Js fails and it stops save process.
When editing a translation via EditInPlace, we should use the status bar of ContentTools (at the bottom of the page) to display contextual informations about the current editing:
This will mainly require JavaScript to extend the ContentTools Inspector UI https://github.com/GetmeUK/ContentTools/blob/master/src/scripts/ui/inspector.coffee
When I enable the edit-in-place feature, the frontend gets destroyed completely, the website is unusable. So I have to disable this feature for now. Is there anything you can do about it?
Is it possible to map domains with loco tags like with happyr bundle ?
dedicated loco projects to domain is working but I tried:
translation_adapter_loco:
projects: test: api_key: 'xxx' domains: ['messages', 'validators']
I can't find any information in doc.
thanks for your help.
%kernel.cache_dir%/translations
is still there after translations are added, resulting in adding translations to remote storage again and again, unless the cache is manually cleared.
Would be great if the web UI would be able to filter on a profiler token. Since 2.7 the profiler collects all translations: symfony/symfony#14003
<select>
with the last 10 profile tokensAlso see lexik/LexikTranslationBundle#165
When having country specific translations there are locales like de_CH
and fr_FR
. In my opinion the "Missing" tab in the profiler should only offer the possibility to translate the non country specific versions de
and fr
by default.
If the current locale setting is de_CH
and there wasn't a fallback to de
available (then it would be in the "Fallback" tab) a new created translation should always be de
(if de
is also in the supported locales) - this is also the symfony default behaviour.
When translations are new, or when they have been edited lately, a workflow to approve them would help to ensure translation quality. The Xliff standard does support this out of the box, the bundle can help with that. Also see XliffExporter
.
Scenario 1: new translation
xliff
file with approved
attribute set to no
if the translation has a value.approved
to yes
Scenario 2: updating translation via edit in place or profiler
approved
back to no
Scenario 3: updating translation web ui
Future enhancement could be to require a certain ROLE
in order to approve a translation.
Executing bin/console config:dump-reference translation
command gives the next error:
[LogicException]
The extension with alias "translation" does not have its getConfiguration() method setup
The "can't be edited" message is great, but it breaks behavior in some cases. Some enhancements for this message would be:
xliff
?)We can always refer to the web UI or profiler.
It's a bit tricky, but I think it could be considered as incorrect progress counting, let me show an example:
Suppose, I have 3 different translation keys in total: foo
, hello
, and world
.
And I have 2 languages, but each one has only 2 different of them:
# messages.en.yml
foo: bar
hello: Hello
# messages.ru.yml
hello: Привет
world: Мир
i.e. if 2 of them are translated into English and another 2 of them are translated into Russian - I have for both:
Total progress for this language: 100%
But I expected to see 66% for both
Hi,
I think desc twig filter is very usefull and it could be easier to migrate from JMSTranslation when we are using it in all our code.
More details about desc filter here: http://jmsyst.com/bundles/JMSTranslationBundle/master/usage
It always sends translations from local to remote, or merges the two.
Any translation removed from the remote is keep comming back from local files rather than beeing removed. If we assume that local files are only "cache", then our sync should always overwrite these files.
Even after changing direction direcly in commands code, the old translations were sent to SaaS.
There are some configuration that is not used. That needs to be cleaned up.
When labels that have a parsed value get translated, the value overwrites the parameter placeholder.
title: 'Hi %name%'
# will be saved as
title: 'Howdy Richard'
For EditInPlace this can be fixed by:
<x-trans>
tag as a data-value
attribute, without any replaced parameter.data-value
, so it is clear to the translator that it is a dynamic parameter.No commands are added in symfony 4
We may just need to register them in DIC and add a tag.
Hello,
I'm trying to use translation:extract in my project.
The process yields a bunch of errors that shouldn't be there:
a- "Message: Form label is not a scalar string": this error happens when I set label => false
on my form configuration. According to Symfony documentation, this is the way to disable label settings, so the field should be simply ignored.
b- "Message: Form choice is not an array": this error happens when I use a function that returns an array instead of an array for a ChoiceType
element. I think the extractor should compute the result of the function and use that to extract the translation items.
in vendor/php-translation/symfony-bundle/Controller/SymfonyProfilerController.php at line 152
$messages = $profile->getCollector('translation')->getMessages();
We should always use the local file storage because it will speed up everything. But additional to that one could use a platform adapter. It is also a storage interface.
One should maybe create a service that chain multiple StorageInterfaces. The LocalFilesystem storage should always be there.
Hi,
I get the following error when I try to extract:
console translation:extract app en
14:18:54 ERROR [console] Error thrown while running command "translation:extract app fr". Message: "Notice: Undefined offset: 0" ["error" => Symfony\Component\Debug\Exception\ContextErrorException { …},"command" => "translation:extract app fr","message" => "Notice: Undefined offset: 0"] []In FormTypeLabelImplicit.php line 37:
Notice: Undefined offset: 0
translation:extract [--hide-errors] [-h|--help] [-q|--quiet] [-v|vv|vvv|--verbose] [-V|--version] [--ansi] [--no-ansi] [-n|--no-interaction] [-e|--env ENV] [--no-debug] [--] [] []
The "editing in place" save action does not store any translations when authenticated anonymous. The problem is that the javascript actually shows the "big white save check", but refreshing the page then shows the original translations again.
I've inspected the POST to the save action, and it seems like it was trying to save translations for nl
instead of en
. Next to that, the POST did not contain any data according to the profiler.
After logging in, and having a UsernamePasswordToken
, the save action was successful again.
This should be a separate package.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.