我想为Latte 模板引擎创建自己的过滤器。他们的文档中有一个示例,但没有描述如何在演示者中注册它。
$latte = new Latte\Engine;
$latte->addFilter('myFilter', function ($s) {
return someMagic($s)
});
我敢打赌,会有一种简单的方法可以在演示者中获取 Latte\Engine 的实例,但我不确定如何。
我想为Latte 模板引擎创建自己的过滤器。他们的文档中有一个示例,但没有描述如何在演示者中注册它。
$latte = new Latte\Engine;
$latte->addFilter('myFilter', function ($s) {
return someMagic($s)
});
我敢打赌,会有一种简单的方法可以在演示者中获取 Latte\Engine 的实例,但我不确定如何。
过滤器也可以通过注册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);
}
}
在演示者中,有一个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,它是所有其他演示者的父级,但您只能在您想要的演示者中注册它并加快您的应用程序。
除了@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);
});
}
}
?>
在 control 或 Presenter 中注册过滤器可能会导致忘记过滤器注册。他们应该在一个地方注册一次,以供整个申请。
这种方法易于扩展,1 个新过滤器 = 1 个新类,无需配置,无需接触其他代码。除了这里的其他答案,这一个尊重开闭实体原则。
首先,我们做一个过滤器提供服务:
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我写了更详细的帖子如何从 Latte 过滤器中摆脱魔法、静态和混沌,我在其中解释了替代方案的优缺点以及为什么这个会获胜。