Skip to content

Commit 03e4c27

Browse files
authored
Added Twig2 support (#26)
* Added Twig2 support * cs * cs * Acced change log
1 parent d76c5ef commit 03e4c27

13 files changed

+281
-58
lines changed

Changelog.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22

33
The change log describes what is "Added", "Removed", "Changed" or "Fixed" between each release.
44

5+
## UNRELEASED
6+
7+
### Added
8+
9+
- Support for Twig2.0
10+
511
## 1.0.0
612

713
## Added

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"php": "^5.5 || ^7.0",
1313
"nikic/php-parser": "^3.0",
1414
"symfony/finder": "^2.7 || ^3.0",
15-
"twig/twig": "^1.21"
15+
"twig/twig": "^1.27 || ^2.0"
1616
},
1717
"require-dev": {
1818
"phpunit/phpunit": "^4.5 || ^5.4",

src/FileExtractor/TwigFileExtractor.php

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,9 @@ final class TwigFileExtractor implements FileExtractor
3333
/**
3434
* @param \Twig_Environment $twig
3535
*/
36-
public function __construct(\Twig_Environment $twig = null)
36+
public function __construct(\Twig_Environment $twig)
3737
{
38-
$this->twig = $twig ?: new \Twig_Environment();
38+
$this->twig = $twig;
3939
}
4040

4141
public function getSourceLocations(SplFileInfo $file, SourceCollection $collection)
@@ -46,7 +46,13 @@ public function getSourceLocations(SplFileInfo $file, SourceCollection $collecti
4646

4747
$path = $file->getRelativePath();
4848

49-
$tokens = $this->twig->parse($this->twig->tokenize($file->getContents(), $path));
49+
if (class_exists('Twig_Source')) {
50+
// Twig 2.0
51+
$stream = $this->twig->tokenize(new \Twig_Source($file->getContents(), $file->getRelativePathname(), $path));
52+
} else {
53+
$stream = $this->twig->tokenize($file->getContents(), $path);
54+
}
55+
$tokens = $this->twig->parse($stream);
5056
$traverser = new \Twig_NodeTraverser($this->twig, $this->visitors);
5157
$traverser->traverse($tokens);
5258
}

src/Visitor/Twig/TranslationBlock.php

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111

1212
namespace Translation\Extractor\Visitor\Twig;
1313

14-
use Symfony\Bridge\Twig\Node\TransNode;
15-
use Translation\Extractor\Model\SourceLocation;
1614
use Translation\Extractor\Visitor\BaseVisitor;
1715
use Twig_Environment;
1816
use Twig_NodeInterface;
@@ -22,20 +20,21 @@
2220
*/
2321
final class TranslationBlock extends BaseVisitor implements \Twig_NodeVisitorInterface
2422
{
25-
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
26-
{
27-
if ($node instanceof TransNode) {
28-
$id = $node->getNode('body')->getAttribute('data');
29-
$domain = 'messages';
30-
if ($node->hasNode('domain')) {
31-
$domain = $node->getNode('domain')->getAttribute('value');
32-
}
23+
/**
24+
* @var WorkerTranslationBlock
25+
*/
26+
private $worker;
3327

34-
$source = new SourceLocation($id, $this->getAbsoluteFilePath(), $node->getLine(), ['domain' => $domain]);
35-
$this->collection->addLocation($source);
36-
}
28+
public function __construct()
29+
{
30+
$this->worker = new WorkerTranslationBlock();
31+
}
3732

38-
return $node;
33+
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
34+
{
35+
return $this->worker->work($node, $this->collection, function () {
36+
return $this->getAbsoluteFilePath();
37+
});
3938
}
4039

4140
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)

src/Visitor/Twig/TranslationFilter.php

Lines changed: 13 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Translation\Extractor\Visitor\Twig;
1313

14-
use Translation\Extractor\Model\SourceLocation;
1514
use Translation\Extractor\Visitor\BaseVisitor;
1615
use Twig_Environment;
1716
use Twig_NodeInterface;
@@ -21,40 +20,21 @@
2120
*/
2221
final class TranslationFilter extends BaseVisitor implements \Twig_NodeVisitorInterface
2322
{
24-
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
25-
{
26-
if (!$node instanceof \Twig_Node_Expression_Filter) {
27-
return $node;
28-
}
29-
30-
$name = $node->getNode('filter')->getAttribute('value');
31-
if ('trans' !== $name && 'transchoice' !== $name) {
32-
return $node;
33-
}
34-
35-
$idNode = $node->getNode('node');
36-
if (!$idNode instanceof \Twig_Node_Expression_Constant) {
37-
// We can only extract constants
38-
return $node;
39-
}
40-
41-
$id = $idNode->getAttribute('value');
42-
$index = 'trans' === $name ? 1 : 2;
43-
$domain = 'messages';
44-
$arguments = $node->getNode('arguments');
45-
if ($arguments->hasNode($index)) {
46-
$argument = $arguments->getNode($index);
47-
if (!$argument instanceof \Twig_Node_Expression_Constant) {
48-
return $node;
49-
}
50-
51-
$domain = $argument->getAttribute('value');
52-
}
23+
/**
24+
* @var WorkerTranslationFilter
25+
*/
26+
private $worker;
5327

54-
$source = new SourceLocation($id, $this->getAbsoluteFilePath(), $node->getLine(), ['domain' => $domain]);
55-
$this->collection->addLocation($source);
28+
public function __construct()
29+
{
30+
$this->worker = new WorkerTranslationFilter();
31+
}
5632

57-
return $node;
33+
public function enterNode(Twig_NodeInterface $node, Twig_Environment $env)
34+
{
35+
return $this->worker->work($node, $this->collection, function () {
36+
return $this->getAbsoluteFilePath();
37+
});
5838
}
5939

6040
public function leaveNode(Twig_NodeInterface $node, Twig_Environment $env)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Twig;
13+
14+
use Translation\Extractor\Visitor\BaseVisitor;
15+
use Twig_Environment;
16+
use Twig_Node;
17+
18+
/**
19+
* @author Tobias Nyholm <[email protected]>
20+
*/
21+
final class Twig2TranslationBlock extends BaseVisitor implements \Twig_NodeVisitorInterface
22+
{
23+
/**
24+
* @var WorkerTranslationBlock
25+
*/
26+
private $worker;
27+
28+
public function __construct()
29+
{
30+
$this->worker = new WorkerTranslationBlock();
31+
}
32+
33+
public function enterNode(Twig_Node $node, Twig_Environment $env)
34+
{
35+
return $this->worker->work($node, $this->collection, function () {
36+
return $this->getAbsoluteFilePath();
37+
});
38+
}
39+
40+
public function leaveNode(Twig_Node $node, Twig_Environment $env)
41+
{
42+
return $node;
43+
}
44+
45+
public function getPriority()
46+
{
47+
return 0;
48+
}
49+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Twig;
13+
14+
use Translation\Extractor\Visitor\BaseVisitor;
15+
use Twig_Environment;
16+
use Twig_Node;
17+
18+
/**
19+
* @author Tobias Nyholm <[email protected]>
20+
*/
21+
final class Twig2TranslationFilter extends BaseVisitor implements \Twig_NodeVisitorInterface
22+
{
23+
/**
24+
* @var WorkerTranslationFilter
25+
*/
26+
private $worker;
27+
28+
public function __construct()
29+
{
30+
$this->worker = new WorkerTranslationFilter();
31+
}
32+
33+
public function enterNode(Twig_Node $node, Twig_Environment $env)
34+
{
35+
return $this->worker->work($node, $this->collection, function () {
36+
return $this->getAbsoluteFilePath();
37+
});
38+
}
39+
40+
public function leaveNode(Twig_Node $node, Twig_Environment $env)
41+
{
42+
return $node;
43+
}
44+
45+
public function getPriority()
46+
{
47+
return 0;
48+
}
49+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Twig;
13+
14+
use Symfony\Bridge\Twig\Node\TransNode;
15+
use Translation\Extractor\Model\SourceCollection;
16+
use Translation\Extractor\Model\SourceLocation;
17+
18+
/**
19+
* @author Tobias Nyholm <[email protected]>
20+
*/
21+
final class WorkerTranslationBlock
22+
{
23+
/**
24+
* @param \Twig_Node|\Twig_NodeInterface $node
25+
* @param SourceCollection $collection
26+
* @param callable $getAbsoluteFilePath
27+
*
28+
* @return \Twig_Node|\Twig_NodeInterface
29+
*/
30+
public function work($node, SourceCollection $collection, callable $getAbsoluteFilePath)
31+
{
32+
if ($node instanceof TransNode) {
33+
$id = $node->getNode('body')->getAttribute('data');
34+
$domain = 'messages';
35+
if ($node->hasNode('domain')) {
36+
if (null !== $domainNode = $node->getNode('domain')) {
37+
$domain = $domainNode->getAttribute('value');
38+
}
39+
}
40+
41+
$source = new SourceLocation($id, $getAbsoluteFilePath(), $node->getTemplateLine(), ['domain' => $domain]);
42+
$collection->addLocation($source);
43+
}
44+
45+
return $node;
46+
}
47+
}
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the PHP Translation package.
5+
*
6+
* (c) PHP Translation team <[email protected]>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Translation\Extractor\Visitor\Twig;
13+
14+
use Translation\Extractor\Model\SourceCollection;
15+
use Translation\Extractor\Model\SourceLocation;
16+
17+
/**
18+
* @author Tobias Nyholm <[email protected]>
19+
*/
20+
final class WorkerTranslationFilter
21+
{
22+
/**
23+
* @param \Twig_Node|\Twig_NodeInterface $node
24+
* @param SourceCollection $collection
25+
* @param callable $getAbsoluteFilePath
26+
*
27+
* @return \Twig_Node|\Twig_NodeInterface
28+
*/
29+
public function work($node, SourceCollection $collection, callable $getAbsoluteFilePath)
30+
{
31+
if (!$node instanceof \Twig_Node_Expression_Filter) {
32+
return $node;
33+
}
34+
35+
$name = $node->getNode('filter')->getAttribute('value');
36+
if ('trans' !== $name && 'transchoice' !== $name) {
37+
return $node;
38+
}
39+
40+
$idNode = $node->getNode('node');
41+
if (!$idNode instanceof \Twig_Node_Expression_Constant) {
42+
// We can only extract constants
43+
return $node;
44+
}
45+
46+
$id = $idNode->getAttribute('value');
47+
$index = 'trans' === $name ? 1 : 2;
48+
$domain = 'messages';
49+
$arguments = $node->getNode('arguments');
50+
if ($arguments->hasNode($index)) {
51+
$argument = $arguments->getNode($index);
52+
if (!$argument instanceof \Twig_Node_Expression_Constant) {
53+
return $node;
54+
}
55+
56+
$domain = $argument->getAttribute('value');
57+
}
58+
59+
$source = new SourceLocation($id, $getAbsoluteFilePath(), $node->getTemplateLine(), ['domain' => $domain]);
60+
$collection->addLocation($source);
61+
62+
return $node;
63+
}
64+
}

0 commit comments

Comments
 (0)