1

Updating the emulsify_twig extension for D10, for some reason the class arguments aren't being passed... I'm extending Drupal\Core\Template\TwigExtension and using the same default arguments but for some reason it isn't picking up the arguments, resulting in: ArgumentCountError: Too few arguments to function Drupal\emulsify_twig\BemTwigExtension::__construct(), 0

This is the relevant code from the class:

use Drupal\Core\Template\TwigExtension;
use Drupal\Core\Routing\UrlGeneratorInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\Core\Theme\ThemeManagerInterface;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\File\FileUrlGeneratorInterface;

class BemTwigExtension extends TwigExtension {
  protected $urlGenerator;  
  protected $renderer;  
  protected $themeManager;  
  protected $dateFormatter;  
  protected $fileUrlGenerator;

  public function __construct(RendererInterface $renderer, UrlGeneratorInterface $url_generator, ThemeManagerInterface $theme_manager, DateFormatterInterface $date_formatter, FileUrlGeneratorInterface $file_url_generator = NULL) {
    parent::__construct(
      $renderer,
      $url_generator,
      $theme_manager,
      $date_formatter,
      $file_url_generator
    );
    
    $this->renderer = $renderer;
    $this->urlGenerator = $url_generator;
    $this->themeManager = $theme_manager;
    $this->dateFormatter = $date_formatter;
    $this->fileUrlGenerator = $file_url_generator;
  }

Any insight as to why the arguments aren't being passed would be appreciated!

1
  • 2
    We would have to see the code that is instantiating the object. Is this a a service? Can we see the service definition please?
    – mona lisa
    Commented Dec 11, 2022 at 17:34

1 Answer 1

4

The error message states that no arguments are being passed to the Twig filter extension. Drupal Twig filter extensions must be defined in [MODULE].services.yml, and in that service definition, the services to be injected as dependencies are defined. These are the arguments that BemTwigExtension::__construct is expecting, but not finding.

You could do something like the followingin emulsify_twig.services.yml:

services:
  emulsify_twig.bem_twig_extension:
    class: Drupal\emulsify_twig\TwigExtension\BemTwigExtension
    tags:
      - { name: twig.extension }
    arguments:
      - '@renderer'
      - '@url_generator'
      ...

Entering all the dependencies using their service definition names.

However, in the original post, as __construct is passing the arguments to the parent, the parent service definition can be referenced to determine which arguments it expects. In the original ploblem TwigExtension is being extended, and the TwigExtension API page lists one service as using it: twig.extension. Viewing the source on twig.extension API page shows the services expected by the parent class (the arguments):

class: Drupal\Core\Template\TwigExtension
arguments:
  - '@renderer'
  - '@url_generator'
  - '@theme.manager'
  - '@date.formatter'
  - '@file_url_generator'
tags:
  - { name: twig.extension, priority: 100 }

Then, instead of redefining all these arguments in the extended service definition, the parent can be set, using its arguments and tags as a base. So, back to emulsify_twig.services.yml the service would be defined as follows:

services:
  emulsify_twig.bem_twig_extension:
    class: Drupal\emulsify_twig\TwigExtension\BemTwigExtension
    parent: twig.extension
    arguments:
      - '@additional_class.1'
      ...

Where @additional_class.1 is the name of any additional services that the extended class will use, that the parent does not. Note that if the extended class does not require any additional services, the __construct() method does not need to be implemented in the extended class at all, as the parent implementation will be used when not defined in the child class. However, the service will still need to be defined in emulsify_twig.services.yml with the parent set as twig.extension.

3
  • Setting the parent key in services was the missing piece... and removing the constructor cuts the amount of code in half - thanks!
    – adam_bear
    Commented Dec 11, 2022 at 21:39
  • You also don't need to declare the protected properties, as the parent defines them as well.
    – Jaypan
    Commented Dec 12, 2022 at 1:22
  • 1
    Yep- the only lines I kept were the class declaration & use TwigExtension, then added parent in services... thanks again!
    – adam_bear
    Commented Dec 12, 2022 at 2:49

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.