依賴注入到 Twig 擴充套件中

此示例將向你展示如何使用 Dependency Inject 來使用在 Drupal 環境中註冊的其他服務。

想象一下,你有一個 SVG 影象檔案,根據專案中的一些隨機 CSS / Javascript 事情改變顏色。為了能夠使用 CSS 定位 SVG,你必須在 DOM 中實際擁有 SVG 檔案。因此,你建立一個沒有任何顏色的基本 SVG 檔案,並將其放在主題資料夾中。

當然,你可以將檔案的內容貼上到 Twig 模板中,但這樣做並不好。你可以建立一個 Twig 擴充套件,但你也不想在擴充套件原始碼中對主題路徑進行硬編碼。

這意味著我們必須動態獲取路徑。你有兩個選擇:

  1. 通過呼叫\Drupal::theme()->getActiveTheme()->getPath(); 使用等效於全域性變數
  2. 在擴充套件類中注入 ThemeManager(由\Drupal::theme() 給出)

在本例中,我們將採用第二個示例,因為它可以廣泛應用於任何服務(如果需要,可以匯入請求或資料庫連線)。

這假設你有一個名為 twig_svg_extensiontwig_svg_extension.services.yml 檔案的模組:

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

請不要告訴 Drupal 注入服務的 arguments 金鑰。

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';
  }
}

請注意建構函式,其中包含我們在服務配置中注入的依賴項以及獲取當前活動主題路徑的 svgFilter

$filepath 應該是你的主題資料夾的相對路徑。副檔名將檔案路徑轉換為它指向的檔案的內容。