I'm sure that I have managed to do this before but for some reason it's not working correctly.
I have a page in my project that lists clients by their account status. It's not mandatory, but a status CAN be passed via the URL, else it simply lists the active clients.
example:
myurl.com/clients/closed
would list all the clients with closed accounts.
My route is set up as follows:
app_show_clients:
path: /clients/{status}
defaults: { _controller: AppBundle:Client:showClients, status: 'active' }
requirements:
status: active|closed
And in my Twig file, I am attempting to retrieve the status as follows:
{{ app.request.get('status') }}
in order to show the status in the title of the page.
However, this just comes back as blank - though if I write:
{{ dump(app.request.get('status')) }}
It gives me the value "closed" in the var dump.
What am I missing here?
Thanks in advance
Michael
Wouldn't it be better to use the controller to handle the request properly?
function showClientsAction($status)
{
// Do some important stuff to fetch clients matching the request
// Return array assumes #Template annotation usage
return array('clients' => $clients, 'status' => $status);
}
So you could simply write {{ status }} in your template.
Did you try by this way:
{{ app.request.query.get("status") }}
Issue has been solved - I had placed the code in the wrong place, therefore I thought it had failed when it actually was working using:
{{ app.request.get('status') }}
which is the correct way.
Related
I render my header.twig from the base.twig file via the render function. So in my base.twig there is the following code to trigger header controller:
{{ render(controller('MyBundle:Global:header')) }}
That controller renders the header.twig. In this twig file there the the following code link for changing the language:
<img src="{{ asset('flags/'~app.request.locale~'.png', 'img') }}" />
The objects form app.request.get('_route') and app.request.get('_route_params') both return null.
app.request.get('_route')
If I run the same code link directly in the base.twig the request returns the correct objects. Looks like because the header.twig has it own controller the request are not working. Is it possible to request the route and parametsr of the active url in a other way?
Adding to #Gustek's answer because I missed the actual issue in the first case.
You are actually rendering a sub request so the _route and _route_params are from the sub request rather than the main request. As you are using a controller the cleanest approach would be to get the parameters from the master request and pass those in as parameters in the controller call. You could pass them in through the render call (as #Gustek has answered) but that would mean you would mean to do it with every call, or you could pass the request stack into the twig session but that would be unnecessary extra work.
public function headerAction(Request $request)
{
$masterRequest = $this->container->get('request_stack')->getMasterRequest();
//...
return $this->render('MyBundle:Global:header.html.twig', [
//...
'_route' => $masterRequest->attributes->get('_route'),
'_route_params' => $masterRequest->attributes->get('_route_params'),
]);
}
controller method takes 2 optional arguments.
http://symfony.com/doc/current/reference/twig_reference.html#controller
Not 100% sure about it but maybe this will work:
{{ render(controller('MyBundle:Global:header',
{
'_route': app.request.get('_route'),
'_route_params': app.request.get('_route_params')
}
)) }}
I have a partial view, that's displays a form on the DVD's page:
Partial View with form:
<div>
{{ form(form) }}
</div>
Use of partial view in the DVD's page:
{{ render(controller(
'DVDBundle:Actors:addActor',
{ 'dvdId': dvd.id }
)) }}
The idea is that admin can add actors using the form on the dvd page (url: website/dvdpage)
However: the function addActor in controller Actors doesnt seem to have anything in Request because its used via partial view:
Controllers function:
public function addActorAction(Request $request, $dvdId)
{
//form related code...
......
...
}
When checked what's inside: $request I get:
_fragment?_path=_format%3Dhtml%26_locale%3Den%26_controller%3DDVDBundle%253AActors%253AaddActor
and the error is forbidden access 403. here:
if (!$request->isMethodSafe()) {
throw new AccessDeniedHttpException();
}
The strange part is that if i go to that view directly via url : website/addactor then that same form works and the Request has correct value in same controller.
I found this:
When using a controller instead of a URL, you must enable the Symfony
fragments configuration:
added exact line to my config: fragments: { path: /_fragment }
but still nothing.
But have no idea how and what to do? Any help?
So yes, this worked for me, passing in the request as a parameter to the controllers function:
{{ render(controller(
'DVDBundle:Actors:addActor',
{ 'dvdId': dvd.id, 'request': app.request }
)) }}
Note, you also need to update the routing to include second parameter like this:
add_actor:
url: addactor/{dvdId}-{request}
....
i want to set a variable to twig when redirect link like when use the render methods :
return $this->render('socialBundle::index.html.twig',array(
'id' => $id
));
it will set the Id variable to twig : {{ id }}
return $this->redirect($this->generateUrl("tuto_animaux_voir", array(
'id' => $id
)));
it will set the Id variable to the link : xxxxx.com/Id , i want that it render this variable to twig when redirect ...
sorry for this bad concept and language because i'm not england , and this is my first question in stackoverflow ,
wait for a reponse , thanks
I don't quite understand what you want to do, if you want to put a link in a twig template or just redirect from a controller according a condition. if you can give more details of what you want to do I think I can help you.
UPDATE (solution)
You could use "Forwarding to Another Controller" instead of using "Redirect" and from there to send the variables to the twig template
Based on your last comment, I came to the following conclusion.
Assume that you have index action, with route tuto_animaux_voir. And route has one parameter id. It takes id as parameter and fetches alert from the database(we have alerts on the database). Also we have entity Alert with fields id(default), title.
...
public function indexAction($id){
$alert = $this->getDoctrine()->getEntityManager("AppBundle:Alert")->find($id);
return $this->render("AppBundle:Post:index.html.twig", array(
'alert' => $alert
));
}
In your template index.html.twig you can show your alert.
...
{{ alert.title }}
...
If you want to redirect to the index action in the twig.
<a href="{{ path("tuto_animaux_voir", { 'id': alert_id })}}">Alert Title<a>
Also if you want render this action as partial.
{{ render(controller('AppBundle:Alert:index',{'id': alert_id})) }}
I think my answer would be helpful for you.
In you case 'tuto_animaux_voir' is a route associated to controller action. Given id will be available as action parameter, so you can pass it like this:
public function fooAction($id)
{
return $this->render(
'socialBundle::foo.html.twig',
['id' => $id]
)
}
You can also fetch data from database and pass them to the view.
If that's not what to you want to achieve, tell us why you want to use redirect, and what these two actions should do.
Edit:
If I understood your comment correctly, you want to implement flash messages, which are already available in symfony.
Example in docs is simple and self-explanatory.
On a dashboard page, I've created a select list in a form that lists the names of components; the value that's passed from the select list is obviously the component id. On pressing submit, the user is routed to a page that displays the data about that component. Should be dirt simple...
Controller:
public function showDashboard()
{
$components = Component::lists('name','id'); ...
return View::make('dashboard', array('components'=>$components, ...))
}
dashboard.blade.php:
{{ Form::open(array('route' => array('components.show', $components->id), 'method'=>'get')) }}
{{ Form::Label('id','Component:') }}
{{ Form::select('id', $components) }}
{{ Form::submit('Show Component', array('class'=>'button')) }}
{{ Form::close() }}
I've tried various ways of doing this, and get a different error every time. The above code doesn't even let me display the dashboard page -- I get a "Trying to get property of non-object" error. Clearly, it's not liking $components because that was passed as a list array and not an object. As I said, I'm sure this is dirt simple, I just can't figure out the proper syntax, and Laravel docs aren't giving me the answer. Thanks!
The problem isn't the dropdown, or the lists method, but rather in your form opening. Here, you have $components->id as an argument to the route, but $components is an array and you can't access an id property on it.
Finally figured this out. I had posted a similar question here subsequent to this one, and rather than repeat the answer, it is here:
How to pass id value from select list to controller when controller expects an object? laravel-4
The very short version: change Route::get to Route::post. Details with code in the link above. Problem solved!
{{ render(controller("SomeBundle:Foo:Bar", {HERE I WANT TO PASS ALL query parameters app.request.query.all}) }}
So can I access all master request query parameters in sub request and the subrequest should also run independently?
Try this:
{{ render(controller("SomeBundle:Foo:bar", {'all': app.request.query.all}) }}
and in action store it in $all variable
public function barAction($all) {
// other your code
}
From your controller:
array_merge($request->query->all(), $request->get('_route_params'));
//query->all : get all query string parameters
//_route_params : get current route parameters
From your twig template must be sth like:
app.request.query.all|merge(app.request.attributes.get('_route_params'))
I've never used this in twig templates, so first test it ;)
Then you can use that functions however you want to build the variables you'll pass to your subrequest
To just pass in what is in app.request.query.all:
{{ render(controller("SomeBundle:Foo:Bar", app.request.query.all)
To merge something extra in:
{{ render(controller("SomeBundle:Foo:Bar", { something: 'extra' }|merge(app.request.query.all))
Tested in Symfony 3.3.10 and Twig 1.35.0