Skip to content
Permalink
Browse files

minor #33039 [TwigBridge] Support for Twig 3 (derrabus)

This PR was squashed before being merged into the 5.0-dev branch (closes #33039).

Discussion
----------

[TwigBridge] Support for Twig 3

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| BC breaks?    | yes
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | N/A
| License       | MIT
| Doc PR        | N/A

I occasionally test my projects against dev branches of the libraries I use. It's probably a bit early for this PR, but since I had to patch Symfony anyway in order to test Twig 3 in my projects, I though I might as well share the branch with you.

BC break: I had to add return types to several non-final classes of the Twig bridge. This will break applications that override these classes without adding the return types.

This PR is marked as a draft because Twig 3 is still a moving target.

Commits
-------

44ed90c Finalized all `@Final` classes.
f30edca Support for Twig 3.
  • Loading branch information...
fabpot committed Aug 21, 2019
2 parents 117acc3 + 44ed90c commit 4fc050491554dc7027ff19a3cd3fb3aff64aedb1
Showing with 141 additions and 438 deletions.
  1. +1 −1 composer.json
  2. +4 −22 src/Symfony/Bridge/Twig/Extension/AssetExtension.php
  3. +11 −33 src/Symfony/Bridge/Twig/Extension/CodeExtension.php
  4. +1 −3 src/Symfony/Bridge/Twig/Extension/CsrfExtension.php
  5. +1 −3 src/Symfony/Bridge/Twig/Extension/CsrfRuntime.php
  6. +6 −14 src/Symfony/Bridge/Twig/Extension/DumpExtension.php
  7. +3 −17 src/Symfony/Bridge/Twig/Extension/ExpressionExtension.php
  8. +7 −28 src/Symfony/Bridge/Twig/Extension/FormExtension.php
  9. +4 −22 src/Symfony/Bridge/Twig/Extension/HttpFoundationExtension.php
  10. +4 −14 src/Symfony/Bridge/Twig/Extension/HttpKernelExtension.php
  11. +3 −9 src/Symfony/Bridge/Twig/Extension/HttpKernelRuntime.php
  12. +4 −20 src/Symfony/Bridge/Twig/Extension/LogoutUrlExtension.php
  13. +3 −13 src/Symfony/Bridge/Twig/Extension/ProfilerExtension.php
  14. +4 −24 src/Symfony/Bridge/Twig/Extension/RoutingExtension.php
  15. +3 −15 src/Symfony/Bridge/Twig/Extension/SecurityExtension.php
  16. +3 −10 src/Symfony/Bridge/Twig/Extension/StopwatchExtension.php
  17. +3 −20 src/Symfony/Bridge/Twig/Extension/TranslationExtension.php
  18. +8 −12 src/Symfony/Bridge/Twig/Extension/WebLinkExtension.php
  19. +7 −18 src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php
  20. +4 −17 src/Symfony/Bridge/Twig/Extension/YamlExtension.php
  21. +3 −5 src/Symfony/Bridge/Twig/Node/DumpNode.php
  22. +2 −4 src/Symfony/Bridge/Twig/Node/FormThemeNode.php
  23. +2 −4 src/Symfony/Bridge/Twig/Node/RenderBlockNode.php
  24. +2 −4 src/Symfony/Bridge/Twig/Node/SearchAndRenderBlockNode.php
  25. +2 −4 src/Symfony/Bridge/Twig/Node/StopwatchNode.php
  26. +2 −4 src/Symfony/Bridge/Twig/Node/TransDefaultDomainNode.php
  27. +3 −8 src/Symfony/Bridge/Twig/Node/TransNode.php
  28. +5 −11 src/Symfony/Bridge/Twig/NodeVisitor/TranslationDefaultDomainNodeVisitor.php
  29. +7 −13 src/Symfony/Bridge/Twig/NodeVisitor/TranslationNodeVisitor.php
  30. +3 −8 src/Symfony/Bridge/Twig/Tests/Extension/CodeExtensionTest.php
  31. +3 −9 src/Symfony/Bridge/Twig/TokenParser/DumpTokenParser.php
  32. +5 −11 src/Symfony/Bridge/Twig/TokenParser/FormThemeTokenParser.php
  33. +4 −12 src/Symfony/Bridge/Twig/TokenParser/StopwatchTokenParser.php
  34. +3 −9 src/Symfony/Bridge/Twig/TokenParser/TransDefaultDomainTokenParser.php
  35. +4 −10 src/Symfony/Bridge/Twig/TokenParser/TransTokenParser.php
  36. +1 −1 src/Symfony/Bridge/Twig/composer.json
  37. +1 −1 src/Symfony/Bundle/FrameworkBundle/composer.json
  38. +1 −1 src/Symfony/Bundle/SecurityBundle/composer.json
  39. +1 −1 src/Symfony/Bundle/TwigBundle/composer.json
  40. +1 −1 src/Symfony/Bundle/WebProfilerBundle/composer.json
  41. +1 −1 src/Symfony/Component/HttpKernel/composer.json
  42. +1 −1 src/Symfony/Component/VarDumper/composer.json
@@ -20,7 +20,7 @@
"ext-xml": "*",
"doctrine/event-manager": "~1.0",
"doctrine/persistence": "~1.0",
"twig/twig": "^2.10",
"twig/twig": "^2.10|^3",
"psr/cache": "~1.0",
"psr/container": "^1.0",
"psr/link": "^1.0",
@@ -19,10 +19,8 @@
* Twig extension for the Symfony Asset component.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.4
*/
class AssetExtension extends AbstractExtension
final class AssetExtension extends AbstractExtension
{
private $packages;
@@ -33,10 +31,8 @@ public function __construct(Packages $packages)
/**
* {@inheritdoc}
*
* @return TwigFunction[]
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction('asset', [$this, 'getAssetUrl']),
@@ -49,31 +45,17 @@ public function getFunctions()
*
* If the package used to generate the path is an instance of
* UrlPackage, you will always get a URL and not a path.
*
* @return string The public path of the asset
*/
public function getAssetUrl(string $path, string $packageName = null)
public function getAssetUrl(string $path, string $packageName = null): string
{
return $this->packages->getUrl($path, $packageName);
}
/**
* Returns the version of an asset.
*
* @return string The asset version
*/
public function getAssetVersion(string $path, string $packageName = null)
public function getAssetVersion(string $path, string $packageName = null): string
{
return $this->packages->getVersion($path, $packageName);
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'asset';
}
}
@@ -19,19 +19,15 @@
* Twig extension relate to PHP code and used by the profiler and the default exception templates.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.4
*/
class CodeExtension extends AbstractExtension
final class CodeExtension extends AbstractExtension
{
private $fileLinkFormat;
private $charset;
private $projectDir;
/**
* @param string|FileLinkFormatter $fileLinkFormat The format for links to source files
* @param string $projectDir The project directory
* @param string $charset The charset
*/
public function __construct($fileLinkFormat, string $projectDir, string $charset)
{
@@ -42,10 +38,8 @@ public function __construct($fileLinkFormat, string $projectDir, string $charset
/**
* {@inheritdoc}
*
* @return TwigFilter[]
*/
public function getFilters()
public function getFilters(): array
{
return [
new TwigFilter('abbr_class', [$this, 'abbrClass'], ['is_safe' => ['html']]),
@@ -61,15 +55,15 @@ public function getFilters()
];
}
public function abbrClass(string $class)
public function abbrClass(string $class): string
{
$parts = explode('\\', $class);
$short = array_pop($parts);
return sprintf('<abbr title="%s">%s</abbr>', $class, $short);
}
public function abbrMethod(string $method)
public function abbrMethod(string $method): string
{
if (false !== strpos($method, '::')) {
list($class, $method) = explode('::', $method, 2);
@@ -85,10 +79,8 @@ public function abbrMethod(string $method)
/**
* Formats an array as a string.
*
* @return string
*/
public function formatArgs(array $args)
public function formatArgs(array $args): string
{
$result = [];
foreach ($args as $key => $item) {
@@ -116,20 +108,16 @@ public function formatArgs(array $args)
/**
* Formats an array as a string.
*
* @return string
*/
public function formatArgsAsText(array $args)
public function formatArgsAsText(array $args): string
{
return strip_tags($this->formatArgs($args));
}
/**
* Returns an excerpt of a code file around the given line number.
*
* @return string An HTML string
*/
public function fileExcerpt(string $file, int $line, int $srcContext = 3)
public function fileExcerpt(string $file, int $line, int $srcContext = 3): ?string
{
if (is_file($file) && is_readable($file)) {
// highlight_file could throw warnings
@@ -160,10 +148,8 @@ public function fileExcerpt(string $file, int $line, int $srcContext = 3)
/**
* Formats a file path.
*
* @return string
*/
public function formatFile(string $file, int $line, string $text = null)
public function formatFile(string $file, int $line, string $text = null): string
{
$file = trim($file);
@@ -211,7 +197,7 @@ public function getFileRelative(string $file): ?string
return null;
}
public function formatFileFromText(string $text)
public function formatFileFromText(string $text): string
{
return preg_replace_callback('/in ("|&quot;)?(.+?)\1(?: +(?:on|at))? +line (\d+)/s', function ($match) {
return 'in '.$this->formatFile($match[2], $match[3]);
@@ -221,7 +207,7 @@ public function formatFileFromText(string $text)
/**
* @internal
*/
public function formatLogMessage(string $message, array $context)
public function formatLogMessage(string $message, array $context): string
{
if ($context && false !== strpos($message, '{')) {
$replacements = [];
@@ -239,15 +225,7 @@ public function formatLogMessage(string $message, array $context)
return htmlspecialchars($message, ENT_COMPAT | ENT_SUBSTITUTE, $this->charset);
}
/**
* {@inheritdoc}
*/
public function getName()
{
return 'code';
}
protected static function fixCodeMarkup(string $line)
protected static function fixCodeMarkup(string $line): string
{
// </span> ending tag from previous line
$opening = strpos($line, '<span');
@@ -17,10 +17,8 @@
/**
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
* @author Titouan Galopin <galopintitouan@gmail.com>
*
* @final since Symfony 4.4
*/
class CsrfExtension extends AbstractExtension
final class CsrfExtension extends AbstractExtension
{
/**
* {@inheritdoc}
@@ -16,10 +16,8 @@
/**
* @author Christian Flothmann <christian.flothmann@sensiolabs.de>
* @author Titouan Galopin <galopintitouan@gmail.com>
*
* @final since Symfony 4.4
*/
class CsrfRuntime
final class CsrfRuntime
{
private $csrfTokenManager;
@@ -17,17 +17,14 @@
use Twig\Environment;
use Twig\Extension\AbstractExtension;
use Twig\Template;
use Twig\TokenParser\TokenParserInterface;
use Twig\TwigFunction;
/**
* Provides integration of the dump() function with Twig.
*
* @author Nicolas Grekas <p@tchwork.com>
*
* @final since Symfony 4.4
*/
class DumpExtension extends AbstractExtension
final class DumpExtension extends AbstractExtension
{
private $cloner;
private $dumper;
@@ -39,29 +36,24 @@ public function __construct(ClonerInterface $cloner, HtmlDumper $dumper = null)
}
/**
* @return TwigFunction[]
* {@inheritdoc}
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction('dump', [$this, 'dump'], ['is_safe' => ['html'], 'needs_context' => true, 'needs_environment' => true]),
];
}
/**
* @return TokenParserInterface[]
* {@inheritdoc}
*/
public function getTokenParsers()
public function getTokenParsers(): array
{
return [new DumpTokenParser()];
}
public function getName()
{
return 'dump';
}
public function dump(Environment $env, array $context)
public function dump(Environment $env, array $context): ?string
{
if (!$env->isDebug()) {
return null;
@@ -19,35 +19,21 @@
* ExpressionExtension gives a way to create Expressions from a template.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @final since Symfony 4.4
*/
class ExpressionExtension extends AbstractExtension
final class ExpressionExtension extends AbstractExtension
{
/**
* {@inheritdoc}
*
* @return TwigFunction[]
*/
public function getFunctions()
public function getFunctions(): array
{
return [
new TwigFunction('expression', [$this, 'createExpression']),
];
}
public function createExpression(string $expression)
public function createExpression(string $expression): Expression
{
return new Expression($expression);
}
/**
* Returns the name of the extension.
*
* @return string The extension name
*/
public function getName()
{
return 'expression';
}
}

0 comments on commit 4fc0504

Please sign in to comment.
You can’t perform that action at this time.