Twig: Dynamic access to object properties

Created on 5 Apr 2010  ·  17Comments  ·  Source: twigphp/Twig

obj['prop'] will return value only if obj is array and there is no way to get object property if we have it's name in a variable: obj[propName] will return null

Most helpful comment

You could try
{{ attribute(object, method) }}
{{attribute(obj, foo)}}
http://twig.sensiolabs.org/doc/2.x/functions/attribute.html

All 17 comments

you can use the dot notation which will check both for arrays and objects so obj.name will look first for a obj['name'] then obj->name and last obj->getName() this is also explained further in the documentation under the Twig for designers chapter.

I think artyv's issue is regarding accessing object properties dynamically as opposed to simply accessing offsets/properties. See my example code.

/* php */
$obj = new stdClass;
$obj->foo = "bar";
$template->render(array('obj, $obj));

/* twig */
{% set prop as "foo" %}
{{ obj.foo }} 
// outputs "bar" 

{{ obj.$prop }} 
// (pseudo-code)
// would compile down to {{ obj.foo }} and output "bar"

jwpage is right, property name, that i need to get is in other variable, so i need equivalent of this php code:
$obj->{$propName}
because $obj is simple object and it does not implement ArrayAccess

This feature won't be included in Twig. Twig is a template system, not a fully-features language. Dynamic properties is clearly out of Twig scope.

i guess the serializer component can be used to convert nested stdClass instances to nested arrays.

i think by just typecasting a stdClass to an array it would b converted. Why make it more difficult than it already is :)

[~] php -r '$class = new stdClass;$class->prop = "hejsa";print_r((array) $class);'      
Array
(
    [prop] => hejsa
)

@henrikbjorn: yes type casting works, however it doesnt work recursively which is why i was suggesting the serializer component. obviously if you know that you dont have a deeply nested structure then obviously just cast to an array and you are done.

I had the same problem and I solved it using a filter. I know it is not the right way to do things but it surely seems the cleanest.

Basically it boils down to this:

function twig_get_filter()
{
    $params = func_get_args();
    $object = array_shift($params);
    $field = implode('', $params);
    return $object->$field;
}

And you can use it as follows:

{{ object|get(text, '_', language, '_', type) }}

Dynamic properties is clearly out of Twig scope.

Why? I'm trying to develop something like symfony datagrid and I would like to use something like this:

{# columns #}
{% for name, column in grid.columns %}
<td>{{ column.render(row[name])|raw }}</td>
{% endfor %}

I can't see any better solution than implement something like Twig_Template::getAttribute method in my datagrid. I like how universal it is.

Because it's an edge case and because you can easily create a function that does what you want pretty easily (untested):

function twig_array_get_function($array, $name)
{
    return $array[$name];
}

Usage:

row|array_get(name)

Yes, for arrays it's easy. Problem is that I have to implement also accessing getters of objects etc which is already implemented in Twig (but there is no way how to use this code).

Good news! As of 1.2, you can now get a dynamic attribute on a variable via the new attribute function (see c609060).

Good to see support has been added for this. I am just getting started with Twig. How hard would it be to change the syntax to something like

{{ object.{property} }} or {{ object.{method}(attrs) }}

I think it's a bit cleaner than {{ attribute(object, method, arguments) }}

Perhaps you could point me in the right direction? I haven't been through all the source code yet.

@rspenc29: I don't want to make it "cleaner" as I want you to think twice before using this in a template. This is to be used with caution as most of the time, it's a smell that you are doing something in a template that should be done elsewhere.

no problem. I will figure it out.

asd deded

You could try
{{ attribute(object, method) }}
{{attribute(obj, foo)}}
http://twig.sensiolabs.org/doc/2.x/functions/attribute.html

Was this page helpful?
0 / 5 - 0 ratings