reuse variable as string - twig

This question maybe kind of silly but I'm a newbie for symfony anyway.
prescenario I pass a variable from controller into index.html.twig by doing this
return $this->render('index/index.html.twig', [ 'department'=>$departments,'URILink'=>$URILink,'departmentDetail'=>$departmentDetails,'contentCell'=>$this->mContentCell ]);
After using {% dump %} it shows me
"department" => array:3 [▶]
"URILink" => "http://localhost/index/department/"
"departmentDetail" => array:1 [▶]
"contentCell" => "department.html.twig"
Then I need to reuse the variable contentCell as string in template to form syntax similar to this ;
<div>{{ include ('department.html.twig'),[departmentDetail:departmentDetail]</div>
For my first attempt I tried this,
<div> {{ include ({{ContentCell}}),[departmentDetail:departmentDetail]}} </div>
Unfortunately it showed me this error
A hash key must be a quoted string, a number, a name, or an expression
enclosed in parentheses (unexpected token "punctuation" of value "{".
Any idea how could I use the variable
contentCell as string value appropriately?

try this:
{% include contentCell with { departmentDetail : departmentDetail} %}

Answer here pass data to twig
You can include a template like this per:
{{ include('YourBundle:ControllerName:yourAction.html.twig', {'variableName': yourData}) }}
Or like this per http://twig.sensiolabs.org/doc/tags/include.html
{% include 'template.html' with {'foo': 'bar'} %}

after try'n try at last I found the the trick how to do it
i take similar analogy for
{{dump(var)}}
so attempt to do this
{{include (contentCell,{'departmentDetail' : departmentDetail}) }}
and it work like charm :) nice

Related

What is the version of #component (from .blade) for twig file?

I don't know if this is right version of #component for twig? Is it render?
{{ render ('mail::message') }}
{{ render ('mail::button', ['url' => '']) }}
or maybe I am not able to write the right syntax here?
Check out Twig's macro.
For the Blade
<!-- /resources/views/demo.blade.php -->
{{ $slot }}
<!-- component use -->
#component('demo')
content
#endcomponent
the basic Twig syntax would be
{# macro definition #}
{% macro demo(param) %}
{{ param }}
{% endmacro %}
{# macro use #}
{# first import and then you can #}
{{ demo('content') }}
You'll need to import the macro before calling it, either with from or import. To import (with either from or import) from the current file, use _self instead of a path. See the docs for more explanation
Your example
{{ render ('mail::button', ['url' => '']) }}
looks like it's coming from Blade's #include, something like
#include('mail::button, ['url' => ''])
For that, Twig's include might be a better fit. The relationship between macros and includes in Twig is similar to the relationship between components and includes in Blade. The basic Twig would be
{# partial.html #}
{{ url }}
{# partial use #}
{% include 'partial.html' with {url: ''} %}

Twig direct include doesn't work, only "with"ing specific keys does

I'm using Pattern Lab with twig templates and having an issue with using objects directly in the with statement in includes.
This is my teaser-content-blocks organism:
{% set content_blocks = [
{
teaser_photo: {
url: 'https://img.buzzfeed.com/buzzfeed-static/static/enhanced/terminal01/2011/3/29/17/enhanced-buzz-14894-1301433714-5.jpg',
alt: 'Man sleeping on a cake',
title: 'Man sleeping on a cake',
height: '200px',
width: '400px',
},
}
] %}
<div class="teaser-content-blocks">
{% for content_block in content_blocks %}
{% include '#molecules/teaser-content-block.twig' with content_block only %}
{% endfor %}
</div>
This is the teaser-photo atom:
<div class="teaser-photo">
<img
src="{{ url }}"
alt="{{ alt }}"
title="{{ title }}"
/>
</div>
And this is what I'm attempting to do with the teaser-content-block molecule:
<div class="teaser-content-block">
<div class="left">
{% include '#atoms/teaser-photo.twig' with teaser_photo only %}
</div>
<div class="right">
{% include '#atoms/title.twig' with { title: 'Sleep on a cake', element: 'h3' } only %}
{% include '#atoms/teaser-body.twig' with { body: "When we say 'sweet dreams', this isn't quite what we mean! Check this mad lad not understanding the general concept of pillows! This utter banterboy has completely confused what he is meant to use as a confectionary-based celebration of one's birth and a soft item of bedding designed to cushion the head during sleep or light rest. Mental!" } only %}
</div>
</div>
It seems, however, that the with teaser_photo only statement causes twig to break and not compile, with an error of Catchable fatal error: Argument 1 passed to Twig_Template::display() must be of the type array, null given.
If I change that include statement to the following:
{% include '#atoms/teaser-photo.twig' with { url: teaser_photo.url, alt: teaser_photo.alt, title: teaser_photo.title } only %}
... it works fine, but this is way too verbose for my liking. I'd rather just pass the object down as it is. It just seems to not want to pick it up in the correct manner, even though theoretically it should work the same.
I'm not a twig expert so I may be missing something really obvious.
Any help much appreciated as always!
Discovered the issue. Pattern Lab of course tries to render every available pattern, so it was trying to render teaser-content-block.twig which is trying to reference the variable teaser_photo, which of course doesn't exist in this scope. So the cure was to replace that line with one that uses a default, like so:
{% include '#atoms/teaser-photo.twig' with teaser_photo|default({}) only %}
... or at least something that does a similar thing. Thanks to #DarkBee too for taking the time to have a look.

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?

Swig (node.js) Include a File and pass an object

I am facing this problem.
I've got a page with an include of another like this:
index.html
{{ set pets = { pets : petsObject } }}
{{ include pets.html }}
petsObject is an object like this
petsObjects: [
{ name : "cat" },
{ name : "dog" }
]
When I try to render the page I get a blank page with only this:
[object Object]
I have no clue about what is going on :(
Thanks in advance!
Seems you'll need to use:
{% include pets.html with pets %}
According to docs for include:
Locally declared context variables are not passed to the included template by default.
It is also recommended for performance to use the only keyword after the included terms, like this:
{% include pets.html with pets only %}
Beyond that, it depends on the contents of pets.html, which you haven't included here. But, make sure that you're attempting to output the name:
{% for pet in pets %}
{{ pet.name }}
{% endfor %}
Or use a filter like json_encode() to format it:
{% for pet in pets %}
{{ pet|json_encode }}
{% endfor %}
Trying to output the Objects themselves will simply produce [object Object]:
new Object().toString() === "[object Object]"

Resources