8

我想为Latte 模板引擎创建自己的过滤器。他们的文档中有一个示例,但没有描述如何在演示者中注册它。


$latte = new Latte\Engine;
$latte->addFilter('myFilter', function ($s) {
    return someMagic($s)
});

我敢打赌,会有一种简单的方法可以在演示者中获取 Latte\Engine 的实例,但我不确定如何。

4

4 回答 4

8

过滤器也可以通过注册config.neon

services:
    nette.latteFactory:
        setup:
            - addFilter(abs, @App\Latte\AbsFilter)

    - App\Latte\AbsFilter

过滤器类可能如下所示:

namespace App\Latte;

class AbsFilter extends \Nette\Object
{
    /**
     * @param int $number
     * @return int
     */
    public function __invoke($number)
    {
        return abs($number);
    }
}
于 2016-01-25T14:08:31.290 回答
4

在演示者中,有一个Latte\Engine可用的实例,$this->template所以你要做的就是像这样注册过滤器:

<?php
    abstract class BasePresenter extends Nette\Application\UI\Presenter
    {
        public function beforeRender()
        {
            // register filters
            $this->template->addFilter('myFilter', function ($s) {
                // don't forget to set your own magic
                return someMagic($s);
            });
        }

    }
?>

我发布了一个示例BasePresenter,它是所有其他演示者的父级,但您只能在您想要的演示者中注册它并加快您的应用程序。

于 2014-11-07T22:30:25.787 回答
1

除了@Nortys 的回答。

有时将 Presenter 中的一些数据注入匿名函数是很有用的:

<?php
abstract class BasePresenter extends Nette\Application\UI\Presenter
{
    public function beforeRender()
    {
        $locale = 'en';

        // register filters
        $this->template->addFilter('myFilter', function ($s) use ($locale) {
            // don't forget to set your own magic
            return someMagic($s, $locale);
        });
    }
}
?>
于 2015-12-19T20:37:35.033 回答
0

依赖注入的 Nette 3.0 / 2020 方法

在 control 或 Presenter 中注册过滤器可能会导致忘记过滤器注册。他们应该在一个地方注册一次,以供整个申请。

这种方法易于扩展,1 个新过滤器 = 1 个新类,无需配置,无需接触其他代码。除了这里的其他答案,这一个尊重开闭实体原则。

带有 FilterProvider 的 LatteFactory 服务

首先,我们做一个过滤器提供服务:

interface FilterProviderInterface
{
    public function getName(): string;
}
final class PlusFilterProvider implements FilterProviderInterface
{
    public function __invoke(int $number, int $anotherNumber): int
    {
        return SomeStaticClass::plus($number, $anotherNumber);
    }

    public function getName(): string
    {
        return 'plus';
    }
}
<?php

declare(strict_types=1);

namespace App\Latte;

use Latte\Engine;
use Latte\Runtime\FilterInfo;

final class LatteFactory
{
    /**
     * @var FilterProviderInterface[]
     */
    private array $filterProviders;

    /**
     * @param FilterProviderInterface[] $filterProviders
     */
    public function __construct(array $filterProviders)
    {
        $this->filterProviders = $filterProviders;
    } 

    public function create(): Engine
    {
        $engine = new Engine();

        // register your filters here
        foreach ($this->filterProviders as $filterProvider) {
            $engine->addFilter($filterProvider->getName(), $filterProvider);
        }

        return $engine;
    }
}

如何添加新过滤器?

  • 创建实现您的接口的新类FilterProviderInterface
  • register 在您的配置中作为服务,或者更好地使用搜索扩展自动发现它
  • 就是这样 :)

你想了解更多吗?

我写了更详细的帖子如何从 Latte 过滤器中摆脱魔法、静态和混沌,我在其中解释了替代方案的优缺点以及为什么这个会获胜

于 2020-09-13T16:12:31.677 回答