我有一篇文章实体,实际上我用3个模板路径()功能,提供的第二个参数文章的蛞蝓,以便获得url显示一文。
我知道这是不是做的最好的方法,因为,例如,如果我想提供ID,而不是塞的,我应该在多个模板修改代码。
我想在文章类,但比我不能使用路由服务来生成URL中使用到getURL()方法。
有没有更好的方式来做到这一点在Symfony的4?
这是ArticleController的一部分:
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\Article;
use App\Repository\ArticleRepository;
class ArticleController extends AbstractController
{
...
/**
* @Route("/article/{slug}", name="article_show")
*/
public function show(Article $article) {
return $this->render('article/show.html.twig', [
'article' => $article
]);
}
}
然后在模板中我有一个类似这样的代码:
{% for article in articles %}
...
<a href="{{ path('article_show',{ 'slug': article.slug } ) }}">
{{ article.title }}
</a>
...
{% endfor %}
我想这样做是有这样的代码:
{% for article in articles %}
...
<a href="{{ article.getUrl() }}">
{{ article.title }}
</a>
...
{% endfor %}
其中的getURL确实路径()方法的工作,所以如果我改变将在所有模板中反映出来的路线的东西,但我不能这样做,因为我无法获取的实体条路线服务。
那么,有没有实现同一个目标的另一种方式?
你所寻找的是达到预期效果的错误的方式。对于这个工作,你将不得不路由器注入基本上把它变成“商业逻辑”(例如控制器),而不是“持续性”,打破了单一职责原则的实体。除了很难实现技术上,你将不得不修改主义的内部
有两种方法来妥善处理这二者均涉及定制嫩枝扩展:
最简单的是定义一个自定义过滤器枝杈这需要生成正确的URL的护理:
<?php
namespace App\Twig\Extension;
use App\Entity\Article;
use Symfony\Component\Routing\RouterInterface;
use Twig\Extension\AbstractExtension;
use Twig\TwigFilter;
class ArticleExtension extends AbstractExtension
{
private $router;
public function __construct(RouterInterface $router)
{
$this->router = $router;
}
public function getFilters()
{
return [
new TwigFilter('article_url', [$this, 'getArticleUrl']),
];
}
public function getArticleUrl(Article $article): string
{
return $this->router->generate('article_show', ['slug' => $article->getSlug()]);
}
}
然后在树枝你只需要使用过滤器是这样的:
{% for article in articles %}
...
<a href="{{ article|article_url }}">
{{ article.title }}
</a>
...
{% endfor %}
如果您使用的Symfony 3.4+与awtowiring /自动配置刚刚创建的类就足够了,否则你需要将它注册为容器树枝延伸。请参考Symfony's documentation了解更多详情
如果你想重用视图/模板以外的路径产生提到的第二个选项才是必需的。在这种情况下必要的逻辑(这是现在在枝条延长)必须被移动到一个单独的独立的服务。然后,你就必须注入此服务为延伸,并使用它,而不是直接调用路由器。检查相关documentation entry了详细的步行槽上创建/注册服务
我不明白为什么一个企业实体应该知道的路由系统。
如果你想它的URL知道由实体,只需添加一个setUrl()
和getUrl()
方法在实体和存储它已经生成的URL