在Twig模板中获取当前URL?

208

我在查找Twig模板中获取当前路径的代码(而不是完整的URL),即我不需要http://www.sitename.com/page,我只需要/page


11
这并不是完全相同的问题,因为回答 #2 包含了链接问题中没有提供的必要信息(关于请求参数)。应该将回答 #2 合并到链接问题中。 - Victor Sergienko
2
尝试使用 app.request.requestUri。 - Kristóf Dombi
8
完全不是重复。投票要求重新开放。我将我的答案发布为评论,因为现在无法回答... {{ app.request.getBaseUrl ~ app.request.getPathInfo }}(如果未安装到域的根目录,则需要 getBaseUrl 部分是可选的) - mpen
8个回答

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

如果你想将其读入一个视图变量:

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

app 全局视图变量包含各种有用的快捷方式,例如 app.sessionapp.security.token.user,它们引用你在控制器中可能使用的服务。


11
如果你的路由包含必填参数,那么很遗憾这种方法行不通。 - Martin Schuhfuß
1
如果您在没有Symfony的情况下使用Twig,可以像这样做:$twig->addGlobal("CurrentUrl", $_SERVER["REQUEST_URI"]); - GateKiller
1
如果你的路由有必填参数,请参考下面的答案 - Sam
@GateKiller 这导致我的功能测试失败:Uncaught PHP Exception PHPUnit_Framework_Error_Notice: "Undefined index: REQUEST_URI" - Robin
非常感谢您提供的精彩答案,非常有帮助! - Vahe Shadunts
你也可以使用 app.request.get('_route')(.attributes是可选的)。在symfony 3.2.6中测试过,旧版本不确定。 - robbe clerckx

265

获取当前URL:{{ app.request.uri }}Symfony 2.3, 3, 4, 5


仅获取路径:{{ app.request.pathinfo }}(不带参数)


获取请求URI:{{ app.request.requesturi }}(带参数)


1
这是唯一一种对我有效的方法。所有其他方法都会漏掉那些不属于路由的查询参数,或者依赖于控制器而不是Twig。 - Craig
13
获取路径可以尝试使用{{ app.request.pathinfo }},或查看/vendor/symfony/http-foundation/Symfony/Component/HttpFoundation/Request.php中可用方法的列表。 - Michael
5
这应该是正确答案。简短流畅。 - fabpico
2
uri 获取带参数的 URL。pathinfo 获取不带参数的路径。requestUri 获取带参数的路径。在我看来,应该将 requestUri 添加到这个答案中。你很少需要域名,也很少想要删除参数。 - rybo111
1
如果您在反向代理/负载均衡器后面,请确保在config/packages/framework.yaml(Symfony 5.2+)中正确设置trusted_{proxies,hosts,headers}。还要确保您的反向代理/负载均衡器将X-Forwarded-{For,host,Proto,Port}头信息发送到Symfony。 - Benoit Duffez

119
在Symfony 2.1中,您可以使用以下代码:
{{ path(app.request.attributes.get('_route'), 
        app.request.attributes.get('_route_params')) }}
在Symfony 2.0中,一种解决方法是编写一个Twig扩展来实现这一点。
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;
}

并像这样使用

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

除非你想要在链接中添加额外的参数(例如在页面导航中),或者你想要更改其中一个参数,否则你不需要这些内容。


11
如果你想在Twig中生成当前链接并更改区域设置以进行语言切换,可以在Symfony 2.1中按如下方式完成: {{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge({'_locale': 'ja'})) }}如果使用Bártfai Tamás的Twig扩展程序,它可能有效。 - Naytzyrhc
对于您的2.0实现,我收到一个错误,说没有容器。因此,我像PagerfantaBundle中所做的那样添加了变量,但然后它说我必须实现ContainerInterface? - Squazic
你需要为这个扩展创建一个构造函数,其中包含一个$container参数。然后在DIC配置中,你需要将容器声明为扩展的参数。就像TwigBundle中的这样 - Bártfai Tamás
12
如果查询字符串中有一些额外的参数,那么_route_parameters将无法起作用。你可以使用app.request.query.all代替。 - wdev

43

您可以这样在Twig中获取当前URL:

{{ app.request.schemeAndHttpHost ~ app.request.requestUri }}

24
应注意,如果您的URL中有额外的查询参数,并且这些参数不是配置的路由的一部分,则接受的答案将不会在当前URL(路径)中包含它们。
为什么要添加额外的参数?
例如,如果您有一个记录列表页面,可以通过关键字进行过滤,并且页面具有分页功能,那么“关键字”和“页面”的查询变量很可能不在路由中。但是,在翻页的前进和后退按钮中,您需要完整的当前URL(包含关键字,以便下一页仍然被过滤)。并且您需要修改页面变量。
如何合并额外的查询参数
因此,您可以获取当前路由,并合并额外的变量(在修改一个或多个这些额外变量后)。请注意,您正在将自己的变量合并到 app.request.query.all 中,然后将该数组合并到 app.request.attributes.get('_route_params') 中。 path() 方法要求您提供路线的所有必需参数,这就是为什么您需要包括 _route_params{{ path(app.request.attributes.get('_route'), app.request.attributes.get('_route_params')|merge(app.request.query.all|merge({'page': 2 }))) }} 虽然这看起来很丑陋,但如果您正在开发分页功能,则需要在每个单独的链接上修改页面变量,因此每次都必须包含整个内容。也许其他人有更好的解决方案。

2
可能应该是 {{ path(app.request.attributes.get('_route'), app.request.query.all|merge(app.request.attributes.get('_route_params'))) }} - FDisk

3

使用 Symfony 5 ,您可以使用以下内容:

{{ app.request.uri }}

2

如果你正在使用 Silex 2,就不能再访问 Request 对象了。

你可以通过以下方式访问当前请求的属性。

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

为了生成完整的当前URL: path(app.request_stack.currentrequest.attributes.get('_route'), app.request_stack.currentrequest.attributes.get('_route_params'))

1
您可以像这样在Twig/Silex 2中获取当前URL:global.request.attributes.get('_route')。需要Twig桥接器 - dsoms

1
在Shopware 6 Twig文件中,您可以使用 Framework/Routing/RequestTransformer.php 中定义的一个 sw- * 属性:
{% set currentUrl = app.request.attributes.get('sw-original-request-uri') %}

/some/path?param=1 一些/路径?参数=1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接