2009-09-11 13 views
73

Me gustaría proporcionar el mismo contenido dentro de 2 archivos base diferentes.plantillas de django: incluir y extender

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 puede utilizar ambos se extienden e incluyen. ¿Hay alguna manera de hacer eso? Y si no, ¿cómo puedo lograr lo anterior?

commondata.html anula un bloque que se especifica en tanto base1.html y base2.html

El propósito de esto es proporcionar la misma página, tanto 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.

Respuesta

83

Cuando utiliza 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 buenos ejemplos del uso de bloques para reemplazar bloques en la plantilla primaria.

https://docs.djangoproject.com/en/dev/ref/templates/language/#template-inheritance

+1

mi commondata.html tiene el bloque definido en ella. Pero no está reemplazando el bloque del tempalte padre ... Si en lugar de hacer un include escribo los datos exactos dos veces tanto en page1.html como en page2.html entonces, por supuesto, funciona.Pero quiero restar importancia a lo que es común en commondata.html. –

+0

Lo intentaré dentro de un bloque, pero creo que lo intenté anteriormente ... –

+0

Parece que funciona, recuerdo haber intentado esto, pero debo haber tenido un error tipográfico o algo así en el momento que causó que no funcionara. –

9

Más información acerca de por qué no estaba trabajando para mí en caso de que ayuda a la gente del futuro:

La razón por la que no estaba funcionando es que {% include%} en Django doesn' Me gustan los personajes 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.

64

a partir de documentos de Django:

La etiqueta include debe ser considerada como una implementación de "hacer que esta subtemplate e incluir el código HTML", no como "analizar esta subtemplate e incluir su contenido como si fuera parte de el padre". 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 su commondata.html y no sabe qué hacer con los bloques externos html representados.

2

Se ha agregado como referencia para futuras personas que lo encuentren a través de google: es posible que desee ver la etiqueta {% sobreextensible%} proporcionada por la biblioteca mezzanine para casos como este.

3

No se pueden 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.

Desde el documentation:

{% extends%} variables utiliza 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" independiente y "page2.html", puso {% extends base_template %} en la parte superior de la "commondata.html". Y en su opinión, defina base_template como "base1.html" o "base2.html".

1

Editar 10mo Dic el año 2015: Como se ha señalado en los comentarios, ssi está obsoleto desde la versión 1.8. Según 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, el derecho (el mejor) respuesta a esta pregunta es el de podshumok, ya que explica por qué el comportamiento de incluir cuando se utiliza junto con la herencia.

Sin embargo, estaba algo sorprendido que nadie menciona la etiqueta ssi proporcionada por el sistema de plantillas Django, que está diseñado específicamente para inline incluyendo una pieza externa de texto. 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 la versión adecuada 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 

Guárdate también de las implicaciones de seguridad de esta técnica y también de los ALLOWED_INCLUDE_ROOTS requeridos definen, que hay que añadir a sus archivos de configuración.

+1

Nota, a partir del 1.8, ssi ha quedado en desuso en favor de Incluir. [https://docs.djangoproject.com/en/1.8/ref/templates/builtins/#std:templatetag-include](https://docs.djangoproject.com/en/1.8/ref/templates/builtins/# std: templatetag-include) –

5

Esto debería hacer el truco para usted: 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 %} 
Cuestiones relacionadas