【问题标题】:How do I add a twig global from a bundle config?如何从捆绑配置中添加全局树枝?
【发布时间】:2022-09-24 00:52:10
【问题描述】:

我希望我的包从其配置中注入一个全局树枝。

class MyBundle extends AbstractBundle
{
    public function build(ContainerBuilder $container): void
    {
        parent::build($container);
        $container->addCompilerPass(new TwigPass());
    }
    public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
    { 
        $theme = $config[\'theme\']; // how to make this a twig global?
        // $twig = $builder->getDefinition(\'twig\'); // NOPE! Twig isn\'t loaded yet.
    }

编译器传递得到树枝,当我的捆绑扩展加载时,它不可用。

class TwigPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if (false === $container->hasDefinition(\'twig\')) {
            return;
        }
        
        $theme = \'theme_from_config\';
        $def = $container->getDefinition(\'twig\');
        $def->addMethodCall(\'addGlobal\', [\'theme\', $theme]);

我缺少某些东西,或者某些东西出了问题。编译器如何通过从扩展中获取配置数据?或者,如果那不是正确的方法,我如何从我的捆绑配置中注入一个全局树枝?

标签: symfony twig


【解决方案1】:

使配置数据可用于传递的方法是将数据作为参数添加到容器中:

class TwigPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container)
    {
        if (false === $container->hasDefinition('twig')) {
            return;
        }
        $theme = $container->getParameter('my.theme');

        $def = $container->getDefinition('twig');
        $def->addMethodCall('addGlobal', ['theme', $theme]);
    }
}
class CeradMyBundle extends AbstractBundle

    public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
    {
        $container->parameters()->set('my.theme', $config['theme']);
    }

要将主题配置值实际放入 $config 数组中,需要创建一个 Configure 类。幸运的是,AbstractBundle 可以通过 configure 方法简化这一点:

# config/packages/cerad_my.yaml
cerad_my:
  theme: theme_from_config_file

class CeradMyBundle extends AbstractBundle

  public function configure(DefinitionConfigurator $definition): void
  {
      $definition->rootNode()
          ->children()
              ->scalarNode('theme')->defaultValue('theme_default')->end()
          ->end()
      ;
  }

在让它工作之后,拥有一个额外的 DI 类(即 TwigPass)有点烦人,所以我从内核中偷了一个技巧,只是让 AbstractBundle 实现了 pass 接口:

class CeradMyBundle extends AbstractBundle implements CompilerPassInterface
{
  public function build(ContainerBuilder $container): void
  {
      // Register as a pass
      $container->addCompilerPass($this);
  }
  public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void
  {
    $container->parameters()
      ->set('my.theme', $config['theme']);
  }
  public function configure(DefinitionConfigurator $definition): void
  {
      $definition->rootNode()
          ->children()
              ->scalarNode('theme')->defaultValue('theme_default')->end()
          ->end()
      ;
  }
  // The compiler pass
  public function process(ContainerBuilder $container)
  {
      if (false === $container->hasDefinition('twig')) {
          return;
      }
      $theme = $container->getParameter('my.theme');
      $def = $container->getDefinition('twig');
      $def->addMethodCall('addGlobal', ['theme', $theme]);
  }
}

如果您遵循这种方法,那么您实际上可以将您的主题保存为您的包类中的一个属性,而无需添加公共参数。你的选择。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-20
    • 1970-01-01
    • 2018-05-14
    • 1970-01-01
    相关资源
    最近更新 更多