drupal Injection de dépendance dans les extensions de brindilles


Exemple

Cet exemple vous montre comment utiliser Dependency Inject pour utiliser d'autres services enregistrés dans l'environnement Drupal.

Imaginez que vous ayez un fichier d’image SVG qui change de couleur en fonction d’un objet CSS / Javascript aléatoire dans votre projet. Pour pouvoir cibler le SVG avec CSS, vous devez avoir le fichier SVG dans le DOM. Donc, vous créez un fichier SVG de base sans aucune couleur et placez-le dans votre dossier de thème.

Bien sûr, vous pourriez simplement coller le contenu du fichier dans le modèle Twig, mais ce ne serait pas bien. Vous pouvez créer une extension Twig mais vous ne voulez pas non plus coder en dur votre chemin de thème dans le code source de l'extension.

Cela signifie que nous devons obtenir le chemin dynamiquement. Vous avez deux options:

  1. Utilisez l'équivalent d'une variable globale en appelant \Drupal::theme()->getActiveTheme()->getPath();
  2. Injecter le ThemeManager (donné par \Drupal::theme() ) dans votre classe d'extension

Dans cet exemple, nous prendrons le deuxième exemple car il peut être largement applicable à tout service (vous importez la demande ou la connexion à la base de données si vous le souhaitez).

Cela suppose que vous avez un module appelé twig_svg_extension et un fichier twig_svg_extension.services.yml :

services:
  twig_svg_extension.twig_extension:
    class: Drupal\twig_svg_extension\TwigExtension\TwigSvgExtension
    arguments: ['@theme.manager']
    tags:
      - { name: twig.extension }

S'il vous plaît pas la clé des arguments qui dit à Drupal le service à injecter.

namespace Drupal\twig_svg_Extension\TwigExtension;

use Drupal\Core\Theme\ThemeManager;
use Twig_Extension;
use Twig_SimpleFilter;

class TwigSvgExtension extends Twig_Extension  {
  private $theme;
  
  // Dependency injection at work!
  public function __construct(ThemeManager $theme) {
    $this->theme = $theme;
  }

  public function getFilters() {
    return [
      'svg' =>new Twig_SimpleFilter('svg', [$this, 'svgFilter']),
    ];
  }

  public function getName() {
    return 'twig_svg_extension.twig_extension';
  }

  public function svgFilter(string $filepath) {
    $realpath = realpath($this->theme->getActiveTheme()->getPath().DIRECTORY_SEPARATOR.$filepath);
    $pathinfo = pathinfo($realpath);

    if($realpath !== false && strtolower($pathinfo['extension']) === 'svg') {
      return file_get_contents($realpath);
    }

    return '"'.$filepath.'" does not exist or is not an SVG';
  }
}

Notez le constructeur qui contient la dépendance que nous avons injectée dans la configuration du service, ainsi que le svgFilter qui obtient le chemin du thème actif actuel.

$filepath devrait être un chemin relatif vers votre dossier de thèmes. L'extension convertira le chemin du fichier dans le contenu du fichier vers lequel il pointe.