Set value of single object in multidimensional array in twig template

To change a certain index of an array you’re best of with extending Twig, a solution could be this,

ProjectTwigExtension.php

namespace Your\Namespace;

class ProjectTwigExtension extends Twig_Extension {

    public function getFunctions() {
        return array(
            new Twig_SimpleFunction('set_array_value', array($this, 'setArrayValue'), ['needs_context' => true,]),
            new Twig_SimpleFunction('set_object_property', array($this, 'setArrayValue'), ['needs_context' => true,]),      
        );      
    }

    public function setArrayValue(&$context, $array_name, $index, $value) {
        if (!isset($context[$array_name])) return;
        if (is_array($context[$array_name])) $context[$array_name][$index] = $value;                
        elseif(is_object($context[$array_name])) {
            if (method_exists($context[$array_name], $index)) $context[$array_name]->{$index}($value);
            elseif(method_exists($context[$array_name], 'set'.$index)) $context[$array_name]->{'set'.$index}($value);
        }
    }

    public function getName() {
        return 'ProjectTwigExtension';
    }        
}

Add extension to twig

$twig->addExtension(new \Your\Namespace\ProjectTwigExtension());
/** ... code ... **/
$user = new User();
$user->setUserName('admin');

$twig->render('template.twig', [ 'somearray' => ['foo' => 'bar',], 'user' => $user, ]);

template.twig

{{ dump(somearray) }} {# output: array(1) { ["foo"]=> string(3) "bar" } #}

{{ set_array_value('somearray', 'foo', 'foobar') }}

{{ dump(array) }} {# output: array(1) { ["foo"]=> string(6) "foobar" }  #}

{{ dump(user.getUserName()) }} {# output: string(5) "admin" #}

{{ set_object_property('user', 'UserName', 'StackOverflow') }}

{{ dump(user.getUserName()) }} {# output: string(13) "StackOverflow" #}

Leave a Comment