在每个 link 上保留查询字符串
Keep query-string on every link
我想通过让用户在顶部导航的选择框中选择一个城市来个性化我的 Symfony 项目。为此,我得到了一个查询字符串,例如?city=berlin,我在我的控制器中获取并过滤结果。
是否有一种简单的方法可以使每个 url 上的查询字符串保持活动状态,或者您更喜欢没有查询字符串的其他解决方案?也许用饼干?
感谢您的帮助!
如果您需要根据路由路径将用户限制在某些条件下(我建议您使用 SEO 网址而不是 GET 查询),然后将其用作其他页面上某些行为的过滤器,那么您可以这样做听众:
基础内核事件:
namespace App\CoreBundle\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
abstract class BaseKernelEvents
{
/**
* @var \Symfony\Bundle\FrameworkBundle\Routing\Router
*/
private $router;
/**
* Initializes a new instance of the KernelEvents class.
*/
public function __construct(ContainerInterface $container, Router $router)
{
$this->container = $container;
$this->router = $router;
}
/*
* Store and get value by route param passed to uri to request and session
*/
protected function storeParam(GetResponseEvent $event, $name, $default = 'none')
{
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
/* @var $session \Symfony\Component\HttpFoundation\Session\Session */
$session = $request->getSession();
// instead of attributes you can get query from request here
$value = $request->attributes->get($name);
if (!$value) {
$value = $session->get($name, $default);
}
return $this->setValues($event, $name, $value);
}
/*
* Set name/value to request context and session
*/
protected function setValues(GetResponseEvent $event, $name, $value)
{
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
$context = $this->router->getContext();
$session = $request->getSession();
$session->set($name, $value);
$context->setParameter($name, $value);
return $value;
}
}
内核事件:
namespace LaMelle\ContentSectionBundle\Listener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use App\CoreBundle\Listener\BaseKernelEvents;
class KernelEvents extends BaseKernelEvents
{
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType())
{
$contentsectionSlug = $this->storeParam($event, 'city');
// DO SOMETHINK BASE ON FILTER
// LIKE CREATE GLOBAL TWIG VAR WITH FILTER VALUE
/* @var \Twig_Environment $globals */
$globals = $this->container->get('twig');
$globals->addGlobal('city', $contentsectionSlug);
}
}
}
因此在所示示例中,您将从会话中填充 'city',直到您访问将 'city' 更改为其他值
的路线
比谈论 cookie 更好的是关于有状态或无状态会话的问题。 Cookies只是将客户端映射到session的实现。
假设您有一位访问者在一个城市参数化页面上。当有人复制 url 并与他人共享时,您除了让您的页面看起来像什么? city 不是任何个人状态,尽管你在上面提到了personalized(例如,具有响应页面,我可以将字体设置为 120% 大小或设置更高相比之下,将是一个个性化的配置我其实不想分享在 url).
city 是页面状态的一部分而不是会话,因此我们希望 city 成为 url 的一部分。定义一个前缀路由,如 /{city}
并导入另一个具有该前缀的 yml (http://symfony.com/doc/current/book/routing.html#prefixing-imported-routes).
每次生成带有城市的 url 时,您都必须对其进行设置。您可以手动执行此操作或创建一些 CityDecoratedRouter implements RouterInterface
以注入 @router
和 @request_stack
并将 city
参数附加到 generate()
中的所有 parameter
数组来电。
@EvgeniyKuzmin 的回答是恕我直言,魔法太多了,没人能想到。在处理那些具有 city
参数的路由时,最好在代码中阅读它,以区别对待路由。当然你还必须为 twig 定义一些新的 city_path
函数,它使用我们的 CityDecoratedRouter
.
我想通过让用户在顶部导航的选择框中选择一个城市来个性化我的 Symfony 项目。为此,我得到了一个查询字符串,例如?city=berlin,我在我的控制器中获取并过滤结果。
是否有一种简单的方法可以使每个 url 上的查询字符串保持活动状态,或者您更喜欢没有查询字符串的其他解决方案?也许用饼干?
感谢您的帮助!
如果您需要根据路由路径将用户限制在某些条件下(我建议您使用 SEO 网址而不是 GET 查询),然后将其用作其他页面上某些行为的过滤器,那么您可以这样做听众:
基础内核事件:
namespace App\CoreBundle\Listener;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Bundle\FrameworkBundle\Routing\Router;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
abstract class BaseKernelEvents
{
/**
* @var \Symfony\Bundle\FrameworkBundle\Routing\Router
*/
private $router;
/**
* Initializes a new instance of the KernelEvents class.
*/
public function __construct(ContainerInterface $container, Router $router)
{
$this->container = $container;
$this->router = $router;
}
/*
* Store and get value by route param passed to uri to request and session
*/
protected function storeParam(GetResponseEvent $event, $name, $default = 'none')
{
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
/* @var $session \Symfony\Component\HttpFoundation\Session\Session */
$session = $request->getSession();
// instead of attributes you can get query from request here
$value = $request->attributes->get($name);
if (!$value) {
$value = $session->get($name, $default);
}
return $this->setValues($event, $name, $value);
}
/*
* Set name/value to request context and session
*/
protected function setValues(GetResponseEvent $event, $name, $value)
{
/* @var $request \Symfony\Component\HttpFoundation\Request */
$request = $event->getRequest();
$context = $this->router->getContext();
$session = $request->getSession();
$session->set($name, $value);
$context->setParameter($name, $value);
return $value;
}
}
内核事件:
namespace LaMelle\ContentSectionBundle\Listener;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use App\CoreBundle\Listener\BaseKernelEvents;
class KernelEvents extends BaseKernelEvents
{
public function onKernelRequest(GetResponseEvent $event)
{
if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType())
{
$contentsectionSlug = $this->storeParam($event, 'city');
// DO SOMETHINK BASE ON FILTER
// LIKE CREATE GLOBAL TWIG VAR WITH FILTER VALUE
/* @var \Twig_Environment $globals */
$globals = $this->container->get('twig');
$globals->addGlobal('city', $contentsectionSlug);
}
}
}
因此在所示示例中,您将从会话中填充 'city',直到您访问将 'city' 更改为其他值
的路线比谈论 cookie 更好的是关于有状态或无状态会话的问题。 Cookies只是将客户端映射到session的实现。
假设您有一位访问者在一个城市参数化页面上。当有人复制 url 并与他人共享时,您除了让您的页面看起来像什么? city 不是任何个人状态,尽管你在上面提到了personalized(例如,具有响应页面,我可以将字体设置为 120% 大小或设置更高相比之下,将是一个个性化的配置我其实不想分享在 url).
city 是页面状态的一部分而不是会话,因此我们希望 city 成为 url 的一部分。定义一个前缀路由,如 /{city}
并导入另一个具有该前缀的 yml (http://symfony.com/doc/current/book/routing.html#prefixing-imported-routes).
每次生成带有城市的 url 时,您都必须对其进行设置。您可以手动执行此操作或创建一些 CityDecoratedRouter implements RouterInterface
以注入 @router
和 @request_stack
并将 city
参数附加到 generate()
中的所有 parameter
数组来电。
@EvgeniyKuzmin 的回答是恕我直言,魔法太多了,没人能想到。在处理那些具有 city
参数的路由时,最好在代码中阅读它,以区别对待路由。当然你还必须为 twig 定义一些新的 city_path
函数,它使用我们的 CityDecoratedRouter
.