繁体   English   中英

Symfony和Twig模板。 如何动态扩展模板或什么都不扩展?

[英]Symfony and Twig templates. How to dynamically extend a template or extend nothing?

让我来描述一下情况。 您有一个个人资料表单和一个表单,用户可以上传个人资料相关文档。 由于配置文件表单已经很长,文档已移动到新表单。

一切都很好。 现在我们要使用bootstrap选项卡来执行Profile | 用户友好的文件。

现在我知道,因为如果您提交文档,我们使用两个单独的表单,配置文件中的更改将无法保存,反之亦然。

我已经在选项卡中添加了文档表单

<div role="tabpanel" class="tab-pane" id="documents">
    {{ render(controller('ManyAppBundle:Document:createDocument', {'viewOnly': true})) }}
</div>

'viewOnly':true是一个查询参数,操作不需要。

我现在的问题是,如果配置文件选项卡呈现文档模板,它必须只显示上传小部件和提交,当你直接进入文档页面时,它必须显示标题和侧栏以及所有内容。

所以我试过了

{% if not viewOnly %}
    {% extends ... %}
{% endif %}

这给出了问题,因为你不能在if中使用extends(导致a(“Node”1“不存在Node”Twig_Node“。”)错误)。

其他类似问题提供了此解决方案

{% extends viewOnly == false ? ... %}

当viewOnly为false时,它必须扩展所有其他模板使用的基本模板,但如果为true,我只想显示:

{{ form_start(form, { 'style': 'horizontal', 'col_size': 'sm' }) }}
    {% if form.documents is defined %}
        {{ form_row(form.documents) }}
    {% endif %}

    {{ form_row(form.submit, { 'attr': { 'class': 'btn btn-success' } }) }}
{{ form_end(form) }}

但现在有了顶级

{% extends viewOnly == false ? ... %}

如果viewOnly变为true则失败并且模板“”无法找到。

有没有办法说延伸这个特定的模板,这将是不扩展任何模板的相同结果?

或者,当viewOnly为false或者什么也不做时,有没有办法说延伸?

逻辑应该在控制器动作中。

你可以做的是创建2个树枝,一个延伸的父树枝,包括另一个有数据的儿童树枝。

在您的控制器中,根据条件,您可以渲染延长的树枝或子树。

在您的情况下,控制器代码可能是这样的:

if ($request->query->get('view-only') === true) {
    return $this->render('MyAppBundle:Default:data.html.twig'); // this twig hasn't extended; only data.
}
else {
    return $this->render('MyAppBundle:Default:index.html.twig'); // this twig has data.html.twig included and extended.
}

我希望能解决你的问题。 :)

基本上有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() %}

我原来的问题没有解决我想要的结果。 我认为我想要的方式是不可能的,如果你动态地想要检查扩展内容,你必须总是扩展多个模板,因为你必须为每个结果扩展一些东西。

这些是您可以通过不同的方式进行动态模板扩展。

虽然我更喜欢Jeet的解决方案,但这里有更复杂的选择。 请记住,这个解决方案只是教育性的。

  1. 创建一个新的Twig扩展 (如果您还没有)。
  2. 将请求注入您的扩展程序。
  3. 创建一个Twig函数extend_from (参见下面的示例代码),它根据请求返回模板。
  4. 将Twig函数调用到扩展块中。

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 %}

这对我来说是一个“神奇”的解决方案。 最好的方法是将您的内容视为一个模块。 您可以单独渲染它,也可以将其包含在布局中。

我的项目为例:

  1. 我创建了一个页面模板 +一个部分模板
  2. 页面模板包括包含一堆模块的部分模板。
  3. 当用户在站点周围导航时,我会在已呈现的页面中加载部分模板。

将来,我可以渲染整个页面,页面的一部分或该页面中的一个模块。

它有点复杂,但它变得非常强大,这些BaseThemeBundle允许我覆盖任何模板。

我对此问题的解决方案是创建一个empty.html视图,其中包含此内容

{% block content %}
{% endblock %}

这不是一个很好的解决方案,但比其他一些方法简单得多,所以我不必添加更多的混乱。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM