Twig Variable Variables for a method - php

I'm attempting to do something that was very easy in PHP, but not so easy in twig.
Basically, I need to call a class method, but I need to be able to define the method to call via a string.
I have 3 methods: getControlvs, getControlnc and getControltr. However, in order to call these methods, I need a seperate variable which determines which one to call.
This is what I'm attempting to call right now:
{% set neutPer = key.getControl~neutFaction %}
Where neutFaction can be either "vs", "nc", or "tr".
This only seems to fire key.getControl and then that's it, the concatenation is lost.
Any ideas?
Thanks in advance!

You can use the attribute twig function:
First concatenate the string as:
{% set method = "getControl" ~ neutFaction %}
Then call as
{{ attribute(key, method) }}
You can pass arguments also as:
{{ attribute(key, method, arguments) }}
In addition, the defined test can check for the existence of a dynamic attribute:
{{ attribute(object, method) is defined ? 'Method exists' : 'Method does not exist' }}

Try {% set neutPer = (key.getControl~neutFaction) %}
Or you could change this in your controller/service that passes the variable to twig so that you do not need to setup a concatenation.

Related

How to add a new parameter in the app.request from twig

I want to add a new parameter in the app.request from twig.
I have tried with this but am not getting the result I expected:
{% set app.request.query.set('script') = false %}
You should never change the request object in a Twig template. I don't think it's even possible actually.
If you just want to add a parameter and use it in the current template, just do something like this:
{% set parameters = app.request.query.all()|merge({'script': false}) %}

form_widget with dynamic form name

In my Twig template I have a FOR LOOP that creates a multiple number of forms like so:
{% for thing in things %}
{% set form_id = 'myform_' ~ thing.Id %}
{% set form_name = attribute(form, 'myform_' ~ thing.Id) %}
{{ form_widget(form_id) }}
{{ form_widget(form_name) }}
{% endfor %}
I would like this to generate the following:
{{ form_widget(myform_1) }}
{{ form_widget(myform_2) }}
.... and so on.
I left my 2 failed attempts in there, (form_id and form_name), to save anyone from suggesting those as possible solutions.
To summarize; I need to insert the dynamically created value (myform_1, myform_2) inside of {{ form_widget() }}
You can render dynamic fields form with dynamic name in Twig with special function of Twig :
{{ attribute(object, method) }}
{{ attribute(object, method, arguments) }}
{{ attribute(array, item) }}
With this function you can easily generate dynamic string name for your field dynamic into your form like this
{{ form_widget(attribute(form, 'myfielddynamicname' ~ var ~ ' lastchar')) }}
With this variable "var" (array or others type) you can render lot of dynamic form name like :
myfielddynamicnamefoolastchar
myfielddynamicnamebarlastchar
myfielddynamicnameneolastchar
For more understanding you can read this official twig documentation function
here : attribute twig function documentation
The things myform_1 and myform_2 simply are variables with FormView object as you define in your controller.
I don't know if Twig allows on dynamic variables call, although you can collect these form objects in array in controller before passing to view. After this step, you can just iterate thought this array It will manage the problem you are facing with.
Don't create a loop in your Twig: the layout should only render a single form. Then you can build the forms in your controller and render each one of them.
See this documentation on the Symfony book on how to get the result of a rendered template. You can concatenate the single render results and return a response with the full content.

Using a Twig variable inside the 'use' tag

I want to dynamically use a Twig template, but for some reason I can't get it to work.
When I add this line, my page crashes:
{% use current_page %}
current_page is set to "birthday.twig", which exists.
As the Twig documentation states:
Because use statements are resolved independently of the context passed to the template, the template reference cannot be an expression.
So unfortunately it is not possible to have a variable {% use xyz %} statement.
However, you can include using a variable. See http://twig.sensiolabs.org/doc/recipes.html

how to pass all request query parameters to embedded controllers in twig symfony 2?

{{ render(controller("SomeBundle:Foo:Bar", {HERE I WANT TO PASS ALL query parameters app.request.query.all}) }}
So can I access all master request query parameters in sub request and the subrequest should also run independently?
Try this:
{{ render(controller("SomeBundle:Foo:bar", {'all': app.request.query.all}) }}
and in action store it in $all variable
public function barAction($all) {
// other your code
}
From your controller:
array_merge($request->query->all(), $request->get('_route_params'));
//query->all : get all query string parameters
//_route_params : get current route parameters
From your twig template must be sth like:
app.request.query.all|merge(app.request.attributes.get('_route_params'))
I've never used this in twig templates, so first test it ;)
Then you can use that functions however you want to build the variables you'll pass to your subrequest
To just pass in what is in app.request.query.all:
{{ render(controller("SomeBundle:Foo:Bar", app.request.query.all)
To merge something extra in:
{{ render(controller("SomeBundle:Foo:Bar", { something: 'extra' }|merge(app.request.query.all))
Tested in Symfony 3.3.10 and Twig 1.35.0

Twig - assume variables as object methods

This is a strange one. I'm trying to implement a 1:1 relationship between Twig and some ViewModel objects, such that Twig is aware of its context and assumes variables are methods on the object.
For example, I have a Twig template and a ViewModel_Product. I could do this...
$template->render(array('product', $product));
...and in the template...
<p>{{ product.name }}</p>
However, because the only thing that will ever be passed to the template is the model, it seems pointless to have users prefix each variable. Better usage would be:
$template->render(array('viewModel', $product));
...and...
<p>{{ name }}</p>
How can I achieve this?
I don't believe this would be possible because twig keeps track of other global variables in each template so how would it know if the variable {{ name }} is part of your view or some other global variable? And as it was mentioned above, having the variable prefix helps to namespace your view which makes for easier reading.
Don't be a lazy coder.

Categories