-
Notifications
You must be signed in to change notification settings - Fork 177
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
[#163] Added support for translation extractors for JS #238
Changes from 1 commit
6b4463a
3743264
7a0bc62
7f3b2ab
9f3d600
32f738c
5aaac48
4137824
4b1f6c4
d57b413
e33a819
f243f89
fb372e7
0ee29c6
2b2c5d4
e6dba39
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
More flexible way to handle extraction from other sources than twig or php
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -34,6 +34,17 @@ public function getConfigTreeBuilder() | |
->prototype('scalar') | ||
->end() | ||
->end() | ||
->arrayNode('frontend') | ||
->arrayPrototype() | ||
->children() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation should use 4 spaces There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
->arrayNode('extensions') | ||
->prototype('scalar') | ||
->end() | ||
->end() | ||
->scalarNode('sequence')->end() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Forcing our users to configure the regex themselves looks like a bad DX to me. Maintaining this regex for the common cases should be the bundle responsibility (you can make it configurable in the extractor class to make it generic, but then, please provide pre-configured services) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. Hopefully the default configuration is alright. |
||
->end() | ||
->end() | ||
->end() | ||
->end(); | ||
|
||
return $builder; | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,7 +8,7 @@ | |
use Symfony\Component\Translation\MessageCatalogue; | ||
use Symfony\Component\Translation\Extractor\ExtractorInterface; | ||
|
||
abstract class Extractor extends AbstractFileExtractor implements ExtractorInterface | ||
final class FrontendExtractor extends AbstractFileExtractor implements ExtractorInterface | ||
{ | ||
const FUNCTION_STRING_ARGUMENT_REGEX = '\s?[\'"]([^"\'),]+)[\'"]\s?'; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this should use possessive quantifiers to avoid useless backtracking, allowing to match on bigger files. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not familiar with possessive quantifiers. My regex skills aren't strong enough. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes (well, I would keep and btw, why forbidding commas and parenthesis inside the string ? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'd say is to ensure the use of transalation key but the again I don't really know as I forked this feature where @jcchavezs left it. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That is exactly the reason but if this can be improved that is great. What I'd request @stof is to drop here the cases we are trying to avoid so they can be added to unit tests. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I see 2 issues here:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And here are a few cases: t.trans('some,thing')
t.trans('display(details)' There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The final space matching is useless (except to increase backtracking due to being non-possessive), as you don't care about what comes next There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Spaces between the function call and the string should allow multiple spaces too, not just a single one. |
||
const REGEX_DELIMITER = '/'; | ||
|
@@ -17,8 +17,11 @@ abstract class Extractor extends AbstractFileExtractor implements ExtractorInter | |
|
||
private $filesystem; | ||
|
||
public function __construct(Filesystem $filesystem) { | ||
$this->filesystem = $filesystem;; | ||
private $configuration; | ||
|
||
public function __construct(Filesystem $filesystem, array $configuration = []) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. rather than an array of configurations here, with each configuration being a non-validated struct expected to have There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
$this->filesystem = $filesystem; | ||
$this->configuration = $configuration; | ||
} | ||
|
||
/** | ||
|
@@ -29,7 +32,14 @@ public function extract($resource, MessageCatalogue $catalogue) | |
$files = $this->extractFiles($resource); | ||
|
||
foreach ($files as $file) { | ||
$this->parseMessagesFromContent(file_get_contents($file), $catalogue); | ||
foreach ($this->configuration as $configuration) | ||
{ | ||
$pathInfo = pathinfo($file); | ||
if (in_array($pathInfo['extension'], $configuration['extensions'], true)) | ||
{ | ||
$this->parseMessagesFromContent(file_get_contents($file), $catalogue, $configuration['sequence']); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is nothing ensuring that There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
} | ||
} | ||
} | ||
} | ||
|
||
|
@@ -41,9 +51,9 @@ public function setPrefix($prefix) | |
$this->prefix = $prefix; | ||
} | ||
|
||
private function parseMessagesFromContent($fileContent, MessageCatalogue $catalogue) | ||
private function parseMessagesFromContent($fileContent, MessageCatalogue $catalogue, $sequence) | ||
{ | ||
$messages = $this->getMessagesForSequence($fileContent, $this->sequence); | ||
$messages = $this->getMessagesForSequence($fileContent, $sequence); | ||
|
||
foreach ($messages as $message) { | ||
$catalogue->set($message, $this->prefix.$message); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Setting them always in the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Then should we specify the domain in the constructor? (as the TranslationDumper does) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The default domain should indeed be injected in the constructor. |
||
|
@@ -53,7 +63,10 @@ private function parseMessagesFromContent($fileContent, MessageCatalogue $catalo | |
/** | ||
* @return array | ||
*/ | ||
abstract protected function getSupportedFileExtensions(); | ||
protected function getSupportedFileExtensions() | ||
{ | ||
return call_user_func_array('array_merge', array_column($this->configuration, 'extensions')); | ||
} | ||
|
||
protected function canBeExtracted($file) | ||
{ | ||
|
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -26,13 +26,10 @@ | |
<argument>%kernel.root_dir%</argument> | ||
<tag name="console.command" command="bazinga:js-translation:dump" /> | ||
</service> | ||
<service id="bazinga.jstranslation.translation_js_extractor" class="Bazinga\Bundle\JsTranslationBundle\Extractor\JsExtractor"> | ||
<service id="bazinga.jstranslation.translation_frontend_extractor" class="Bazinga\Bundle\JsTranslationBundle\Extractor\FrontendExtractor" public="true"> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should not be public. Extractors are totally fine as private services as Symfony does not retrieve them dynamically from the container. This would allow inlining the service. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
<argument type="service" id="filesystem"></argument> | ||
<tag name="translation.extractor" alias="js" /> | ||
</service> | ||
<service id="bazinga.jstranslation.translation_coffee_extractor" class="Bazinga\Bundle\JsTranslationBundle\Extractor\CoffeeExtractor"> | ||
<argument type="service" id="filesystem"></argument> | ||
<tag name="translation.extractor" alias="coffee" /> | ||
<tag name="translation.extractor" alias="frontend" /> | ||
<argument></argument> <!-- frontend --> | ||
</service> | ||
</services> | ||
</container> |
This file was deleted.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,20 +2,26 @@ | |
|
||
namespace Bazinga\JsTranslationBundle\Tests\Extractor; | ||
|
||
use PHPUnit\Framework\TestCase; | ||
use Bazinga\Bundle\JsTranslationBundle\Extractor\FrontendExtractor; | ||
use Bazinga\Bundle\JsTranslationBundle\Tests\WebTestCase; | ||
use Symfony\Component\Translation\MessageCatalogue; | ||
use Bazinga\Bundle\JsTranslationBundle\Extractor\Extractor; | ||
|
||
abstract class AbstractExtractorTest extends TestCase | ||
final class FrontendExtractorTest extends WebTestCase | ||
{ | ||
const TEST_LOCALE = 'en'; | ||
const TEST_KEY_1 = 'test-key-1'; | ||
|
||
/** | ||
* @var Extractor | ||
* @var FrontendExtractor | ||
*/ | ||
protected $extractor; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should be private There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
|
||
public function setUp() | ||
{ | ||
$container = $this->getContainer(); | ||
$this->extractor = $container->get('bazinga.jstranslation.translation_frontend_extractor'); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK, this is the only place where you need the service to be public. But there is a much simpler way to handle all this: don't use a WebTestCase to test the FrontendExtractor but instantiate it directly in the test (the only other service it depends on is the Filesystem, which is dead easy to instantiate) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. OK |
||
} | ||
|
||
/** | ||
* @dataProvider resourcesWithNotValidTransFunctionUsage | ||
*/ | ||
|
This file was deleted.
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 would rather name it
extractor