You are here

protected function TwigNodeTrans::compileString in Drupal 10

Same name and namespace in other branches
  1. 8 core/lib/Drupal/Core/Template/TwigNodeTrans.php \Drupal\Core\Template\TwigNodeTrans::compileString()
  2. 9 core/lib/Drupal/Core/Template/TwigNodeTrans.php \Drupal\Core\Template\TwigNodeTrans::compileString()

Extracts the text and tokens for the "trans" tag.

Parameters

\Twig\Node\Node $body: The node to compile.

Return value

array Returns an array containing the two following parameters:

  • string $text The extracted text.
  • array $tokens The extracted tokens as new \Twig\Node\Expression\TempNameExpression instances.

File

core/lib/Drupal/Core/Template/TwigNodeTrans.php, line 113

Class

TwigNodeTrans
A class that defines the Twig 'trans' tag for Drupal.

Namespace

Drupal\Core\Template

Code

protected function compileString(Node $body) {
  if ($body instanceof NameExpression || $body instanceof ConstantExpression || $body instanceof TempNameExpression) {
    return [
      $body,
      [],
    ];
  }
  $tokens = [];
  if (count($body)) {
    $text = '';
    foreach ($body as $node) {
      if ($node instanceof PrintNode) {
        $n = $node
          ->getNode('expr');
        while ($n instanceof FilterExpression) {
          $n = $n
            ->getNode('node');
        }
        if ($n instanceof CheckToStringNode) {
          $n = $n
            ->getNode('expr');
        }
        $args = $n;

        // Support TwigExtension->renderVar() function in chain.
        if ($args instanceof FunctionExpression) {
          $args = $n
            ->getNode('arguments')
            ->getNode(0);
        }

        // Detect if a token implements one of the filters reserved for
        // modifying the prefix of a token. The default prefix used for
        // translations is "@". This escapes the printed token and makes them
        // safe for templates.
        // @see TwigExtension::getFilters()
        $argPrefix = '@';
        while ($args instanceof FilterExpression) {
          switch ($args
            ->getNode('filter')
            ->getAttribute('value')) {
            case 'placeholder':
              $argPrefix = '%';
              break;
          }
          $args = $args
            ->getNode('node');
        }
        if ($args instanceof CheckToStringNode) {
          $args = $args
            ->getNode('expr');
        }
        if ($args instanceof GetAttrExpression) {
          $argName = [];

          // Reuse the incoming expression.
          $expr = $args;

          // Assemble a valid argument name by walking through the expression.
          $argName[] = $args
            ->getNode('attribute')
            ->getAttribute('value');
          while ($args
            ->hasNode('node')) {
            $args = $args
              ->getNode('node');
            if ($args instanceof NameExpression) {
              $argName[] = $args
                ->getAttribute('name');
            }
            else {
              $argName[] = $args
                ->getNode('attribute')
                ->getAttribute('value');
            }
          }
          $argName = array_reverse($argName);
          $argName = implode('.', $argName);
        }
        else {
          $argName = $n
            ->getAttribute('name');
          if (!is_null($args)) {
            $argName = $args
              ->getAttribute('name');
          }
          $expr = new NameExpression($argName, $n
            ->getTemplateLine());
        }
        $placeholder = sprintf('%s%s', $argPrefix, $argName);
        $text .= $placeholder;
        $expr
          ->setAttribute('placeholder', $placeholder);
        $tokens[] = $expr;
      }
      else {
        $text .= $node
          ->getAttribute('data');
      }
    }
  }
  elseif (!$body
    ->hasAttribute('data')) {
    throw new SyntaxError('{% trans %} tag cannot be empty');
  }
  else {
    $text = $body
      ->getAttribute('data');
  }
  return [
    new Node([
      new ConstantExpression(trim($text), $body
        ->getTemplateLine()),
    ]),
    $tokens,
  ];
}