2

I need the 'language_manager' service inside a custom FieldFormatter. I'd prefer not to use \Drupal::service('language_manager').

Is there a special tag for FieldFormatters, or any other method to define it as a service?

4

You don't need to define your FieldFormatter as a service. FieldFormatters are instantiated inside the FormatterPluginManager's createInstance method (FormatterPluginManager::createInstance) which calls a create method on the formatter plugin object, passing a $container object as a parameter.

But this happens only if your FieldFormatter implements the \Drupal\Core\Plugin\ContainerFactoryPluginInterface. From then on, you are able to inject the service inside your FieldFormatter.

  • Wow, that was fast :) I tried it, and it works. Although this solution still means pulling the service from the container instead of injecting it from the outside, it seems to be the way to go atm. Having scanned the code I did not found any possibility to create the field formatter as a service. – jensjensen Jan 6 '17 at 13:46
  • Yes, kind of had it ready in my head :-). I think it's the way to go. It would also feel a bit counter-intuitive to me to define a plugin as a service. They are contrary in nature. – Stefanos Petrakis Jan 6 '17 at 14:01
  • The reason this is better than just calling \Drupal:: is that this is only a fallback. If you want to write a unit test for your class, you can simply ignore create() and directly instantiate the object with mock dependencies. – Berdir Jan 6 '17 at 17:04
1

You can see example CommentDefaultFormatter.php. You need method create and __construct like this:

<?php

namespace Drupal\mymodule\Plugin\Field\FieldFormatter;

use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;


class MymoduleFieldFormatter extends FormatterBase implements ContainerFactoryPluginInterface {

  /**
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static(
      $plugin_id,
      $plugin_definition,
      $configuration['field_definition'],
      $configuration['settings'],
      $configuration['label'],
      $configuration['view_mode'],
      $configuration['third_party_settings'],
      $container->get('language_manager')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, LanguageManagerInterface $language_manager) {
    parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
    $this->languageManager = $language_manager;
  }


}

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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