Interpret variable inside another - twig

I am trying to interpret a variable inside another. Something like:
// list of variables
foo: 'test';
bar: 'this is {{ foo }}'
// Twig
{{ bar }}
// result :
this is a test
I try this but I think it is old : Twig variables in twig variable

You can do this with template_from_string Twig function.
{% set foo = 'test' %}
{{ include(template_from_string('this is {{ foo }}')) }}
The template will render with the context of the containing template, meaning, it will have access to all variables that the main template has access to.
Note that template_from_string Twig function is not available by default. It only becomes available once you activate Twig\Extension\StringLoaderExtension extension found in Twig package.

Related

How to use safe filter on custom Django tag?

I'm trying to implement a custom Django tag that will formulate an import statement in Javascript to load my vue3 app as well as its components template html files using a get request in axios.
The custom tag in my templatetags directory looks like this:
templatetags/vuecomponents.py
from django import template
from django.templatetags.static import static
register = template.Library()
#register.simple_tag
def v_load_app_component(app_name, script_name, components):
components = components.strip("[]").split(", ")
app_script = static(f"js/{script_name}.js")
comps = [static(f"components/{name}.html") for name in components]
return f"import {{{ app_name }}} from \"{app_script}?{components[0]}={comps[0]}\""
Right now it only loads the first component as I just want a prototype. The only issue is when I drop this into a template like so:
createpost.html
<script type="module">
{% v_load_app_component "creator" "internalpostform" "[internalpostform]" %}
// OUTPUTS:
// import { creator } from "static/js/internalpostform.js?internalpostform=internalpostform.html"
creator.mount("#app")
</script>
It outputs the relevant import statement as:
import { creator } from "static/js/internalpostform.js?internalpostform=internalpostform.html"
With the double quotes escaped. Even when I tried to apply the safe filter ({% v_load_app_component "creator" "internalpostform" "[internalpostform]"|safe %}) it still escaped the output of my custom tag function.
How can I make it to where the output of my custom tag doesn't automatically have symbols converted to html entities?
I found it after a little digging in Django's documentation. The safe filter is only for variables i.e. {{ variable|safe }} but does not apply to a tag {% tag "argument"|safe %}.
To prevent Django from escaping the output of a tag you simply use {% autoescape off %}
{% autoescape off %}
{% v_load_app_component "creator" "internalpostform" "[internalpostform]" %}
{% endautoescape %}
This results in the desired behavior.

Fetch url parameters in twig

this is my URL:
192.168.0.101/user1/opc_autopart/upload/index.php?route=product/category&path=20
I want to fetch path parameter and below is my code
{{ app.request.get('path') }}
This code is not working
You may use:
{{ app.request.query.get('path') }}
to get the path query string in twig.
You would better define a default value, in case there is no path parameter:
{{ app.request.query.get('path')|default('1') }}

How to get route link in Slim3 Twig?

I defined my route so:
$app->get('/about', function ($request, $response, $args) {
return $this->view->render($response, 'about.twig');
})->setName('about.page');
I'm interested to get route link by name like: {% get_route('about.page') %}
How can I achieve this?
In Slim3 there is the path_for(name) function. F.ex:
{{ path_for('about.page') }}
Reference: http://www.slimframework.com/docs/features/templates.html
The slim/twig-view component exposes a custom path_for() function to your Twig templates. You can use this function to generate complete URLs to any named route in your Slim application. The path_for() function accepts two arguments:
1 A route name
2 A hash of route placeholder names and replacement values
Note: The path_for uses the function of the router which is $router->pathFor(..)
Why not to use {%
{% is a control structur in twig, Message: Unknown "path_for" tag in "base.twig" at line XX. is displayed because there is no such tag as control structur defined so twig doesn't know that this is actually a function.
So use the output structur in twig {{.
Is this possible?
Yes.
IIRC
{{ path_for('about.page') }}
Reference:
https://github.com/slimphp/Twig-View/blob/master/src/TwigExtension.php#L37

Twig : Access to variable from outer scope in a form widget customization

I'm trying to customize a specific widget, like in the documentation : http://symfony.com/doc/current/cookbook/form/form_customization.html#how-to-customize-an-individual-field
The problem is that in this custom block, I need to use a variable from my actual template. I thought "blocks have access to variables from outer scopes", but apparently not in this case :
{% extends "CDASvBundle::layout.html.twig" %}
{% block _contact_activity1_widget %}
<select name="contact[activity1]">
{% for key, child_contact_categories in contact_categories_tab %}
<option value="{{key}}">{{child_contact_categories}}</option>
{% endfor %}
</select>
It's saying that contact_categories_tab is undefined, but outside of this block (in the normal content block for example), it works !
I tried something like :
{% use 'form_div_layout.html.twig' with contact_categories_tab as contact_categories_tab %}
But that doesn't either.. Though I'm not sure I understand if I have to use use and how !
I see one other solution that I haven't tried yet : put this customization in another template. But I don't really want to do that (few lines in a new template), there should be a way to do that in only ONE template ?!
Finally found the answer in a previous post :
Each symfony form type extents AbstractType class.
AbstactType class has method:
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->set('img_src', '120x100.jpg');
$view->set('my_variable', $foo);
}
You can create this method on your form type and next in your twig:
{{ asset(img_src) }}
Source : How to get entity or pass variable to Symfony2 twig form widget?

Twig - Output array key if array is referenced

I have a series of templates which target the Twig variable {{ file }}, which currently outputs the file's src e.g. "/path/to/file.jpg".
I want to update the contents of file to an array so that it stores multiple properties e.g. {{ file.src }} {{ file.size }}.
If I make this change then all uses of {{ file }} will output Array.
Is it possible to set Twig so that it will instead target the first property of the array? In this case {{ file.src }}.
Many thanks!
You can't if your variable is a pure array, but you can do it with objects.
If you want your object to be usable like an array, you need to extend ArrayObject in your class.
You can implement the magic method __toString to make your object printable as a string (in your case, $this['src']).
Let's have an example.
1) Create the following class :
class File extends \ArrayObject
{
public function __toString()
{
if (isset($this['src']))
{
return $this['src'];
}
}
}
2) In a controller, initialize your object.
$file = new File();
$file['src'] = 'my_file.png';
$file['size'] = 42;
3) In your twig file, try it :
{{ file }}<br/>
{{ file.src }}<br/>
{{ file.size }}<br/>
4) Enjoy

Resources