207

I looked around for the code to get the current path in a Twig template (and not the full URL), i.e. I don't want http://www.sitename.com/page, I only need /page.

Syscall
  • 19,327
  • 10
  • 37
  • 52
Mark Cibor
  • 2,737
  • 4
  • 21
  • 23
  • 11
    This is NOT an exact duplicate, as answer #2 contains necessary information (about request parameters) that the linked question doesn't provide. One should merge the answer #2 into the linked question. – Victor Sergienko Jun 18 '12 at 10:33
  • 2
    try app.request.requestUri. – Kristóf Dombi Dec 30 '12 at 18:37
  • 8
    Not a dupe at all. Voting to reopen. Posting my answer as a comment because I'm not allowed to answer now... `{{ app.request.getBaseUrl ~ app.request.getPathInfo }}` (`getBaseUrl` bit is optional; only needed if not installed to root of domain) – mpen Oct 26 '13 at 02:03

8 Answers8

281
{{ path(app.request.attributes.get('_route'),
     app.request.attributes.get('_route_params')) }}

If you want to read it into a view variable:

{% set currentPath = path(app.request.attributes.get('_route'),
                       app.request.attributes.get('_route_params')) %}

The app global view variable contains all sorts of useful shortcuts, such as app.session and app.security.token.user, that reference the services you might use in a controller.

Kevin Kopf
  • 13,327
  • 14
  • 49
  • 66
Rodney Folz
  • 6,709
  • 2
  • 29
  • 38
  • 11
    unfortunately, this will not work if you have a route with mandatory parameters. – Martin Schuhfuß Jun 01 '12 at 13:18
  • 1
    If you are using Twig without Symfony you can do something like this: $twig->addGlobal("CurrentUrl", $_SERVER["REQUEST_URI"]); – GateKiller Nov 16 '12 at 16:50
  • 1
    If your route has mandatory parameters, see [the answer below](http://stackoverflow.com/a/9384118/328817). – Sam May 02 '14 at 08:56
  • @GateKiller This made my Functional Test Fail: `Uncaught PHP Exception PHPUnit_Framework_Error_Notice: "Undefined index: REQUEST_URI"` – Robin Aug 15 '14 at 10:18
  • You can also use `app.request.get('_route')` (.attributes is optional). Tested in symfony 3.2.6, not sure of older versions. – robbe clerckx Apr 04 '17 at 15:01
263

Get current url: {{ app.request.uri }} in Symfony 2.3, 3, 4, 5


Get path only: {{ app.request.pathinfo }} (without parameters)


Get request uri: {{ app.request.requesturi }} (with parameters)

Boschman
  • 825
  • 1
  • 10
  • 17
  • 1
    This is the only one that worked for me. All the others missed out query parameters that weren't part of the route, or relied on the controller and rather than Twig. – Craig Feb 18 '14 at 21:03
  • 13
    To get the path only try ```{{ app.request.pathinfo }}``` or see a list of available methods in ```/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php``` – Michael Jun 19 '14 at 14:52
  • 5
    This should be the correct answer. Short and smooth. – fabpico Aug 04 '17 at 09:10
  • 2
    `uri` gets the URL with parameters. `pathinfo` gets the path with *NO* parameters. `requestUri` gets the path *WITH* parameters. `requestUri` should be added to this answer IMO. You'll rarely need the domain, and you'll rarely want to remove the parameters. – rybo111 Jun 04 '19 at 12:56
  • 1
    If you are behind a reverse proxy/load balancer, ensure to properly set `trusted_{proxies,hosts,headers}` in `config/packages/framework.yaml` (Symfony 5.2+). Ensure also your reverse proxy/load balancer sends the `X-Forwarded-{For,host,Proto,Port}` headers to Symfony. – Benoit Duffez Jun 21 '21 at 13:38
119

In symfony 2.1 you can use this:

{{ path(app.request.attributes.get('_route'), 
        app.request.attributes.get('_route_params')) }}

In symfony 2.0, one solution is to write a twig extension for this

public function getFunctions()
{
    return array(
        'my_router_params' => new \Twig_Function_Method($this, 'routerParams'),
    );
}

/**
 * Emulating the symfony 2.1.x $request->attributes->get('_route_params') feature.
 * Code based on PagerfantaBundle's twig extension.
 */
public function routerParams()
{
    $router = $this->container->get('router');
    $request = $this->container->get('request');

    $routeName = $request->attributes->get('_route');
    $routeParams = $request->query->all();
    foreach ($router->getRouteCollection()->get($routeName)->compile()->getVariables() as $variable) {
        $routeParams[$variable] = $request->attributes->get($variable);
    }

    return $routeParams;
}

And use like this

{{ path(app.request.attributes.get('_route'), my_router_params()|merge({'additional': 'value'}) }}

You won't need all this unless you want to add additional parameters to your links, like in a pager, or you want to change one of the parameters.

Bártfai Tamás
  • 2,444
  • 2
  • 18
  • 6
  • 11
    If you want to generate the current link in Twig and change the locale for language switching, it can be done in Symfony 2.1 as follows: {{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'ja'})) }} It may work if you use the the Twig extension by Bártfai Tamás – Naytzyrhc Aug 02 '12 at 04:05
  • For your 2.0 implementation, I get an error saying that there's no container. So I added the variable as is done in PagerfantaBundle, but then it says I have to implement the ContainerInterface? – Squazic Aug 09 '12 at 21:31
  • You have to create a constructor for this extension, which has a $container parameter. Then in the DIC config you have to declare the container as a parameter for the extension. [Like here in the TwigBundle](https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml#L54) – Bártfai Tamás Aug 10 '12 at 07:23
  • 12
    The _route_parameters won't work if you have some additional params in your query string. You could use app.request.query.all instead. – wdev Nov 26 '12 at 17:42
43

You can get the current URL in Twig like this:

{{ app.request.schemeAndHttpHost ~ app.request.requestUri }}
user5670895
  • 1,488
  • 17
  • 29
Zaheer Babar
  • 1,636
  • 1
  • 15
  • 17
24

It should be noted that if you have additional query parameters in your URL, which are not part of the configured route, the accepted answer will not include them in the current URL (path).

Why would you want extra parameters?

For example, if you have a list page with records that can be filtered by keyword and the page has pagination, most likely the query variables for "keyword" and "page" will not be in your route. But in your forward and back buttons for paging, you need the full current URL (that contains the keywords so the next page is still filtered). And you need to modify the page variable.

How to Merge In Extra Query Parameters

So you can get the current route, and merge in the extra variables (after modifying one or more of those extra variables). Note that you are merging in your own variables to the app.request.query.all, and then merging that array into the app.request.attributes.get('_route_params'). The path() method requires that you provide all the required parameters of the route, which is why you need to include the _route_params.

{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge(app.request.query.all|merge({'page': 2 }))) }}

That's really ugly, but if you are developing pagination, you will need to modify the page variable on each separate link, so you have to include the whole thing each time. Perhaps others have a better solution.

Chadwick Meyer
  • 7,041
  • 7
  • 44
  • 65
  • 2
    Probably should be `{{ path(app.request.attributes.get('_route'), app.request.query.all|merge(app.request.attributes.get('_route_params'))) }}` – FDisk Feb 09 '16 at 15:27
3

Using Symfony 5 you can use this:

{{ app.request.uri }}
L3xpert
  • 1,109
  • 1
  • 10
  • 19
2

If you are using Silex 2 you can not access the Request object anymore.

You can access the current request attributes this way.

app.request_stack.currentrequest.attributes.get('_route')

And to generate the full current URL : path(app.request_stack.currentrequest.attributes.get('_route'), app.request_stack.currentrequest.attributes.get('_route_params'))

Tim
  • 1,238
  • 1
  • 14
  • 24
  • 1
    You can get the current URL in Twig/Silex 2 like this: `global.request.attributes.get('_route')`. [Twig bridge](https://silex.sensiolabs.org/doc/2.0/providers/twig.html#global-variable) is required. – dsoms Jun 07 '17 at 15:03
1

In a Shopware 6 Twig file, you may use one of the sw-* attributes defined in Framework/Routing/RequestTransformer.php:

{% set currentUrl = app.request.attributes.get('sw-original-request-uri') %}

/some/path?param=1

Anse
  • 1,573
  • 12
  • 27