Asked  8 Months ago    Answers:  5   Viewed   42 times

I read in the Twig documentation that it is possible to iterate over an associative array in the following manner:

{% for key, value in array %}  
 {{key}}  
 {{value}}  
{% endfor %}  

I was wondering whether this is possible for objects of type stdClass as well.

I would have expected Twig to iterate over the property values of the object taking the property names as keys. Instead, the instruction block contained in the for loop is not executed at all.

 Answers

98

You can first cast the object to array. You can build own filter casting your object to array. More about filters is available here: http://twig.sensiolabs.org/doc/advanced.html#filters

It could then look like that:

{% for key, value in my_object|cast_to_array %}
Wednesday, March 31, 2021
 
ManojGeek
answered 8 Months ago
49

Turns out I was wrong.

You can use the _context variable which contains all variables passed to the template.

Try {{ dump(_context) }}

Relevant Documentation

You can create a function that gets passed this context and the array key to access that value.

This twig function should work fine:

public function getAttribute($context, $key)
{
    if (!array_key_exists($key, $context)) {
        return '';
    }

    return $context[$key];
}

With the variables being passed title=foo and another variable being passed refTitle=title, this should output "foo".

{{ attribute(_context, refTitle) }}
Wednesday, March 31, 2021
 
dmp
answered 8 Months ago
dmp
97

What you're trying to do is call a method on an object with parameters in a Twig template. I do not think this is supported, as it's probably viewed as a bad idea. Twig supports the notion of getters on an object though, which are called without parameters:

{{ lang.test }}

will try to invoke one of the following, in this order:

  • $lang->test
  • $lang->test()
  • $lang->getTest()
  • $lang->isTest()

If the object implements any of these accessors and conventions, Twig will find it. Anything outside of this convention, like get('test'), is not part of the Twig philosophy. And it's not a widely used idiom in general, so you should probably stick to one of the above methods.

See http://twig.sensiolabs.org/doc/templates.html#variables.

You can implement __isset, __get or __call magic methods to support one of these accessor methods.

Saturday, May 29, 2021
 
John_BSDthos
answered 5 Months ago
70

for foo in some_dict iterates through the keys of a dictionary, not its values.

d = {'a': 1, 'b': 2, 'c': 3}
for dd in d:
    print(dd)
# gives a; b; c

You probably want to do for foo in some_dict.values()

for dd in d.values():
    print(dd)
# gives 1; 2; 3
Sunday, August 22, 2021
 
Ramacciotti
answered 2 Months ago
83

You should learn about Twig's internals:

  • all Twig files are converted to PHP classes

  • {% extends %} is the equivalent for the litteral PHP extends (used for inheritance).

  • {% import %} assign a property of your context to an object of type "the twig file you're importing"

  • blocks are no more than php methods, and the native php inheritance let you overwrite Twig blocks sweetly.

So, taking this into account, your converted twig code will look like this:

class base {

   public function display() {
      $context['macros'] = new macros();
      $context['macros']->render_sections();
      echo '<section>';
      echo $this->blockWorking();
      echo '</section>';
   }

   public function blockWorking() {
     echo "content1-default";
   }

}

class macros {

  public function render_sections() {
     echo '<section>';
     echo $this->blockNotWorking();
     echo '</section>';
  }

  public function blockNotWorking() {
     echo "content2-defualt";
  }

}

class view extends base {

   public function blockWorking() {
     echo "content1-override";
   }

   public function blockNotWorking() {
     echo "content2-override";
   }

}

$view = new view();
$view->display();

You can clearly see here that the blockNotWorking() method of the view class can never overwrite the macro.

Sunday, August 29, 2021
 
jezrael
answered 2 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share