Twig 将字符串变量渲染为数组

Twig render string variable as array

我们正在使用 twig 渲染引擎,用负载数据填充 json。

或者换句话说:

{
    "payload": {
        "sld": "{{sld}}",
        "tld": "{{tlds}}"
    }
}

我正在循环所有变量并“呈现”值。当一切都是字符串时,它工作完美


{
    "payload": {
        "sld": "test",
        "tld": "com"
    }
}

但是,如果任何 twig 变量是数组,它就会崩溃。 或者换句话说:

{{tlds}} 是数组 === ["com", "net"]

因为是存放在json里,所以没有字符串引号"".

是写不出来的

预期结果应该是:

{
    "payload": {
        "sld": "test",
        "tld": ["com", "net"]
    }
}

你能帮我解决问题吗?

, you should use the built in json_encode 过滤器。
这就是说,这样做只会导致你的 JSON 对象的 HTML 编码版本。为了克服这个问题,您还必须使用 raw 过滤器。

所以有了 Twig 的这一衬里:

{{ data | json_encode() | raw }}

数据如下:

$data = [
  [
    "payload" => [
      "sld" => "test",
      "tld" => "com"
    ]
  ],
  [
    "payload" => [
      "sld" => "test",
      "tld" => [
        "com",
        "net"
      ]
    ]
  ]
];

这将为您提供此 JSON(为了可读性而美化):

[
   {
      "payload":{
         "sld":"test",
         "tld":"com"
      }
   },
   {
      "payload":{
         "sld":"test",
         "tld":[
            "com",
            "net"
         ]
      }
   }
]

所有这些都可以在这里测试:https://twigfiddle.com/i604iv

经过一些测试和集思广益,我决定删除树枝渲染器并将其迁移到更简单的版本。

长话短说,这将呈现所有类似 {{variable.something}} 的语法,并使用有效负载中的相应值填充它。

如果该值是一个数组,它将json对其进行编码,然后对其进行解码,以实现请求的功能。


 private function renderVariables(array $variables = [], array $payload = [])
    {
        $rendered = [];

        foreach ($variables as $key => $value) {
            if (is_array($value)) {
                $rendered[$key] = $this->renderVariables($value, $payload);
            } else {
                $rendered[$key] = $this->replaceMarkdown($value, $payload);

                if (strpos($rendered[$key], '[') !== false || strpos($rendered[$key], '{') !== false) {
                    $rendered[$key] = json_decode($rendered[$key]);
                }
            }
        }
        return $rendered;
    }

    public function replaceMarkdown(string $param, array $argv)
    {
        return preg_replace_callback('/\{\%\s*(.*)\s*\%\}|\{\{(?!%)\s*((?:[^\s])*)\s*(?<!%)\}\}/i',
            function ($field) use ($argv) {
                $field = $field[2];

                if (strpos($field, '.') !== false) {
                    $fields = explode('.', $field);
                } else {
                    $fields = array($field);
                }

                $currentData = $argv; # we should take care for magic before foreach

                foreach ($fields as $currentField) {
                    if (isset($currentData[$currentField])) {
                        $currentData = $currentData[$currentField];
                    } else {
                        return $field . '-not-found';
                    }

                }
                if (is_array($currentData)) {
                    $currentData = json_encode($currentData);
                }
                return (string)$currentData;
            }, $param);
    }