41

I have this in PHP:

$units = array();
foreach ($popPorts as $port) {
$units[$port->getFrameNo()][$port->getSlotNo()][$port->getPortNo()] = $port->getPortNo();
}

How can I achieve the same in twig?

I have tried this so far:

{% set frames = [] %}
{% for row in object.popPorts %}
    {% set frames[row.frameNo][row.slotNo][row.portNo] = row.portNo %}
{% endfor %}
{{ dump(frames) }}

But then I get an error:

Unexpected token "punctuation" of value "[" ("end of statement block" expected).

The output should be like this:

array (size=3)
  (frame) 1 => 
    array (size=2)
      (slot) 1 =>
        array (size=4)
          0 => (port) 26
          1 => (port) 27
          2 => (port) 28
          3 => (port) 29
      (slot) 5 =>
        array (size=2)
          0 => (port) 31
          1 => (port) 34
  (frame) 2 => 
    array (size=1)
      (slot) 3 =>
        array (size=1)
          0 => (port) 32
  (frame) 3 => 
    array (size=1)
      (slot) 6 =>
        array (size=1)
          0 => (port) 33
3
  • can you provide an example of your $units when it is done? because i could be that "row" has no key named "frameNo" Commented Mar 29, 2017 at 13:27
  • 4
    Doing this in twig will probably be annoying. You can use attribute for using a dynamic value as key, but not sure how it will work in nested structures. I would argue that converting types is logic that should be done in a Transformer/Converter class in your code and not in your template. Commented Mar 29, 2017 at 13:34
  • 3
    You cannot do that in twig, you need for example merge(). But although it is possible, but will lead to a lot of ugly code (you need temporary variables for your keys...). So if you can do it in php and send the result to twig, I would recommend that instead. Commented Mar 29, 2017 at 13:35

2 Answers 2

60

I'm afraid you can't create arrays like that in Twig. Even appending new items to an array is complicated because you need to create an array for the new element and concatenate it with the existing array. Example:

{% set array = [] %}
{% for item in items %}
    {% set array = array|merge([{ title: item.title, ... }]) %}
{% endfor %}

I know this looks awful, but all this inconvenience is done on purpose. Twig is meant to create templates, so the features available to create or process information are limited on purpose. The idea is that heavy data processing should be done with PHP.

Sign up to request clarification or add additional context in comments.

1 Comment

I completely understand. Thank you. I can process this with PHP but then I have to do to much overriding of Sonata Admin Bundle just to add this to one show template of an entity. Anyway, I will check it out. Thanks
58

Another way :

{% set array = {
  'item-1': {
    'sub-item-1': 'my-sub-item-1',
    'sub-item-2': 'my-sub-item-2'
  },
  'item-2': {
    'sub-item-1': 'my-sub-item-1',
    'sub-item-2': 'my-sub-item-2'
  },
  'item-3': {
    'sub-item-1': 'my-sub-item-1',
    'sub-item-2': 'my-sub-item-2'
  }
}
%}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.