我有一个Project
实体,它有一个控制器定义了许多路径:
projects/1
projects/1/foo
projects/1/bar
我需要一项服务来提供当前项目。用例是我在我的基本树枝模板中有依赖关系,需要知道当前项目。即一个下拉项目选择器,它位于当前控制器正在服务的模板的上下文之外。
我尝试使用$container->get('router.request_context');
创建获取路由信息的服务,但是,它只提供路径。如果我不需要,我不想解析路径字符串。
最合适的方法是什么?
答案 0 :(得分:1)
如果我理解正确,问题的解决方案是渲染/嵌入控制器。当然,它是最简单的,但在某种程度上可接受的解决方案,用于使用除当前模板之外的一些自定义逻辑来呈现html的部分。
您可以阅读rendering/embedding controllers。
一些片段......
定义controller:action
(显然我的例子中的逻辑很简单):
/**
* Generate select input field.
*
* @Route("/widget", name="project_widget")
* @Method("GET")
*/
public function widgetAction()
{
$repo = $this->getDoctrine()
->getManager()
->getRepository('AppBundle:Project');
// #NOTICE: Wee need master request info, because our widget
// is rendered and called as subrequest.
$masterRequest = $this->get('request_stack')->getMasterRequest();
// #NOTICE: You need second parameter as default value in case there is no id in masterRequest route.
$currentProjectId = $masterRequest->get('id', 0);
$currentProject = $repo->find($currentProjectId);
$projects = $repo->findAll();
return $this->render('project/widget.html.twig', [
'currentProject' => $currentProject,
'projects' => $projects,
]);
}
然后你需要为它创建模板project/widget.html.twig
:
<div class="widget_project_selection">
{% if projects is not empty %}
<select name="widget_project_selection" id="widget_project_selection">
<option value="">None</option>
{% for project in projects %}
<option value="{{ project.id }}"
{# #NOTICE: If this is current project, select it #}
{{- currentProject and project.id == currentProject.id
? 'selected="selected"'
: '' -}}
>
{{- project.title -}}
</option>
{% endfor %}
</select>
{% else %}
<span>{{ 'Sadly, no projects yet :('|trans }}</span>
{% endif %}
</div>
最后(但并非最不重要)将其渲染到base.html.twig
中的某处:
{{- render(controller('AppBundle:Project:widget')) -}}
我为你创建了Github repo as reference。这是一个具有类似设置的小型Symfony应用程序。如果您愿意,您甚至可以运行它,不要忘记依赖关系和数据库更新。入口点为/app_dev.php/project/
查看base.html.twig
中的widgetAction,widget template和example usage。
编辑:但这不是一切。你说你需要一项服务。如果出于某种原因渲染/嵌入控制器不是您的选择,或者您真的想要使用Service
(如在Dependency Container
中),您可以extend Twig并使用full power of services
我还以Twig过滤器为例,向您展示了here和here (usage in templates)中Twig Extensions的真正威力。
有关Twig Extensions的更多信息,请查看Twig Extension和Extending Twig。
同时查看service.yml
了解服务和扩展定义 - 如果您不使用Symfony3.3 +,还需要做一些额外的工作 - defining service and extension directly。
答案 1 :(得分:-1)
在您的控制器中,您可以使用类型提示来加载&#34;当前&#34;实体通过路线。
例如:
#myrouter.yml
current_project:
path: /projects/{project}
另外,你的控制器......
//mycontroller.php
public function myControllerAction(Request $request, Project $project)
{
//$project is entity (assuming valid) loaded via the route above
return $this->render('mytemplate.twig', ['project' => $project]);
}