mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-14 19:36:43 +00:00
Merge branch '3.x' into 4.x
* 3.x: Escaper performance: avoid static variables Fix compatibility with Symfony 8 Add documentation for use_yield option Stof suggestion about empty content Update templates.rst: Removing duplication Update configuration keys + allow extra keys for extensions replace typographic quote with straigt single quote Add TwigCsFixer in tools list Update reduce.rst Bump version Prepare the 3.21.1 release Update CHANGELOG Fix warning Fix instantiation
This commit is contained in:
+11
@@ -143,6 +143,17 @@ The following options are available:
|
||||
(default to ``-1`` -- all optimizations are enabled; set it to ``0`` to
|
||||
disable).
|
||||
|
||||
* ``use_yield`` *boolean*
|
||||
|
||||
``true``: forces templates to exclusively use ``yield`` instead of ``echo``
|
||||
(all extensions must be yield ready)
|
||||
|
||||
``false`` (default): allows templates to use a mix of ``yield`` and ``echo``
|
||||
calls to allow for a progressive migration.
|
||||
|
||||
Switch to ``true`` when possible as this will be the only supported mode in
|
||||
Twig 4.0.
|
||||
|
||||
Loaders
|
||||
-------
|
||||
|
||||
|
||||
@@ -11,12 +11,13 @@ When writing Twig templates, we recommend you to follow these official coding
|
||||
standards:
|
||||
|
||||
* Put exactly one space after the start of a delimiter (``{{``, ``{%``,
|
||||
and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``):
|
||||
and ``{#``) and before the end of a delimiter (``}}``, ``%}``, and ``#}``)
|
||||
if the content is non empty:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{{ user }}
|
||||
{# comment #}
|
||||
{# comment #} {##}
|
||||
{% if user %}{% endif %}
|
||||
|
||||
When using the whitespace control character, do not put any spaces between
|
||||
@@ -25,7 +26,7 @@ standards:
|
||||
.. code-block:: twig
|
||||
|
||||
{{- user -}}
|
||||
{#- comment -#}
|
||||
{#- comment -#} {#--#}
|
||||
{%- if user -%}{%- endif -%}
|
||||
|
||||
* Put exactly one space before and after the following operators:
|
||||
|
||||
@@ -10,14 +10,14 @@ value and key of the sequence or mapping:
|
||||
|
||||
{% set numbers = [1, 2, 3] %}
|
||||
|
||||
{{ numbers|reduce((carry, v, k) => carry + v * k) }}
|
||||
{{ numbers|reduce((carry, value, key) => carry + value * key) }}
|
||||
{# output 8 #}
|
||||
|
||||
The ``reduce`` filter takes an ``initial`` value as a second argument:
|
||||
|
||||
.. code-block:: twig
|
||||
|
||||
{{ numbers|reduce((carry, v, k) => carry + v * k, 10) }}
|
||||
{{ numbers|reduce((carry, value, key) => carry + value * key, 10) }}
|
||||
{# output 18 #}
|
||||
|
||||
Note that the arrow function has access to the current context.
|
||||
@@ -27,9 +27,3 @@ Arguments
|
||||
|
||||
* ``arrow``: The arrow function
|
||||
* ``initial``: The initial value
|
||||
|
||||
.. note::
|
||||
|
||||
Internally, Twig uses the PHP `array_reduce`_ function.
|
||||
|
||||
.. _`array_reduce`: https://www.php.net/array_reduce
|
||||
|
||||
@@ -9,7 +9,7 @@ Converts an argument to a date to allow date comparison:
|
||||
{# do something #}
|
||||
{% endif %}
|
||||
|
||||
The argument must be in one of PHP’s supported `date and time formats`_.
|
||||
The argument must be in one of PHP's supported `date and time formats`_.
|
||||
|
||||
You can pass a timezone as the second argument:
|
||||
|
||||
|
||||
+2
-5
@@ -68,11 +68,10 @@ Many IDEs support syntax highlighting and auto-completion for Twig:
|
||||
|
||||
You might also be interested in:
|
||||
|
||||
* `Twig CS Fixer`_: a tool to check/fix your templates code style
|
||||
* `Twig Language Server`_: provides some language features like syntax
|
||||
highlighting, diagnostics, auto complete, ...
|
||||
|
||||
* `TwigQI`_: an extension which analyzes your templates for common bugs during compilation
|
||||
|
||||
* `TwigStan`_: a static analyzer for Twig templates powered by PHPStan
|
||||
|
||||
Variables
|
||||
@@ -858,9 +857,6 @@ The following operators don't fit into any of the other categories:
|
||||
|
||||
{{ user.name }}
|
||||
|
||||
Twig supports a specific syntax via the ``[]`` operator for accessing items
|
||||
on sequences and mappings, like in ``user['name']``:
|
||||
|
||||
After the ``.``, you can use any expression by wrapping it with parenthesis
|
||||
``()``.
|
||||
|
||||
@@ -1077,6 +1073,7 @@ Twig can be extended. If you want to create your own extensions, read the
|
||||
.. _`TwigStan`: https://github.com/twigstan/twigstan
|
||||
.. _`Twig pack`: https://marketplace.visualstudio.com/items?itemName=bajdzis.vscode-twig-pack
|
||||
.. _`Modern Twig`: https://marketplace.visualstudio.com/items?itemName=Stanislav.vscode-twig
|
||||
.. _`Twig CS Fixer`: https://github.com/VincentLanglet/Twig-CS-Fixer
|
||||
.. _`Twig Language Server`: https://github.com/kaermorchen/twig-language-server/tree/master/packages/language-server
|
||||
.. _`Twiggy`: https://marketplace.visualstudio.com/items?itemName=moetelo.twiggy
|
||||
.. _`PHP spaceship operator documentation`: https://www.php.net/manual/en/language.operators.comparison.php
|
||||
|
||||
+8
-7
@@ -19,13 +19,14 @@ class MissingExtensionSuggestorPass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container): void
|
||||
{
|
||||
if ($container->getParameter('kernel.debug')) {
|
||||
$twigDefinition = $container->getDefinition('twig');
|
||||
$twigDefinition
|
||||
->addMethodCall('registerUndefinedFilterCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestFilter']])
|
||||
->addMethodCall('registerUndefinedFunctionCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestFunction']])
|
||||
->addMethodCall('registerUndefinedTokenParserCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestTag']])
|
||||
;
|
||||
if (!$container->getParameter('kernel.debug')) {
|
||||
return;
|
||||
}
|
||||
$twigDefinition = $container->getDefinition('twig');
|
||||
$twigDefinition
|
||||
->addMethodCall('registerUndefinedFilterCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestFilter']])
|
||||
->addMethodCall('registerUndefinedFunctionCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestFunction']])
|
||||
->addMethodCall('registerUndefinedTokenParserCallback', [[new Reference('twig.missing_extension_suggestor'), 'suggestTag']])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,14 +39,14 @@ class Configuration implements ConfigurationInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Full configuration from {@link https://commonmark.thephpleague.com/2.3/configuration}.
|
||||
* Full configuration from {@link https://commonmark.thephpleague.com/2.7/configuration}.
|
||||
*/
|
||||
private function addCommonMarkConfiguration(ArrayNodeDefinition $rootNode): void
|
||||
{
|
||||
$rootNode
|
||||
->children()
|
||||
->arrayNode('commonmark')
|
||||
->ignoreExtraKeys()
|
||||
->ignoreExtraKeys(false)
|
||||
->children()
|
||||
->arrayNode('renderer')
|
||||
->info('Array of options for rendering HTML.')
|
||||
@@ -68,6 +68,10 @@ class Configuration implements ConfigurationInterface
|
||||
->info('The maximum nesting level for blocks.')
|
||||
->defaultValue(\PHP_INT_MAX)
|
||||
->end()
|
||||
->integerNode('max_delimiters_per_line')
|
||||
->info('The maximum number of strong/emphasis delimiters per line.')
|
||||
->defaultValue(\PHP_INT_MAX)
|
||||
->end()
|
||||
->arrayNode('slug_normalizer')
|
||||
->info('Array of options for configuring how URL-safe slugs are created.')
|
||||
->children()
|
||||
|
||||
@@ -140,6 +140,10 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
case 'html':
|
||||
// see https://www.php.net/htmlspecialchars
|
||||
|
||||
if ('UTF-8' === $charset) {
|
||||
return htmlspecialchars($string, \ENT_QUOTES | \ENT_SUBSTITUTE, 'UTF-8');
|
||||
}
|
||||
|
||||
// Using a static variable to avoid initializing the array
|
||||
// each time the function is called. Moving the declaration on the
|
||||
// top of the function slow downs other escaping strategies.
|
||||
@@ -195,7 +199,7 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
* Escape sequences supported only by JavaScript, not JSON, are omitted.
|
||||
* \" is also supported but omitted, because the resulting string is not HTML safe.
|
||||
*/
|
||||
static $shortMap = [
|
||||
$short = match ($char) {
|
||||
'\\' => '\\\\',
|
||||
'/' => '\\/',
|
||||
"\x08" => '\b',
|
||||
@@ -203,10 +207,11 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
"\x0A" => '\n',
|
||||
"\x0D" => '\r',
|
||||
"\x09" => '\t',
|
||||
];
|
||||
default => false,
|
||||
};
|
||||
|
||||
if (isset($shortMap[$char])) {
|
||||
return $shortMap[$char];
|
||||
if ($short) {
|
||||
return $short;
|
||||
}
|
||||
|
||||
$codepoint = mb_ord($char, 'UTF-8');
|
||||
@@ -288,18 +293,13 @@ final class EscaperRuntime implements RuntimeExtensionInterface
|
||||
* entities that XML supports. Using HTML entities would result in this error:
|
||||
* XML Parsing Error: undefined entity
|
||||
*/
|
||||
static $entityMap = [
|
||||
return match ($ord) {
|
||||
34 => '"', /* quotation mark */
|
||||
38 => '&', /* ampersand */
|
||||
60 => '<', /* less-than sign */
|
||||
62 => '>', /* greater-than sign */
|
||||
];
|
||||
|
||||
if (isset($entityMap[$ord])) {
|
||||
return $entityMap[$ord];
|
||||
}
|
||||
|
||||
return \sprintf('&#x%02X;', $ord);
|
||||
default => \sprintf('&#x%02X;', $ord),
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user