3

For project needs I need to change some form fields data before they render. To do that I iterate over form elements and dynamically change values I need.

Problem is that I can't change value. I got this error:

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

I used this piece of code to change value but I got error above:

{% set arr = arr|merge({'element': 'value'}) %}

Does someone knows where is the problem?

This is code I used.

Twig template code (example code I used)

<ul>
        {% dump (edit_form) %}
        {% for element in edit_form.children %}
            {% dump (element.vars) %}
            {% set element.vars = element.vars|merge({'name': 'My title (just for testing purpose)'}) %}

            <li>{{ element.vars.name }}</li>
        {% endfor %}
    </ul>

Form object:

FormView {#637 ▼
  +vars: array:24 [▶]
  +parent: null
  +children: array:4 [▼
    "title" => FormView {#699 ▼
      +vars: array:24 [▼
        "value" => "le title"
        "attr" => []
        "form" => FormView {#699}
        "id" => "adminbundle_intro_title"
        "name" => "title"
        "full_name" => "adminbundle_intro[title]"
        "disabled" => false
        "label" => null
        "label_format" => "admin.intro.form.%name%"
        "multipart" => false
        "block_prefixes" => array:3 [▶]
        "unique_block_prefix" => "_adminbundle_intro_title"
        "translation_domain" => null
        "cache_key" => "_adminbundle_intro_title_text"
        "errors" => FormErrorIterator {#696 ▶}
        "valid" => true
        "data" => "le title"
        "required" => true
        "size" => null
        "label_attr" => []
        "compound" => false
        "method" => "POST"
        "action" => ""
        "submitted" => false
      ]
      +parent: FormView {#637}
      +children: []
      -rendered: false
    }
    "content" => FormView {#698 ▶}
    "isEnabled" => FormView {#702 ▶}
    "_token" => FormView {#711 ▶}
  ]
  -rendered: false
}
2
  • You can't assign a property of an object / index of an array inside twig. You need to merge the whole object/array with all it's properties/indices Commented May 15, 2017 at 11:39
  • @DarkBee Thank you for your replay. I am aware now that I need to change whole array. Problem is that I need to change only one or two elements of this array. Not all of them. And I am not sure how to achieve it. Commented May 15, 2017 at 11:43

1 Answer 1

2

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" #}
Sign up to request clarification or add additional context in comments.

6 Comments

thank you for your answer. I tried your code and I didn't changed value
What PHP version are you using?
I am using PHP 7
So you are using Twig 2.X then? I'm still on 1.X perhaps sthing changed in between
@DarkBee's solution works on both Twig 1.x and 2.x but don't forget that in your question, element is an object not an array, so you enter the return; case of the extension. You need to tweak it a bit more.
|

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.