使用 Symfony 和 twig 重定向回来
Redirect back with Symfony and twig
在我的 Symfony 项目中,我有两种观点。特定实体的详细信息视图和一个按钮,通过日期参数将我带到一个新视图以及一些其他数据。
我的代码的问题是从第二种方法返回到第一种方法生成 'Return to previous' 页面按钮..
代码:
/**
* @Route("/details/{id}", name="first_method")
*/
public function firstMethod(Detail $id)
{
$workspace = $this->entityManager
->getRepository(Detail::class)
->find($id);
$build['detail'] = $detail;
$form = $this->createFormBuilder()
->add('date', DateTimeType::class, [
'data' => new \DateTime(),
'widget' => 'single_text'
])
->add(
'save',
SubmitType::class,
[
'attr' => ['class' => 'btn-submit']
]
)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$date = $data['date']
return $this->redirectToRoute('second_method', [
'date' => $date
]);
}
return $this->render('first-method.html.twig', [
'detail' => $detail,
]);
}
还有那个 'second' 方法:
/**
* @Route("/second-method/{date}", name="second_method")
*/
public function secondMethod($date)
{
return $this->render('second-method.html.twig', [
'someData' => $someData,
'date' => $date,
]);
}
我在 second_method 树枝视图上有一个按钮需要 return 我回到 method_one 页面。
如何实现,因为第二种方法可能需要参数 $id,但找不到提供它的方法。也许还有其他方法?有人可以帮忙吗?
我认为我应该喜欢第一种方式:
{{ path('first_method', {'detailId':detail.id}) }}
正如@msg 所暗示的,您应该为第二个页面提供第二个参数。然后,您将需要 @Entity
注释用于 Detail
转换和 @ParamConverter
注释用于日期转换:
/**
* @Route("/second_method/{id_detail}/{date}", name="second_method")
* @Entity("detail", expr="repository.find(id_detail)")
* @ParamConverter("date", options={"format": "!Y-m-d"})
*/
public function (Detail $detail, \DateTime $date)
// ...
参数转换将执行第一次完整性检查,如果实体不存在,将 return 和 404
。
您还可以在控制器中检查 $detail
是否与 URL 中的 date
一致。请记住:永远不要相信用户输入(这包括 URLs)。
并且您可以在重定向到第二个控制器时提供这个新参数:
return $this->redirectToRoute("second_method", [
"date" => $date,
"id_detail" => $workspace->getId() // You can also pass the whole object and fetch the ID in the template
]);
然后在您的模板中:
{{ path('first_method', {'id': id_detail}) }}
详情
对于 ParamConverters
,您可以在此处找到更多详细信息:https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
我个人更喜欢 @Entity
注释来转换 Entity
,因为您确定转换是如何完成的:我发现当您的项目增长并且您的实体有更多和更多参数。尽管 @ParamConverter
适合您的情况。
不改变 second_method
路由参数的替代方案,仅依赖于 referer。
将辅助方法添加到控制器:
/**
* Returns the referer url to redirect back if the request came from first_method
* Otherwise returns FALSE.
*/
private function getBackUrl(Request $request, UrlMatcherInterface $matcher)
{
$referer = $request->headers->get('referer');
if (null === $referer) {
return false;
}
$url = parse_url($referer);
if ($url['host'] != $request->getHost()) {
return false;
}
// Remove the baseurl if we're in a subdir or there's no Rewrite
$path = str_replace($request->getBaseUrl(), '', $url['path']);
try {
$route = $matcher->match($path);
} catch (ResourceNotFoundException $e) {
// Doesn't match any known local route
return false;
}
// A route has been determined, check if it matches the requirement
if ('first_method' == $route['_route']) {
return $referer;
}
return false;
}
将方法更改为(Route
注释未更改,只是方法签名更改):
public function secondMethod($date, Request $request, UrlMatcherInterface $matcher)
{
return $this->render('second-method.html.twig', [
'someData' => $someData,
'date' => $date,
'back_url' => $this->getBackUrl($request, $matcher),
]);
}
在您的模板中:
{# Show the button only if the request came from first_method (otherwise will be false) #}
{% if back_url %}
<a class="btn" href="{{ back_url }}">Return</a>
{% endif %}
在我的 Symfony 项目中,我有两种观点。特定实体的详细信息视图和一个按钮,通过日期参数将我带到一个新视图以及一些其他数据。
我的代码的问题是从第二种方法返回到第一种方法生成 'Return to previous' 页面按钮..
代码:
/**
* @Route("/details/{id}", name="first_method")
*/
public function firstMethod(Detail $id)
{
$workspace = $this->entityManager
->getRepository(Detail::class)
->find($id);
$build['detail'] = $detail;
$form = $this->createFormBuilder()
->add('date', DateTimeType::class, [
'data' => new \DateTime(),
'widget' => 'single_text'
])
->add(
'save',
SubmitType::class,
[
'attr' => ['class' => 'btn-submit']
]
)
->getForm();
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$data = $form->getData();
$date = $data['date']
return $this->redirectToRoute('second_method', [
'date' => $date
]);
}
return $this->render('first-method.html.twig', [
'detail' => $detail,
]);
}
还有那个 'second' 方法:
/**
* @Route("/second-method/{date}", name="second_method")
*/
public function secondMethod($date)
{
return $this->render('second-method.html.twig', [
'someData' => $someData,
'date' => $date,
]);
}
我在 second_method 树枝视图上有一个按钮需要 return 我回到 method_one 页面。
如何实现,因为第二种方法可能需要参数 $id,但找不到提供它的方法。也许还有其他方法?有人可以帮忙吗?
我认为我应该喜欢第一种方式:
{{ path('first_method', {'detailId':detail.id}) }}
正如@msg 所暗示的,您应该为第二个页面提供第二个参数。然后,您将需要 @Entity
注释用于 Detail
转换和 @ParamConverter
注释用于日期转换:
/**
* @Route("/second_method/{id_detail}/{date}", name="second_method")
* @Entity("detail", expr="repository.find(id_detail)")
* @ParamConverter("date", options={"format": "!Y-m-d"})
*/
public function (Detail $detail, \DateTime $date)
// ...
参数转换将执行第一次完整性检查,如果实体不存在,将 return 和 404
。
您还可以在控制器中检查 $detail
是否与 URL 中的 date
一致。请记住:永远不要相信用户输入(这包括 URLs)。
并且您可以在重定向到第二个控制器时提供这个新参数:
return $this->redirectToRoute("second_method", [
"date" => $date,
"id_detail" => $workspace->getId() // You can also pass the whole object and fetch the ID in the template
]);
然后在您的模板中:
{{ path('first_method', {'id': id_detail}) }}
详情
对于 ParamConverters
,您可以在此处找到更多详细信息:https://symfony.com/doc/current/bundles/SensioFrameworkExtraBundle/annotations/converters.html
我个人更喜欢 @Entity
注释来转换 Entity
,因为您确定转换是如何完成的:我发现当您的项目增长并且您的实体有更多和更多参数。尽管 @ParamConverter
适合您的情况。
不改变 second_method
路由参数的替代方案,仅依赖于 referer。
将辅助方法添加到控制器:
/**
* Returns the referer url to redirect back if the request came from first_method
* Otherwise returns FALSE.
*/
private function getBackUrl(Request $request, UrlMatcherInterface $matcher)
{
$referer = $request->headers->get('referer');
if (null === $referer) {
return false;
}
$url = parse_url($referer);
if ($url['host'] != $request->getHost()) {
return false;
}
// Remove the baseurl if we're in a subdir or there's no Rewrite
$path = str_replace($request->getBaseUrl(), '', $url['path']);
try {
$route = $matcher->match($path);
} catch (ResourceNotFoundException $e) {
// Doesn't match any known local route
return false;
}
// A route has been determined, check if it matches the requirement
if ('first_method' == $route['_route']) {
return $referer;
}
return false;
}
将方法更改为(Route
注释未更改,只是方法签名更改):
public function secondMethod($date, Request $request, UrlMatcherInterface $matcher)
{
return $this->render('second-method.html.twig', [
'someData' => $someData,
'date' => $date,
'back_url' => $this->getBackUrl($request, $matcher),
]);
}
在您的模板中:
{# Show the button only if the request came from first_method (otherwise will be false) #}
{% if back_url %}
<a class="btn" href="{{ back_url }}">Return</a>
{% endif %}