Je voudrais fournir le même contenu dans 2 fichiers de base différents.
Donc j'essaie de faire ceci:
page1.html:
{% extends "base1.html" %}
{% include "commondata.html" %}
page2.html:
{% extends "base2.html" %}
{% include "commondata.html" %}
Le problème est que je ne semble pas pouvoir utiliser à la fois les extensions et les inclus. Y a-t-il un moyen de faire ça? Et si non, comment puis-je accomplir ce qui précède?
commondata.html remplace un bloc spécifié à la fois dans base1.html et base2.html
Le but est de fournir la même page aux formats pdf et html, où le formatage est légèrement différent. La question ci-dessus simplifie cependant ce que j'essaie de faire, si je peux obtenir une réponse, cela résoudra mon problème.
Lorsque vous utilisez la balise de modèle d'extension, vous indiquez que le modèle actuel en étend une autre: il s'agit d'un modèle enfant, dépendant d'un modèle parent. Django examinera votre modèle enfant et utilisera son contenu pour renseigner le parent.
Tout ce que vous voulez utiliser dans un modèle enfant doit être contenu dans des blocs que Django utilise pour renseigner le parent. Si vous souhaitez utiliser une instruction include dans ce modèle enfant, vous devez la placer dans un bloc pour Django en donner un sens. Sinon, cela n’a aucun sens et Django ne sait pas quoi en faire.
La documentation de Django) contient quelques très bons exemples d’utilisation de blocs pour remplacer des blocs dans le modèle parent.
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance
De Django docs:
La balise include doit être considérée comme une implémentation de "rendre ce sous-modèle et inclure le code HTML", et non comme "analyser ce sous-modèle et inclure son contenu comme s'il faisait partie du parent". Cela signifie qu'il n'y a pas d'état partagé entre les modèles inclus - chaque inclusion est un processus de rendu totalement indépendant.
Donc Django ne récupère aucun bloc de votre commondata.html et il ne sait pas quoi faire avec le rendu HTML en dehors des blocs.
Cela devrait faire l'affaire: mettez la balise include à l'intérieur d'une section de bloc.
page1.html:
{% extends "base1.html" %}
{% block foo %}
{% include "commondata.html" %}
{% endblock %}
page2.html:
{% extends "base2.html" %}
{% block bar %}
{% include "commondata.html" %}
{% endblock %}
Plus d'informations sur les raisons pour lesquelles cela n'a pas fonctionné pour moi au cas où cela aiderait les personnes futures:
La raison pour laquelle cela ne fonctionnait pas, c'est que {% include%} in Django n'aime pas les caractères spéciaux comme les apostrophes sophistiquées. Les données de modèle que j'essayais d'inclure ont été collées à partir de Word. I dû supprimer manuellement tous ces caractères spéciaux et ensuite il a été inclus avec succès.
Vous ne pouvez pas extraire des blocs d'un fichier inclus dans un modèle enfant pour remplacer les blocs du modèle parent. Cependant, vous pouvez spécifier un parent dans une variable et faire spécifier le modèle de base dans le contexte.
De la documentation :
{% extend variable%} utilise la valeur de variable. Si la variable correspond à une chaîne, Django utilisera cette chaîne comme nom du modèle parent. Si la variable correspond à un objet Modèle, Django utilisez cet objet comme modèle parent.
Au lieu de "page1.html" et "page2.html" séparés, mettez {% extends base_template %}
en haut de "commondata.html". Et ensuite, à votre avis, définissez base_template
être "base1.html" ou "base2.html".
Ajouté pour référence aux futurs utilisateurs qui trouvent ceci via Google: Vous pouvez consulter la balise {% overextend%} fournie par la bibliothèque mezzanine pour des cas comme celui-ci.
Edit 10 déc 2015 : Comme indiqué dans les commentaires, ssi est obsolète depuis la version 1.8. Selon la documentation:
Cette balise est obsolète et sera supprimée dans Django 1.10. Utilisez plutôt la balise include.
À mon avis, la bonne (meilleure) réponse à cette question est celle de podshumok , car elle explique pourquoi le comportement de include quand il est utilisé avec l'héritage .
Cependant, j'ai été quelque peu surpris que personne ne mentionne la balise ssi fournie par le système de templates Django, qui est spécifiquement conçu pour inline, y compris un élément externe de texte. Ici, inline signifie que le texte externe ne sera pas interprété, analysé ou interpolé, mais simplement "copié" dans le modèle d'appel.
Veuillez vous référer à la documentation pour plus de détails (assurez-vous de vérifier votre version appropriée de Django dans le sélecteur situé dans la partie inférieure droite de la page).
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi
De la documentation:
ssi Outputs the contents of a given file into the page. Like a simple include tag, {% ssi %} includes the contents of another file – which must be specified using an absolute path – in the current page
Méfiez-vous également des implications de cette technique pour la sécurité ainsi que de la définition requise de ALLOWED_INCLUDE_ROOTS, qui doit être ajoutée à vos fichiers de paramètres.