web-dev-qa-db-fra.com

Twig étendre le modèle à condition

J'utilise Symfony 2 avec Twig et ma question est assez simple:

Dans une vue, je souhaite étendre l'une des dispositions en fonction d'une variable. Si la variable est false je veux étendre UdoWebsiteBundle::layout.html.twig et si c'est true je veux étendre UdoWebsiteBundle::layout_true.html.twig.

Voici le code que j'ai essayé:

{% block layout_extender %}

    {% if intro == 'false' %}
        {% extends 'UdoWebsiteBundle::layout.html.twig' %}
    {% else %}
        {% extends 'UdoWebsiteBundle::layout_true.html.twig' %}
    {% endif %}

{% endblock %}

Je reçois cette erreur:

Plusieurs balises d'extension sont interdites dans "UdoWebsiteBundle: home: home.html.twig" à la ligne 7

Existe-t-il un autre moyen d'y parvenir?

46
Dan Cearnau

Essaye celui-là:

{% extends intro == 'false' 
    ? 'UdoWebsiteBundle::layout.html.twig' 
    : 'UdoWebsiteBundle::layout_true.html.twig' %}

Idée tirée d'ici: http://jorisdewit.ca/2011/08/27/extending-different-layouts-for-ajax-requests-in-twig-symfony2/

51
Maerlyn

Pour le garder propre, vous devez utiliser Twig support d'héritage dynamique en utilisant une variable, définie dans votre contrôleur, comme modèle de base:

{% extends parent_template_var %}

Si la variable est évaluée en un objet Twig_Template, Twig l'utilisera comme modèle parent.

Définissez parent_template_var dans votre contrôleur:

if($intro == 'false')
    $parent_template_var = 'UdoWebsiteBundle::layout.html.twig';
}else{
    $parent_template_var = 'UdoWebsiteBundle::layout_true.html.twig';
}
return $this->render('::/action.html.twig', array('parent_template_var' => $parent_template_var ));

http://twig.sensiolabs.org/doc/tags/extends.html

16
svassr

Réponse du documentation officielle :

Héritage conditionnel

Comme le nom du modèle pour le parent peut être n'importe quelle expression Twig valide, il est possible de rendre le mécanisme d'héritage conditionnel:

{% extends standalone ? "minimum.html" : "base.html" %}

Dans cet exemple, le modèle étendra le modèle de disposition "minimum.html" si la variable autonome est évaluée à true et "base.html" dans le cas contraire.

6
Benoit

Vous ne pouvez pas étendre plusieurs modèles, c'est pourquoi vous avez l'erreur, si vous le souhaitez, vous devez les pousser dans un tableau comme ci-dessous.

{% extends ['MyAppCustomBundle::Layout/layout.html.twig', 'FOSUserBundle::layout.html.twig'] %}

Mais vous devrez utiliser Twig version 1.2 pour le faire. documentation twig

2
bazingabazinga

Tout cela est logique de faire ce modèle ou ce modèle.

Mais permettez-moi de décrire une autre situation. Vous avez un formulaire de profil et un formulaire où les utilisateurs peuvent télécharger des documents liés au profil personnel. Le formulaire de profil étant déjà très long, les documents sont passés à un nouveau formulaire.

Tout fonctionne très bien. Maintenant, nous voulons utiliser les onglets bootstrap pour créer des documents de profil pour la convivialité.

Maintenant, je sais parce que nous utilisons deux formulaires distincts si vous soumettez les documents, les modifications sur le profil ne seront pas enregistrées et vice versa.

J'ai ajouté le formulaire de document dans l'onglet en utilisant

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

'ViewOnly': true est un paramètre de requête et n'est pas requis par l'action.

Ma question devient maintenant si l'onglet de profil rend le modèle de document, il ne doit montrer que le widget de téléchargement et la soumission où, comme lorsque vous allez directement à la page du document, il doit afficher le titre et la barre latérale et tout. J'ai donc essayé

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

Cela a posé des problèmes car vous ne pouvez pas utiliser les extensions dans un if. Comme vous l'avez suggéré dans d'autres réponses, essayez d'utiliser

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

Cela a résolu le problème Twig jusqu'à l'exécution du code lorsque viewOnly est faux.

Lorsque viewOnly est faux, il doit étendre le modèle de base utilisé par tous les autres modèles, mais si c'est vrai, je veux seulement montrer ceci:

{{ 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) }}

Mais maintenant avec le haut

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

si viewOnly devient faux, il échoue avec le modèle "" introuvable.

Existe-t-il un moyen de dire étendre ce modèle spécifique qui sera le même résultat que de ne pas étendre de modèle?

Ou bien existe-t-il un moyen de dire étendre cela lorsque viewOnly true mais rien ne se passe en cas d'échec?

2
dTHQb