4

我正在尝试在Twig中编写模板。在其中,我希望它对来自控制器的字符串数据执行一些操作。特别是,我想将一个常见的操作(从转换underscore_case为)引入一个单独的函数。CamelCase然后以后我可以像{% set x = magic(a) ~ magic(b) %}. 但是我找不到如何在模板本身内创建这样一个可重用的函数。有宏,但那些似乎无法返回值。过滤器是另一个似乎符合要求的选项,但我只能在 PHP 端定义它们。

这可以做到吗?还是我应该在控制器端进行所有高级字符串操作?感觉就像我在里面拉了部分显示逻辑;应该在视图中的东西。

4

3 回答 3

6

Twig 用于输出数据。如果您需要在将数据发送到 twig 之前“转换”数据,或者您需要扩展 twig

理想情况下,您发送给 twig 的所有数据只是变量和数组,它们本身需要最少的操作。

当您实际上在“twig”中时,可以假定数据处理已“完成”,并且只需要以最少的逻辑将其输出到适当的位置即可决定用户界面样式。

因此,在将数据发送到 twig 之前,请重新审视您的逻辑并更好地准备数据。

一个扩展工具包类的示例,该类包含我们的魔法方法来做真正的魔法。

class CustomToolkit 
{
    public function magic_a($a) 
    {
        return strtolower($a);    }

    public function magic_b($b) 
    {
        return camel_case($b);
    }

    public function magic_tidle($a, $b) 
    {
        return $this->magic_a($a) ~ $this->magic_b($b);
    }
}

然后你把它添加到你的树枝实例中。我在这里添加了一个完整的实例化循环。如果您有服务提供商,您可以从那里获取实例并将其添加到该实例中。

$twig = new Twig_Environment(new Twig_Loader_Array([
                                                      'html' => $contents
                                                   ]),[
                                                      'auto_reload' => true,
                                                      'debug' => false,
                                                   ]);
$twig->addExtension('toolkit', new CustomToolkit ());
echo $twig->render('html', $values);

然后在你的树枝代码中,你应该能够按照以下方式做一些事情

{% set x = toolkit.magic_tidle("value","value_b") %} 
于 2018-09-12T13:29:03.430 回答
3

你是对的,宏没有返回值,你不能真正让它们有任何返回值。他们所做的只是输出字符串。

尽管如此,您仍然可以使用以下方法捕获字符串输出sethttps
://twig.symfony.com/doc/2.x/tags/set.html 语法类似于以下内容:

{% set var %}
    {{ call.macro() }}
{% endset %}

然后将宏调用的输出存储在var. 你可能想去掉空格。

但是,请考虑重新考虑您在做什么。这仍然是表示逻辑,还是您的控制器只是“太懒”而无法在将字符串传递给树枝之前对其进行转换?如果它真的是表示逻辑,那么简单地通过扩展 twig 添加一个 twig 过滤器肯定是值得的。不仅因为您的代码变得可测试。

于 2018-09-12T13:31:02.400 回答
1

这可以做到吗?

是的!但是,Twig 模板并不是运行逻辑的理想场所。至少,我们应该尽力避免它。相反,Controller 应该返回 Twig 模板需要的内容。逻辑应该在 Service、Utility、Helper(你给它命名)等中运行,并且 Controller 将其返回给 Twig。Twig 然后只是显示它。

树枝宏可以返回值吗?

是的!看看这个例子。它接受参数并返回(不是真正的“返回”东西,但你明白了)一些东西。

例子:

假设您尝试操作的数据很简单。

use Doctrine\Common\Inflector\Inflector;

Controller
{
   action() {
      $data = Inflector::camelize('hello_world'); // This will become helloWorld

      return ....;
   }
}

查看 Inflector 类。它有有用的东西。

于 2018-09-12T13:27:33.337 回答