I want to use redirect in symfony to generate a url and at the same time I want to make a variable 'levels', accessible in the twig template but it does not seem to be working for me.
here is the code:
return $this->redirect($this->generateUrl('show_admin_panel'), array('levels' => $levels));
I got this error: The HTTP status code "1" is not valid.
and if I use this:
return $this->redirect($this->generateUrl('show_admin_panel', array('levels' => $levels) ) );
I get this error: Variable "levels" does not exist in AUIAraBundle:Admin:admin_panel.html.twig at line 10
this is the code in the twig template:
{% for level in levels %}
<li>{{level.letter}}</li>
{% endfor %}
You don't need to query that variable 'level' in the action that redirects, just do:
return $this->redirect($this->generateUrl('show_admin_panel'));
Then in your controller linked to your 'show_admin_panel', make sure query that variable and pass it to the render method
//$level = something;
return $this->render('AUIAraBundle:Admin:admin_panel.html.twig',
array(
'levels' => $levels
)
);
}
Related
I'm following the steps outlined in this documentation https://symfony.com/doc/current/controller/upload_file.html to allow a file to be uploaded. It is working perfectly for adding a new item, but when I try to edit my entity, I'm getting the following error:
The form's view data is expected to be an instance of class Symfony\Component\HttpFoundation\File\File, but is a(n) string. You can avoid this error by setting the "data_class" option to null or by adding a view transformer that transforms a(n) string to an instance of Symfony\Component\HttpFoundation\File\File.
I've tried code like what is suggested in that article to append the path of the folder as File type to the entity like this in my update method:
public function editAction(Request $request, Advertiser $advertiser)
{
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
$editForm = $this->createForm(AdvertiserType::class, $advertiser);
$editForm->handleRequest($request);
if ($editForm->isSubmitted() && $editForm->isValid()) {
$this->getDoctrine()->getManager()->flush();
return $this->redirectToRoute('advertiser_list');
}
return $this->render('advertiser/index.html.twig', [
'form' => $editForm->createView()
]);
}
The logo_directory parameter is properly defined (and working fine for creating new entities).
Please let me know if you have any ideas what I am doing wrong.
Thanks for the help.
UPDATE: In this article The form's view data is expected to be an instance of class ... but is a(n) string there is a proposed solution to include in the form builder code the following:
->add('file', FileType::class, array('data_class' => null))
So I'm doing this now and the edit form will show - but it doesn't prepoulate with the previous selection.
->add('logo', FileType::class, array('data_class' => null), ['label' => 'Logo (JPG or PNG file)'])
Any thoughts on how this can be changed to allow the form to show with the previous selection pre-populated?
Setting a null data_class will remove the warning but it will not work, you don't need it at this point.
This is due to the fact that once your file is persisted, what remains in your database is just a path, not the file itself (which is on disk);
If you want to edit this entity again, the path (a string) must be converted to a File entity again; That's what the error message says.
.. and this is what you did when you wrote :
$advertiser->setLogo(
new File($this->getParameter('logo_directory') .'/' . $advertiser->getLogo())
);
Now, the problem that remains is that you want to prepopulate the file field. In fact, that is not possible, since the file field points to a location in your own computer, not to a file on your server (and you cannot automatically upload something from someone's computer like that, that would be very dangerous).
What you want to do is possibly indicate that a file is already stored, get its path and maybe display it to your user.
So in your Twig template, something like that (change with your real logo directory) :
{% if form.logo.vars.data %}
<img src="{{ asset('/uploads/logos_directory/' ~ form.logo.vars.data.filename) }}"/>
{% endif %}
Hope it's clear.
Is there a more elegant way of checking if a variable in Twig is both defined (safe to reference/use) and also check the boolean value of as I am doing below?
I have a number of Twig templates which have messy logic in it like this and i'd rather it was more readable, however I don't know how this is done in Twig.
{% if primaryMethod is defined and paymentInProgress is defined and transactions is defined and not primaryMethod and not paymentInProgress and not transactions %}
You could write your own test to reduce the amount of Twig code you need.
This is fairly simple to do and just requires 2 steps:
First register your test in twig (either directly or use the method getTests in your twig extension
$twig->addTest(new \Twig_SimpleTest('false', null, [ 'node_class' => '\MyProject\Twig\Node\FalseExpressionNode' ]));
Create the test
<?php
namespace MyProject\Twig\Node;
class FalseExpressionNode extends \Twig_Node_Expression_Test_Defined {
public function compile(\Twig_Compiler $compiler)
{
$compiler->subcompile($this->getNode('node'))
->raw('&& $context[\''.$this->getNode('node')->getAttribute('name').'\'] === false');
}
}
Then you could use your test inside twig
{% if primaryMethod is false and paymentInProgress is false and transactions is false %}
sidenote : The test FalseExpressionNode is extending from Twig_Node_Expression_Test_Defined in order to suppress any undefined variables messages when twig is in debug mode
I am looking for best solution how to send value returned by one of entity function's in symfony2 to twig template.
The problem is connecting with getting file url for file uploaded according to "How to Handle File Uploads with Doctrine" manual (http://symfony.com/doc/current/cookbook/doctrine/file_uploads.html). I was following the last example ("Using the id as the Filename").
In controller I am getting one of documents entity.
$document = $this->getDoctrine()->getRepository('AppBundle:Documents')->find($id);
and I provide entity details to twig template:
return $this->render('AppBundle:Documents:details.html.twig', array('document' => $document));
However in the template I need to get link to the file which is generated by getAbsolutePath() function.
public function getAbsolutePath()
{
return null === $this->link
? null
: $this->getUploadRootDir().'/'.$this->id.'.'.$this->link;
}
I may use in controller the following code:
return $this->render('AppBundle:Documents:details.html.twig', array('document' => $document, 'link' => $document->getAbsolutePath()));
but this solution does not seems to tidy for me, as I am already sending $document to twig. What would be your practical solution?
Its simple. In a Twig template you can simply do:
{{ document.getAbsolutePath() }}
What is the format of the array returned using the getResult() method in the following example, using Doctrine and Symfony2:
$query = $this->_em->createQuery('SELECT p.id, p.nameProduct FROM ArkiglassProductBundle:Product p');
return $query->getResult();
And I would like to know how to access each case and print every row.
<?php
$query = $em->createQuery('SELECT u.username, u.name FROM CmsUser u');
$users = $query->getResults(); // array of CmsUser username and name values
echo $users[0]['username'];
taken from the doctrine documentation
Are you asking about "0" in $users[0]?
I hope I am not misunderstanding your question.
getResults() returns an array of database results. Once you've given your array a name you can access each element using the index.
Of course if you want to loop over it you will probably use a foreach loop so you won't have to use the index:
$products = $query->getResults();
foreach ($products as $product){
echo $product->id.' '.$product->nameProduct;
}
This said... this pseudo code is here for the sake of explanation. If you are using Symfony you will have to display your results in a view file, probably using twig like Manuszep did in his example.
In his case you will have to use a for in loop like he did.
The query returns an array of Users:
array(
0 => array(username => 'aaa', name => 'bbb'),
1 => array(username => 'ccc', name => 'ddd')
)
So the $users[0] element means the first user in the list.
You can use a for loop to iterate:
{% for user in users %}
{{ user.username }} - {{ user.name }}
{% endfor %}
I'm trying to manipulate the query string values in a URL.
I can get the current URL or route either from the Request object or Twig's functions, but it's the query string I'm struggling with.
I don't need app.request.attributes.get('_route_params') as this gets the query string params that are in the route.
I need to get query string params that are actually in the URL.
I want to be able to do the two things listed below in both Symfony2 (in a PHP controller) and Twig (in a Twig template):
Get all current query string values in the URL and display them
Do 1, but change one of the query string values before displaying them
I can't find anyone who knows how to do this.
You can use app.request.query.all to get your query strings.
If you want to change a param in Twig you can do this
{% set queryParams = app.request.query.all %}
{% set queryParams = queryParams|merge({queryKey: newQueryValue}) %}
To get the query string "https://stackoverflow.com?name=jazz"
{{ app.request.query.get('name') | default('default value if not set'); }}
Into controller
use Symfony\Component\HttpFoundation\Request;
public function fooAction(Request $request)
{
$params = $request->query->all();
}
please, pay attention: $request->query->all(); will return an array with keys named as query parameters
Into twig
As long you pass from controller (read this as always) you can pass your parameters to a view in that way
use Symfony\Component\HttpFoundation\Request;
public function fooAction(Request $request)
{
$params = $request->query->all();
return $this->render('MyFooBundle:Bar:foobar.html.twig', array('params' => $params));
}
Into your twig template foobar.html.twig you can access all query string parameters simply by using the params variable.
e.g with this request URL: http://example.com/?foo=bar&secondfoo=secondbar
{% for paramName, paramValue in params %}
<div>{{ paramName }}: {{ paramValue }}</div>
{% endfor %}
<div>{{ params.secondfoo }}</div>
twig output:
<div>foo: bar</div>
<div>secondfoo: secondbar</div>
<span>secondbar</span>
Another method is to use app.request.query.all in twig, without passing anything to twig from your controller.
Final note
If you want to modify one of those parameters when passing an array to twig from your controller, simply change one of the array values, as you would with normal values (i.e.: $params['id'] = $params['id'] - 1;)
Hi Stephen we have tried ur solution to get the value but it going to default value.
http://localhost:4000/about/investors/key-dates-and-events-details?year=2017#q1
i have used like this on my twig file
{{ app.request.query.get('year') | default('default value if not set'); }} Quareter Q1
Please let me know.