我想将给定请求 url 的查询参数自动复制到我的路由生成的所有 url。
可以说有人要求example.com/en?preview=true
。因此,我希望在此页面上生成的所有 url 也preview=true
自动附加查询参数,即不更新我所有的路由定义。
我尝试将预览参数添加为 onKernelRequest 侦听器中所有现有路由的默认值,但并没有走得太远。
提前致谢
我想将给定请求 url 的查询参数自动复制到我的路由生成的所有 url。
可以说有人要求example.com/en?preview=true
。因此,我希望在此页面上生成的所有 url 也preview=true
自动附加查询参数,即不更新我所有的路由定义。
我尝试将预览参数添加为 onKernelRequest 侦听器中所有现有路由的默认值,但并没有走得太远。
提前致谢
我自己通过扩展默认框架路由器解决了这个问题。
# src/Your/Bundle/Resources/config/service.yml
parameters:
router.class: Your\Bundle\Routing\PreviewRouter
<?php
// src/Your/Bundle/Routing/PreviewRouter.php
namespace Your\Bundle\Routing;
use Symfony\Bundle\FrameworkBundle\Routing\Router as BaseRouter;
/**
* extends the base router's generate function to always append
* the preview query param on all generated urls
*/
class PreviewRouter extends BaseRouter
{
public function generate($name, $parameters = array(), $referenceType = self::ABSOLUTE_PATH)
{
// parent router generates url
$url = parent::generate($name, $parameters, $referenceType);
// check for existing preview query string
parse_str($this->getContext()->getQueryString(), $contextQueryParams);
if(isset($contextQueryParams['preview']) && filter_var($contextQueryParams['preview'], FILTER_VALIDATE_BOOLEAN))
{
// put possible query string params into $queryParams array
$urlParts = parse_url($url);
parse_str(isset($urlParts['query']) ? $urlParts['query'] : '', $urlQueryParams);
// strip everything after '?' from generated url
$url = preg_replace('/\?.*$/', '', $url);
// append merged query string to generated url
$url .= '?'.http_build_query(array_merge(
array('preview' => $contextQueryParams['preview']),
$urlQueryParams
));
}
// remove preview param if set to false deliberately
$url = preg_replace('/(\?|&)preview=(false|0|off)/', '', $url);
return $url;
}
}
我有一个可能的实现,但是有一些警告。如果您生成的 url 上已经有查询字符串,这将不起作用。
您将需要创建一个新的 Twig 过滤器扩展。让我们从创建扩展类开始。您可能希望从 acme 演示中移动和更改它。
//src/Acme/DemoBundle/Twig/AcmeExtension.php
<?php
namespace Acme\DemoBundle\Twig;
class AcmeExtension extends \Twig_Extension
{
public function getFilters()
{
return array(
new \Twig_SimpleFilter('queryString', array($this, 'queryStringFilter')),
);
}
public function queryStringFilter($array)
{
return http_build_query($array);
}
public function getName()
{
return 'acme_extension';
}
}
然后,您需要将此新扩展注册为服务:
//src/Acme/DemoBundle/Resources/config/services.yml
parameters:
acme_demo.acme_extension.class: Acme\DemoBundle\Twig\AcmeExtension
services:
acme_demo.acme_extension:
class: %acme_demo.acme_extension.class%
tags:
- { name: twig.extension }
然后你需要在你的主配置中包含这个新服务:
//app/config/config.yml
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: "@AcmeDemoBundle/Resources/config/services.yml" }
然后,当您在树枝文件中生成路线时:
<a href="{{path('some_route_id')}}?{{app.request.query.all|queryString}}">This will have your query string appended.</a>
您可以将所有现有查询作为第二个参数添加到路径调用中:
<a href="{{ path('my_route', app.request.query.all)}}">My Link</a>