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
Related
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'] = ...//
}
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 #}
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.
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());
I'm having problem with displaying form when using CollectionType. It doesn't show newOrderCustomerType inputs, just label "Customer Id". Whats wrong?
newOrderCustomerType
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class newOrderCustomerType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->
add('firstname', TextType::class,array('label'=>'Firstname'))->
add('lastname', TextType::class,array('label'=>'Lastname'))->
add('email', TextType::class,array('label'=>'Email'))->
add('login', TextType::class,array('label'=>'Login'));
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Customer',
));
}
public function getName()
{
return 'app_bundlenew_order_customer_type';
}
}
newOrderType
<?php
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CollectionType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
class newOrderType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('customerId',CollectionType::class,array(
'entry_type'=>newOrderCustomerType::class,
'allow_add' => true,
'by_reference' => false,
'data_class' => 'AppBundle\Entity\Customer',
))
->add('shopOrderId')
->add('orderDate')
->add('postBuyFormMsg')
->add('invoice')
->add('payType')
->add('shipmentType')
->add('payStatus')
->add('save',SubmitType::class);
}
public function configureOptions(OptionsResolver $resolver)
{
}
public function getName()
{
return 'app_bundlenew_order_type';
}
}
And in TWIG template
{{ form_start(orderForm) }}
{{ form_widget(orderForm) }}
{{ form_end(orderForm) }}
How to make it show all input fields?
If you have an active "allow_add" option, it is possible to render this input throught the 'prototype' option:
$builder
->add('customerId',CollectionType::class,array(
'entry_type'=>newOrderCustomerType::class,
'allow_add' => true,
'by_reference' => false,
'data_class' => 'AppBundle\Entity\Customer',
'prototype' => true,
))
and then in the form:
{{ form_row(orderForm.customerId.vars.prototype}) }}
It should work.
For more, see the Symfony documentation of prototype option
Try removing 'data_class', I don't think that's part of CollectionType:
->add('customerId',CollectionType::class,array(
'entry_type'=>newOrderCustomerType::class,
'allow_add' => true,
'by_reference' => false,
))
See if that works.