Let me describe a situation. You have a profile form and a form where users can upload personal profile related documents. Since the profile form is already very long the documents moved to a new form.
Everything works great. Now we want to use the bootstrap tabs to do Profile | Documents for user friendliness.
Now I know because we are using two separate forms if you submit the documents the changes on the profile won't save and vice versa.
I have added the document form in the tab using
YoutubeIntents
The 'viewOnly': true is a query parameter and is not required by the action.
My question now becomes if the profile tab renders the document template it must only show the upload widget and the submit where as when you go directly to the document page it must show the title and side bar and everything.
So I tried
<!--Message-->
That gave problems because you can't use extends within a if(Causes a ("Node "1" does not exist for Node "Twig_Node".") error).
Other similar question provided this solution
<!-- Message -->
When viewOnly is false it must extend the base template used by all other templates but if it is true I only want to show this:
<div role="tabpanel" class="tab-pane" id="documents">
{{ render(controller('ManyAppBundle:Document:createDocument', {'viewOnly': true})) }}
</div>
But now with the top
{% if not viewOnly %}
{% extends ... %}
{% endif %}
if viewOnly becomes true it fails with Template "" can't be find.
Is there a way to say extends this specific template that will be the same result of not extending any template?
Or alternatively is there a way of saying extend this when viewOnly is false or just do nothing?
答案 0 :(得分:3)
基本上有3种解决方案可以确定如何在树枝模板中扩展不同类型的模板之间进行切换。
第一个是基于非常简单的真或假逻辑。您可以在twig文件中轻松完成此操作,如以下示例所示
{% extends entity.isExpired == false ? active.html.twig : expired.html.twig %}
第二个将是@Jeet建议在控制器中执行此操作。这也可以像布尔检查一样简单,但与其他实体检查一样先进,如下例所示
/* User Controller */
public function showAction($id)
{
$user = $this->get('myapp.repository.user')->findBy($id);
$isUser = $user instanceof User;
if (!$isUser) {
return $this->redirectToBloggersPage();
}
/* $params is what you will normally return to the template */
$params = array (
'user' => $user,
);
if ($user->hasPostedBlog()) {
$params['blog'] = $this->get('myapp.repository.blog')->findByUserLatest($user);
return $this->render('MyAppBundle:User:user_and_blog_view.html.twig', $params);
}
else {
return $this->render('MyAppBundle:User:user_view.html.twig', $params);
}
}
第三个将是@Thomas建议在单独的枝条功能中执行此操作。这将在Twig扩展中完成,您可以在其中注入服务,如以下示例所示
/* Twig extension */
public function extendBookForm()
{
if ($this->getSecurityContext()->isGranted('IS_AUTHENTICATED_FULLY')) {
return "user_view.html.twig";
}
return "public_view.html.twig";
}
/* Twig file */
{% extends extend_book_from() %}
我原来的问题没有解决我想要的结果。我认为我想要的方式是不可能的,如果你动态地想要检查扩展内容,你必须总是扩展多个模板,因为你必须为每个结果扩展一些东西。
这些是您可以通过不同的方式进行动态模板扩展。
答案 1 :(得分:1)
虽然我更喜欢Jeet的解决方案,但这里有更复杂的选择。请记住,此解决方案仅具有教育意义。
extend_from
(请参阅下面的示例代码)。Twig功能可能如下所示:
/**
* Returns the template to be extended
* Notes: Code assumes that the request data is a protected property
* on the Twig extension.
*
* @param string $template = "full.html.twig" the full layout template
* @return string the template to be extended
*/
public function extendFrom($template = "full.html.twig")
{
if ($this->request->query->get('view-only') === true) {
return "empty_layout.html.twig";
}
return $template;
}
在你的模板中:
{# Templates assumes that your extended templates have a "content block" #}
{% extends extend_from() %}
{% block content %}
{# Your template content here #}
{% endblock %}
它有点像魔法&#34;解决方案给我。最好的方法是将您的内容视为一个模块。您可以单独渲染它,也可以将其包含在布局中。
例如在my project中:
将来,我可以渲染整个页面,页面的一部分或该页面中的一个模块。
它有点复杂,但它变得非常强大,这些BaseThemeBundle允许我覆盖任何模板。
答案 2 :(得分:0)
我对这个问题的解决方案是创建一个只包含此内容的empty.html视图
{% block content %}
{% endblock %}
这不是一个很好的解决方案,但是比其他一些方法简单得多,因此我不必添加更多的混乱情况。