3

I am trying to dynamically assign variables in Twig inside a loop. For example, this is the JSON being passed into the template:

[{
   "name": "firstName",
   "value": "Adam",
 },
 {
   "name": "Lastname",
   "value": "Human",
 }]

It's worth noting, I do not have the ability to modify this JSON formatting, as it's coming from a third party, so I need to solve this problem on the template side.

I want to loop through this json and create variables for each object, like so:

{% for item in json %}
    {% set {{item.name}} = item.value %}
{% endfor %}

The challenge is Twig is assumes I'm assigning a value to a literal, when I want to assign the value to a evaluated variable name. This way I can just reference each item in the array like {{firstName}} and get back "Adam" in the template.

I've tried a number of different ways to force Twig to dynamically create a variable array, such as:

{% set (item.name) = item.value %}

and

{% set options = {} %}
{% for item in json %}
    {% set options[item.name] = item.value %}
{% endfor %}

With no luck.

Any ideas on dynamically creating variables? This is straight forward in most programming languages, so I'm struggling to understand how this is handled in a template engine like Twig.

AdamPat
  • 101
  • 1
  • 10
  • 3
    Please, do it in a controller. – u_mulder Jun 07 '17 at 16:43
  • You should have your data ready when sent to a view. – nerdlyist Jun 07 '17 at 16:48
  • @nerdlyist This is not an option. The JSON is passed to me by a third party which I do not have control over. Hence the question. – AdamPat Jun 07 '17 at 16:52
  • 2
    That doesn't really exclude you from manipulating it before sending it to twig, unless your only allowed access to the template files.. – Jenne Jun 07 '17 at 17:22
  • @JennevanderMeer we use Twig for dynamic scripting in our email sending provider. So there's no controller between the API call and the template. – AdamPat Jun 07 '17 at 18:24
  • @AdamPat you could put one between them? Twig is not meant for dynamic scripting it is meant for templating. – nerdlyist Jun 07 '17 at 19:20
  • @nerdlyist I understand the ideology, but it doesn't solve my problem. I'm not in control of the application, I only have access to the template side. If there was another option I wouldn't have posted a question here. – AdamPat Jun 07 '17 at 20:48

1 Answers1

4

If the values are actually iterateable and not a single json string you can put them in an array like:

{% set values = [] %}
{% for item in json %}
    {% set values = values|merge({(item.name): item.value}) %}
{% endfor %}

Then you can use values.firstName.

If it is a json string and thus can't be looped through like this. You need to write a basic string parser in twig. I've written something similar like that last week in this answer however. Its a very bad idea in general as it fails on so many occasions.

Jenne
  • 864
  • 5
  • 11
  • Thanks, I'll give it a shot. I was trying something similar, but it was by initializing an empty object `{}` rather than an array `[]`. I'll let you know if it works! – AdamPat Jun 07 '17 at 20:49