how to pass variable from twig path to the same controller? - symfony

In template i need to pass variable to controller when clicked link
{{ variable }}
click
.
How to do this?
/**
* #Route("/test", defaults={"variable" = 1}, name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable)
{
return array('variable'=>$variable);
}
You will say i need placeholder in #Route /test/{variable}, then how to first time visit url test?
edit: this is silly question. I had some cache problem while testing this issue. The answear is obvious.

You need to define your #Route annotation like you mention:
/**
* #Route("/test/{variable}", defaults={"variable" = 0}, name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable)
{
return array('variable'=>$variable);
}
Thanks to defaults option you can access your route with or without variable:
With:
click
This will generate url /test/2 and your $variable will equal 2
Without:
click
This will generate url /test and your $variable will equal 0 (a value set in defaults option)

I had to do something similar, and #Tomasz, your answer helped me a lot. I my case I needed two variables.
Using the above example as a reference:
* #Route("/test/{variable}/{var2}",
* defaults={"variable" = 0, "var2" = 0},
* name="test")
* #Method("GET")
* #Template()
*/
public function testAction($variable, $var2)
{
return array('variable'=>$variable, 'var2 => $var2);
}
Then in twig you can use:
click
which generates URL /test/2/3
In my case, I was using something more fancy, like an Entity:
<td><a href="{{ path('submitPetHasProgram',
{'prog':stu.getTcProgram.getProgramId,
'student':stu.getStuId}) }}">Select</a></td>
Hopefully this will help someone out in the future who is struggling for a solution to this type of problem.

Related

Redirect to route

I want some routes to "exists", but to redirect to another route.
For example, this is what I did with the / route
/**
* Homepage exists but redirect to projet
*
* #Route("/", name="homepage")
* #Method("GET")
*/
public function indexAction() {
return $this->redirectToRoute('projet_index');
}
/**
* #Route("/projets/", name="projet_index")
* #Method("GET")
*/
public function indexAction() {}
The thing I want to know is if it's this the best method to do it?
Nope the best way to do that is simple as that:
/**
* #Route("/", name="homepage")
* #Route("/projets/", name="projet_index")
* #Method("GET")
*/
public function indexAction() {
// your code here
}
This is somewhat off-topic, but there's a somewhat dirty trick you can use in a similar scenario, where you want to have several URLs resolving to a single route, using placeholders with requirements and default values:
/**
* #Route("/{path<projets/|>?}", name="projet_index")
*/
public function someAction() {
// ...
}
The way it works is by defining an optional placeholder (with the {...} syntax) called "path" (though you can call it something else). That placeholder is given requirements with the <...> syntax: it can be either "projets/" or the empty string "". Therefore, both the "/" and the "/projets/" URLs match that route, and nothing else, as they're off the form "/{path}" with a path placeholder that matches its requirements.
So far, so good. But there's still one thing we need to do: give it a default value with the ?, otherwise methods like redirectToRoute or the Twig function path will complain that we aren't given them a value for all the placeholders. Note that you could also use "/{path<projets/|>?projets/}" to make the default value URL "/projets/" instead of "/".
I know it's not exactly what OP wanted, but I think it can be a useful trick to know, and someone having a question similar to OP's might find it useful.

Symfony parameters Routes (Easy to answer)

I try to pass my user id in parameter because I wanted to use it in an other function to link them but don't know why that don't work (I think that I do a mistake and will be easy to answer thx :)
return $this->redirect('/profile/new/', array(
'id' => $user->getId(),
));
My receiver :
/**
* Creates a new profile entity.
*
* #Route("/new/{id}", name="profile_new")
*/
public function newProfileAction(Request $request)
{
when I do /profile/new/8 for example it works! But when I click in the button submit that don't redirect with the id ... (of course the routes are good and when I do - it works :
return $this->redirect('/profile/new');
my receiver (when it works) :
/**
* Creates a new profile entity.
*
* #Route("/new", name="profile_new")
*/
public function newProfileAction(Request $request)
{
You should use $this->redirectToRoute('ROUTENAME',[PARAMETERS]) means:
$this->redirectToRoute('profile_new',['id'=>$ID])
If you use $this->redirect('URL') you have to parse the URL so you need to "/profile/new/ID"

how to set the routing translation based on annotation?

All the routing of my website is realized based on the annotations. Now, I want to translate my routing. To realize that, I tried to use the bundle JMSI18nRoutingBundle.
Nevetheless, the documentation does not give any example how to specify the route for each locale.
This is an action with its routing, how to translate it?
/**
* #Route("/welcome", name="welcome")
* #Template()
*/
public function welcomeAction() {
return array();
}
Thanks,
Question after being edited
/**
* #Route("/welcome", name="welcome", defaults={"_locale" = "en"})
* #Route("/bienvenue", name="welcome", defaults={"_locale" = "fr"})
* #Route("/willkommen", name="welcome", defaults={"_locale" = "de"})
* #Template()
*/
public function welcomeAction() {
return array();
}
Now, what is happening with this new annotations:
the selected route is always the last one which is /willkommen (if you change the order the routes, the selected route is still the last one)
the _locale is set the the locale of the last route which 'de' according to the annotation above.
So, any proposal?
Thanks...
I found the solution. You just have to set run the following command
php app/console translation:extract fr --bundle=MinnTestBundle
--enable-extractor=jms_i18n_routing --output-format=yml
Then, minn/TestBundle/Ressources/translations/routes.fr.yml file will be generated. Customize you route translations & that is it!
Hope it will help others...
You can add multiple route annotations.
/**
* #Route("/welcome", name="welcome", defaults={"_locale" = "en"})
* #Route("/bienvenue", name="welcome", defaults={"_locale" = "fr"})
* #Template()
*/

Symfony Newb Routing Issue

I have just started using Symfony and I am having a routing problem. Here is the routing fromt the controller:
/**
* #Route("/social/{name}/", name="_speed1")
* #Route("/social/drivers/")
* #Route("/social/drivers/{name}/", name="_driver")
* #Route("/social/", name="_speed")
* #Template()
*/
public function unlimitedAction()
{
If I go to speed/social/ or speed/social/bob or speed/social/drivers/ or speed/social/drivers/bob all of those pages render with no problem. However I need the name being passed in so I changed
public function unlimitedAction()
{
to
public function unlimitedAction($name)
{
If I go to speed/social/drivers/ or speed/social/drivers/bob it returns fine. However, if I go to speed/social/ then I get the following error:
Controller "MyBundle\Controller\DefaultController::unlimitedAction()"
requires that you provide a value for the "$name" argument (because there is
no default value or because there is a non optional argument after this one).
I can't understand why it works for one route but not the other.
So my question is, how can I acheive my routing so that I can go to:
speed/social/
speed/social/drivers/
speed/social/drivers/bob
And be able to pass the variable to the action without error.
Thanks!
To answer your question: you have to provide a default value for name parameter, for each route without the {name} parameter in the url. I can't test it right now and I can't remember the syntax when using annotations, but should be something like this:
/**
* #Route("/social/{name}/", name="_speed1", defaults={"name"=null})
* #Route("/social/drivers/{name}/", name="_driver", defaults={"name"=null})
* #Template()
*/
public function unlimitedAction($name)
{
}
This way you should be able to call /social/ and /social/foo as well as /social/drivers/ and /social/drivers/foo.
But, really, this is not the right way to go. Just define more actions, each binded to a single route:
/**
* #Route("/social", name="social_index")
* #Template()
*/
public function socialIndexAction() { } // /social
/**
* #Route("/social/{name}", name="social_show")
* #Template()
*/
public function socialShowAction($name) { } // /social/foo
As a general rule, each method (each action) should be focused to do just one thing and should be as short as possible. Use services and make your controllers do what they are supposed to do: understand user input, call services and show views.

Redirect using #Route annotations

Is there a way to redirect using annotations?
/**
* Delete user
*
*
* #Route("/deleteUser/{user_id}", name="delete_user_from_id")
* #Template()
*/
public function deleteUserAction($user_id)
{
//....
return $this->redirect($this->generateUrl('acme_demo_homepage'));
}
Can we use annotations instead to avoid this extra line? Something like #redirect?
Nope, it is not possible.
Have a look into FrameworkExtraBundle. A redirect must be triggered in a controller (often after some logic ;) )

Resources