python - examples - Plantillas django: incluir y extender
include django template (7)
Me gustaría proporcionar el mismo contenido dentro de 2 archivos base diferentes.
Así que estoy tratando de hacer esto:
page1.html:
{% extends "base1.html" %}
{% include "commondata.html" %}
page2.html:
{% extends "base2.html" %}
{% include "commondata.html" %}
El problema es que parece que no puedo usar tanto extends como include. ¿Hay alguna manera de hacer eso? Y si no, ¿cómo puedo lograr lo anterior?
commondata.html anula un bloque que se especifica en base1.html y base2.html
El objetivo de esto es proporcionar la misma página en formato pdf y html, donde el formato es ligeramente diferente. La pregunta anterior simplifica lo que estoy tratando de hacer, así que si puedo obtener una respuesta, eso resolverá mi problema.
Agregado para referenciar a las personas futuras que lo encuentren a través de google: es posible que desee consultar la etiqueta {% overextend%} proporcionada por la biblioteca mezzanine para casos como este.
Cuando usa la etiqueta de plantilla extends, está diciendo que la plantilla actual se extiende a otra, que es una plantilla secundaria, que depende de una plantilla principal. Django mirará la plantilla de su hijo y usará su contenido para poblar al padre.
Todo lo que desee utilizar en una plantilla secundaria debe estar dentro de los bloques, que Django usa para llenar el elemento primario. Si desea usar una declaración de inclusión en esa plantilla secundaria, debe colocarla dentro de un bloque, para que Django le dé sentido. De lo contrario, simplemente no tiene sentido y Django no sabe qué hacer con él.
La documentación de Django tiene algunos ejemplos realmente buenos del uso de bloques para reemplazar bloques en la plantilla principal.
https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance
De los documentos de Django:
La etiqueta de inclusión se debe considerar como una implementación de "renderizar esta subtabla e incluir el HTML", no como "analizar esta subcompetencia e incluir su contenido como si fuera parte de la matriz". Esto significa que no hay un estado compartido entre las plantillas incluidas; cada inclusión es un proceso de representación completamente independiente.
Así que Django no toma ningún bloque de tus commondata.html y no sabe qué hacer con los bloques externos html representados.
Esto debería ser el truco para ti: poner etiqueta de inclusión dentro de una sección de bloque.
page1.html:
{% extends "base1.html" %}
{% block foo %}
{% include "commondata.html" %}
{% endblock %}
page2.html:
{% extends "base2.html" %}
{% block bar %}
{% include "commondata.html" %}
{% endblock %}
Más información sobre por qué no funcionaba para mí en caso de que ayude a las personas del futuro:
La razón por la que no funciona es que {% include%} en django no le gusta los caracteres especiales como el apóstrofo elegante. La información de la plantilla que estaba tratando de incluir se ha pegado de la palabra. Tuve que eliminar manualmente todos estos caracteres especiales y luego se incluyó con éxito.
No puede insertar bloques de un archivo incluido en una plantilla secundaria para anular los bloques de la plantilla principal. Sin embargo, puede especificar un padre en una variable y tener la plantilla base especificada en el contexto.
De la documentation :
{% extends variable%} usa el valor de la variable. Si la variable se evalúa como una cadena, Django usará esa cadena como el nombre de la plantilla principal. Si la variable se evalúa como un objeto Plantilla, Django usará ese objeto como la plantilla padre.
En lugar de "page1.html" y "page2.html" por separado, ponga {% extends base_template %}
en la parte superior de "commondata.html". Y en su opinión, defina base_template
para que sea "base1.html" o "base2.html".
Editar 10 de diciembre de 2015 : Como se señaló en los comentarios, ssi está en desuso desde la versión 1.8. De acuerdo con la documentación:
Esta etiqueta ha quedado obsoleta y se eliminará en Django 1.10. Use la etiqueta de inclusión en su lugar.
En mi opinión, la respuesta correcta (mejor) a esta pregunta es la de podshumok , ya que explica por qué el comportamiento de incluir cuando se usa junto con la herencia.
Sin embargo, me sorprendió un poco que nadie mencionara la etiqueta ssi proporcionada por el sistema de creación de plantillas de Django, que está específicamente diseñado para incluir un texto externo en línea . Aquí, en línea significa que el texto externo no será interpretado, analizado o interpolado, sino simplemente "copiado" dentro de la plantilla de llamada.
Consulte la documentación para obtener más detalles (asegúrese de verificar su versión apropiada de Django en el selector en la parte inferior derecha de la página).
https://docs.djangoproject.com/en/dev/ref/templates/builtins/#ssi
De la documentación:
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
Tenga en cuenta también las implicaciones de seguridad de esta técnica y también de la definición de ALLOWED_INCLUDE_ROOTS requerida, que debe agregarse a sus archivos de configuración.