Get current route in Symfony 3.3 and Twig - symfony

I would like to have the current route in Symfony 3 in a Twig view.
I already did some research, but I didn't find any solution. I try the following in my Twig view:
{{ app.request.uri }}
It returns something like: http://localhost:8000/_fragment?_path=_format%3Dhtml%26_locale%3Dfr%26_controller%3DFOSUserBundle%253ASecurity%253Alogin
{{ app.request.get('_route') }}
Always returns NULL.
{{ app.request.getpathinfo }}
Always have: /_fragment
What I need is very simple. For an URL like localhost:8000/article/5, I would like to retrieve /article/5.How to do this?

The following code snippet will do the trick:
{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')) }}
app.request.attributes.get('_route') - returns current route name.
app.request.attributes.get('_route_params') - returns current route params.
path() - generates route path by route name and params.
This approach will not work for forwarded requests. In case of forward request, there is a workaround: you should pass "_route" and "_route_params" to a forwarded params list.
return $this->forward('Yourbundle:Controller:action', array(
//... your parameters...,
'_route' => $this->getRequest()->attributes->get('_route'),
'_route_params' => $this->getRequest()->attributes->get('_route_params');
));
Also you can use app.request to access any Request object functions, such as getPathInfo(), which should return current route path.
{{ app.request.pathInfo }}

Related

How to change template of controller rendered in twig file (Symfony 3)?

I know that we can render the content of a controller in twig file like this:
{{ render(controller('FOSUserBundle:Security:login',{"baseTemplate": true})) }}
However, I don't know if we can pass the new template so that the controller will use it instead of the default. Anyone tried to override template in this way?
I don't really understand the issue here
If you do
{{ render(controller('FOSUserBundle:Security:login',{"baseTemplate": true})) }}
You could aswell do:
{{ render(controller('FOSUserBundle:Security:login',{"template": "your_template.html.twig"})) }}
Or
{{ render(controller('FOSUserBundle:Security:login',{"templateNumber": "4"})) }}
Where templateNumber is used in a condition inside your controller ?

How to pass an array in a redirect

I'm trying to pass an array in a redirect
$qtedispo = array($x,$c,$s);
return $this->redirect($this->generateUrl('demandeveh_afficherConf',array('qte'=>$qtedispo));
but when i try to call that array in twig
{%for q in qte %}
{{qte[0]}}
{%endfor%}
it tells me that the variable qte is unknown. Any help please?
You are making an HTTP redirection with an array as parameter.
If the route (on which you are making the redirection) is waiting for an argument (e.g. function afficherConf(array $qte)), you have to go into and pass the $qte parameter to the rendered template.
For instance:
// _controller part of to route "demandeveh_afficherConf"
public function afficherConfAction(array $qte)
{
// ...
return $this->render('AppBundle:Demandeveh:afficherConf.html.twig', array('qte' => $qte));
}
Then in the template ("afficherConf.html.twig" for this example), you should be able to do:
{% for q in qte %}
{{ q }}
{% endfor %}
Depending on the number of dimensions of your $qte var.
Note:
You should have a look at the doc.

Symfony -- Twig's trans filter not picking up locale

I have verified that if I add the following line to my twig template, it outputs the desired locale:
{{ app.request.locale }}
However, the following is outputting in English:
{{ 'String'|trans }}
If I force the locale of the trans filter:
{{ 'String'|trans({}, 'messages', 'ja') }}
It outputs in the proper translation. Note that I'm setting the locale using an eventListener:
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
$locale = $request->cookies->get('_locale') ? $request->cookies->get('_locale') : $request->getPreferredLanguage($this->availableLanguages);
$request->setLocale($locale);
}
I figured out the answer through Symfony Documentation:
Setting the locale using $request->setLocale() in the controller is too late to affect the translator.
Either set the locale
Via a Listener (like above)
Via the URL (see next)
Or call setLocale() directly on the Translator Service.
I ended up fixing it by changing the priority of the service, like the accepted answer in this thread: Symfony 2.1 set locale
Mabey a late reply but I was facing the same problem, after a bit of reading i found a better solution. You can use the trans function instead of the trans filter which seems to be a cleaner solution.
{% trans from "your-trans-domain" into app.user.locale %} trans.key {% endtrans %}
See symfony docs:
Docs v2.7 for translations

Passing all parameters as array and changing one of them

I am passing an array of get arguments from controller to twig template, and then create a link:
{{ url('route_name', array_of_get_parameters) }}
It works, but what if I want to pass all BUT ONE of those parameters unchanged? Something like:
{{ url('route_name', array_of_get_parameters, {'param1': 'value'}) }}
The example above doesn't work of course...is there a way to do this?
Use twig merge filter like this:
{{ url('route_name', array_of_get_parameters|merge({'param1': 'value'})) }}
You cannot do this.
Instead override the value in the controller (<- better) or in the twig template, before the url generation.

How to get the current page name in Silex

I'm wondering how to get the current page name, basically 'just' the last parameter in the route (i.e. /news or /about). I'm doing this because I want to be able to have the current page in the navigation highlighted.
Ideally, I'd like to store the current page name in a global variable so that in Twig I can just compare the current page name against the link and add a class accordingly.
I can't figure out how to add the current page name to a global variable though. I've tried using something like this:
$app['twig']->addGlobal('current_page_name', $app['request']->getRequestUri());
at the top of my app.php file, but an 'outside of request scope' error. But I wouldn't like to have to include this in every route.
What's the best way to do this?
If you put it into an app-level before middleware like this, that'll work:
$app->before(function (Request $request) use ($app) {
$app['twig']->addGlobal('current_page_name', $request->getRequestUri());
});
The "page name" part of your question is unclear, are you looking for the current route's name? You can access that via $request->get("_route") even in the before middleware, as it gets called when routing is already done.
You could also generate navigation list directly in stand alone nav twig template. And then import it in to the main template. Then you would only have to get silex to pass to the view the current page identifier. Simplest way... for example from Silex you would have to pass in the "path" variable to your view. Probably it would more convenient to to fetch nav_list from database and pass it in to twig template as global array variable instead. However this example is the simplest you could get to do what you intend.
nav.twig
{% set nav_list = [
["./", "home"],
["./contact", "contact"],
["./about", "about us"]
{# ... #}
] %}
{% set link_active = path|default("") %}
{% for link in nav_list %}
<li><a href="{{ link[0] }}" class="{% if link[0] == link_active %} activeClass {% endif %}" >{{ link[1] }}</a></li>
{% endfor %}
app.php
//...
$app->match('/about', function (Request $request) use ($app) {
return $app['twig']->render('about.twig', array(
'path' => './'.end(explode('/', $request->getRequestUri()))
));
});
//...

Resources