TWIG form template: call variable in attr - twig

In a twig form template in Symfony 4 app I need to have an attribute with a variable.
Exemple:
{{ form_widget(myform.field, {'attr': {'class': 'bidding-slider','data-slider-value': '800'}}) }}
I need to put a variable in 'data-slider-value' instead of a manual value.
I tried :
{{ form_widget(myform.field, {'attr': {'class': 'bidding-slider','data-slider-value': '{{ variable }}'}}) }}
but it do not work...
{{ variable }} alone return well the value I need to put in 'data-slider-value'.
Second tried:
I have Extended form class 'TextType' method buildView.
To do that I added this file : src/Form/Extension/TextTypeExtension.php
// src/Form/Extension/TextTypeExtension.php
namespace App\Form\Extension;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\FileType;
class TextTypeExtension extends AbstractTypeExtension
{
/**
* Return the class of the type being extended.
*/
public static function getExtendedTypes(): iterable
{
// return FormType::class to modify (nearly) every field in the system
return [TextType::class];
}
public function buildView(FormView $view, FormInterface $form, array $options)
{
$tjm = $form->get('dailyrate')->getData();
$view->vars['attr']['data-slider-value'] = $tjm;
}
}
But now I am not sure of the way to use that in my form template...
Thank you very much for helping me.
Alex

Extend your form's class method buildView:
public function buildView(FormView $view, FormInterface $form, array $options)
{
$view->vars['attr']['data-slider-value'] = ...//
}

Related

Get URL in twig

Need to get the URL in a template.
I have tried using get.request.url and it always returns blank. I've tried get.request.attributes.get('_route') and it always returns blank. Since I'm new to twig I'm sure I'm missing something fairly basic and easy.
As you are working with twig standalone, u'd need to pass the information yourself. You could create a small wrapper class to solve this for you though.
Request.php
class Request {
public function __construct() {}
public function get($key) {
return isset($_GET[$key]) ? $_GET[$key] : null;
}
public function post($key) {
return isset($_POST[$key]) ? $_POST[$key] : null;
}
public function url() {
$http = 'http'.(isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? 's': '');
return $http.'://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
}
}
And register the class as a global into twig:
<?php
require_once __DIR__.'/vendor/autoload.php';
$loader = new Twig_Loader_Filesystem(__DIR__.'/../views');
$twig = new Twig_Environment($loader);
$twig->addGlobal('request', new Request());
Now you can use your wrapper inside twig
{{ request.url }}{# output current url #}
{{ request.get('variable') }}{# contents of $_GET['variable'] when set or null #}
{{ request.post('variable') }}{# contents of $_POST['variable'] when set or null #}

Twig function with needs_context

I need to get current_page in needs_context of my function.
It's working correctly, but needs_context stays empty.
My class Helper extends \Twig_Extension
class Helpers extends \Twig_Extension {
public function getName() {
return 'Helpers';
}
public function getFunctions() {
return [
new \Twig_SimpleFunction('activeClass', [
$this,
'activeClass'
], [
'needs_context' => true
])
];
}
public function activeClass($context, $page) {
if (isset($context['current_page']) && $context['current_page'] === $page){
return ' active ';
}
}
In my .twig file
Foo
I hope with this function to return active class for the current href in the navbar. I use Slim v3 with his extension Twig-view.
Thanks for your help.
I resolved the problem.
Because I use a extension of Twig for Slim and no Twig, it's different.
Normaly, we use needs_context to extract the value of the current_page.
But with Twig-view for Slim PHP, we can use {% if is_current_path('your_page') %}class="active"{% endif %}
Sincere thanks to #martias and #DarkBee for their help.

reuse select menu with different ids' and names' in twig

I would like to reuse a select menu, but change every time the id and the name for it in Twig. How could it be done?
I thought of a wrapper block about the select menu and then extend it each time of reuse. But how to set the values for id and name using {{ parent() }}?
I do this by storing and creating the keys in my custom Twig_Extension class, here is a small setup for it. By keeping it global I can ensure unique id's in every view/macro/include ...
example.twig
{% for i in 1..5 %}
<ul id="{{ get_unique_key('my_menu') }}">
<li>Foo</li>
</ul>
{% endfor %}
ProjectTwigExtension
class ProjectTwigExtension extends Twig_Extension {
private $keys = array();
public function getFunctions() {
return array(
new Twig_SimpleFunction('get_unique_key', array($this, 'getUniqueKey')),
);
}
/**
* Create an unique HTML identifier
*
* #param $name String to make unique
*
* #returns String
*/
public function getUniqueKey($name) {
if (!in_array($name, $this->keys)) {
$this->keys[] = $name;
return $name;
}
$i = 0;
while(in_array($name.++$i,$this->keys)) {}
$this->keys[] = $name.$i;
return $name.$i;
}
public function getName() {
return 'ProjectTwigExtension';
}
}
Register extension
$twig = new Twig_Environment($loader);
$twig->addExtension(new ProjectTwigExtension());

Twig extension: render template with variables

I have created a twig extension te render a view with some variables , but I have this error
An exception has been thrown during the rendering of a template ("Notice: Array to string conversion")
in :Backend\twig:activate.html.twig at line 1.
This is the Class extension:
namespace AppBundle\Twig;
class ActivateExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
new \Twig_SimpleFilter('activate', array($this, 'booleanFilter'), array('is_safe' => array('html'),
'needs_environment' => true)),
);
}
public function booleanFilter(\Twig_Environment $twig, $var1, $var2)
{
return $twig->render(':Backend/twig:activate.html.twig', array(
'var1' => $var1,
'var2' => $var2
));
}
public function getName()
{
return 'activate_extension';
}
}
this is the view to be rendred:
//test
{{ var1 }}<br>
{{ var2 }}
and this is how the filter is called in the other view:
{{ entity.activate|activate('test var1', 'test var2') }}
Referring to the TWIG developer guide about Filters:
When called by Twig, the PHP callable receives the left side of the
filter (before the pipe |) as the first argument and the extra
arguments passed to the filter (within parentheses ()) as extra
arguments.
So the first argument of the php function is the value of entity.activate probably the array of the errors, then the other params are passed as arguments. As example you should change your filters as follow:
public function booleanFilter(\Twig_Environment $twig, $activate, $var1, $var2)
{
return $twig->render(':Backend/twig:activate.html.twig', array(
'var1' => $var1,
'var2' => $var2
));
}
Hope this help. Sorry for my comment about twig functions

PUGXMultiUserBundle get type of current user

How can I get the type of current user with PUGXMultiUserBundle ?
This code returns this error
{% if app.user.type == 'user_one' %}
//...
{% endif %}
This is the error
Method "type" for object "AppBundle\Entity\UserOne" does not exist
This is entity User
namespace AppBundle\Entity;
use FOS\UserBundle\Model\User as BaseUser;
use Doctrine\ORM\Mapping as ORM;
/**
* #ORM\Entity
* #ORM\Table(name="user")
* #ORM\InheritanceType("JOINED")
* #ORM\DiscriminatorColumn(name="type", type="string")
* #ORM\DiscriminatorMap({"user_one" = "UserOne", "user_two" = "UserTwo"})
*
*/
abstract class User extends BaseUser
{
/**
* #ORM\Id
* #ORM\Column(type="integer")
* #ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
public function __construct()
{
parent::__construct();
// your own logic
}
}
after updating database there is a new field named type created in table user
Ah, I see the problem. In the twig file, you are calling:
{% if app.user.type == 'user_one' %}
Where "app.user" specifies the object, and "type" specifies the method. But you don't have a "method" defined in the Class. But instead you have the DiscriminatorColumn.
A method would be something like:
public function type(){
...
}
Hopefully that makes sense.

Resources