I want to add property 2 to this object in twig
object
property1
According to this question Updating object properties in twig The accepted answer says that it can be achieved by merge, but merge filter does not work with objects, is there any way to achieve this?
I think the most elegant way is using setters and getters:
class TestStdClass
{
private $prop1;
public function getProp1()
{
return $this->prop1;
}
public function setProp1($prop1)
{
$this->prop1 = $prop1;
}
}
Then in a Twig template use tag do
to evaluate expression (obj
is an instance of TestStdClass
):
{{ dump(obj) }} {# will print an empty object #}
{% do obj.setProp1('Hello') %}
{{ dump(obj) }}
This will print:
TestStdClass {#2468 ▼
-prop1: "Hello"
}
Don`t know about standart way to do it in twig, but i think that you can do it like this:
1. Create custum twig extension
class TwigPropertySetter extends \Twig_Extension {
function getName() {
return 'property_setter';
}
function getFunctions() {
return [
'setObjectProperty' => new \Twig_Function_Method($this, 'setObjectProperty')
];
}
function setObjectProperty($object, $propertyName, $propertyValue) {
$object->{$propertyName} = $propertyValue;
return $object;
}
}
2. Add extension to your twig renderer
$twig = new Twig_Environment(null, $options);
$twig->addExtension(new TwigPropertySetter());
3. Use function in your twig template
....
{% set object = setObjectProperty(object, 'property2', 'value2') %}
Show new object porperty {{ object.property2 }}
....
Notice: Not tested
You could also add a general setter to your class to get the dynamicity like in Kison's solution:
class Foo {
public function setProperty($name, $value) {
$this->$name = $value;
}
}
And then in Twig:
{% do obj.setProperty('property2', 'Second property') %}
This is simpler than Kison's solution and more dynamic than martin's solution. However, if you have many classes that need this kind of general setter, then Kison's solution might be better as it's more universal (i.e. you can add properties to objects of any class).