Quiero usar el mismo {% block%} dos veces en la misma plantilla de django. Quiero que este bloque aparezca más de una vez en mi plantilla base:
# base.html
<html>
<head>
<title>{% block title %}My Cool Website{% endblock %}</title>
</head>
<body>
<h1>{% block title %}My Cool Website{% endblock %}</h1>
</body>
</html>
Y luego extiéndelo:
# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}
# pictures.html
{% extends 'base.html' %}
{% block title %}My Pictures{% endblock %}
# cats.html
{% extends 'base.html' %}
{% block title %}My Cats{% endblock %}
Obtendré una excepción, ya que Django quiere que el bloque aparezca solo una vez:
TemplateSyntaxError en /
La etiqueta 'block' con el nombre 'title' aparece más de una vez
Una solución rápida y sucia sería duplicar el bloque de título en título1 y title2 :
# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}
Pero esto es una violación del principio DRY . Sería muy difícil ya que tengo muchas plantillas heredadas, y también porque no quiero ir al infierno ;-)
¿Hay algún truco o solución para este problema? ¿Cómo puedo repetir el mismo bloque en mi plantilla, sin duplicar todo el código?
django
django-templates
dry
David Arcos
fuente
fuente
Respuestas:
Creo que el uso del procesador de contexto es en este caso una exageración. Puedes hacer esto fácilmente:
y entonces:
y así sucesivamente ... Parece compatible con DRY.
fuente
h1
contenido dentro del bloque que define eltitle
. O un bloque que define una parte detitle
.Utilice el complemento de macros de plantilla de Django:
https://gist.github.com/1715202 (django> = 1.4)
o
http://www.djangosnippets.org/snippets/363/ (django <1.4)
django> = 1.4
y
django <1.4
y
fuente
Probablemente no quiera usar un bloque, sino simplemente usar una variable:
Luego establece el título a través del contexto.
fuente
Aquí hay una forma que descubrí al intentar hacer lo mismo yo mismo:
Desafortunadamente, requiere un archivo adicional, pero no requiere que pase el título de la vista.
fuente
<tr>
fila era bastante compleja.Puedes usar
{% include subtemplate.html %}
más de una vez. No es lo mismo que los bloques, pero funciona.fuente
include
es más lento queblock
. docs.djangoproject.com/en/1.10/topics/performance/…Aquí hay una discusión: http://code.djangoproject.com/ticket/4529 Obviamente, el equipo central de django rechaza este ticket porque piensan que este no es un escenario común, sin embargo, no estoy de acuerdo.
repetir bloque es una implementación simple y limpia para esto: https://github.com/SmileyChris/django-repeatblock
la plantilla de macros es otra, sin embargo, el autor mencionó que no se ha probado cuidadosamente: http://www.djangosnippets.org/snippets/363/
Usé repetir bloque.
fuente
Como actualización para cualquiera que se encuentre con esto, tomé el fragmento mencionado anteriormente y lo convertí en una biblioteca de etiquetas de plantilla, django-macros, hace que las macros sean más potentes y también implementa un patrón de bloque repetido explícitamente: django-macros .
fuente
Aquí hay una solución ligera similar a la anterior
do_set
ydo_get
la respuesta de la etiqueta de plantilla. Django le permite pasar todo el contexto de la plantilla a una etiqueta que le permite definir una variable global.base.html:
page.html:
etiqueta personalizada (tengo la idea aquí: https://stackoverflow.com/a/33564990/2747924 ):
Además, no olvide
{% load %}
sus etiquetas personalizadas ni las agregue a la lista integrada de opciones de plantilla para que no tenga que cargarlas en cada plantilla. La única limitación de este enfoque es{% define %}
que debe llamarse desde una etiqueta de bloque porque las plantillas secundarias solo representan etiquetas de bloque que coinciden con las etiquetas principales. No estoy seguro si hay una forma de evitar eso. También asegúrese de que ladefine
llamada llegue antes de intentar usarla obviamente.fuente
A partir de la sugerencia de Van Gale, puede crear obtener y establecer etiquetas agregando lo siguiente a su archivo templatetags.py:
Luego establezca valores en una plantilla vía
{% set foo %}put data here{% endset %}
y consígalos{% get foo %}
en otra.fuente
Yo también he encontrado la misma necesidad de repetir {% block%} en mis archivos de plantilla. El problema es que quiero que se use un Django {% block%} en cualquier caso de un condicional de Django, y quiero que el {% block%} se pueda sobrescribir por archivos posteriores que pueden extender el archivo actual. (Entonces, en este caso, lo que quiero es definitivamente más un bloque que una variable porque técnicamente no lo estoy reutilizando, solo aparece en cualquier extremo de un condicional.
El problema:
El siguiente código de plantilla de Django dará como resultado un error de sintaxis de plantilla, pero creo que es un "deseo" válido tener un {% block%} definido reutilizado en condicional (IE, ¿por qué el analizador Django valida la sintaxis en AMBOS extremos? de un condicional, ¿no debería solo validar la condición VERDADERA?)
La solución:
Puede usar un {% include%} para insertar condicionalmente un {% block%} más de una vez. Esto funcionó para mí porque el verificador de sintaxis de Django incluye solo el VERDADERO {% include%}. Vea el resultado a continuación:
fuente
Utilizo esta respuesta para mantener las cosas secas.
fuente
Hay dos soluciones fáciles para esto.
Lo más fácil es poner su título en una variable de contexto. Establecería la variable de contexto en su vista.
Si está utilizando algo como vistas genéricas y no tiene views.py para imágenes, gatos, etc., entonces puede seguir el camino de una etiqueta de plantilla personalizada que establece una variable en el contexto .
Seguir esta ruta te permitiría hacer algo como:
Luego en su base.html:
fuente
Any variable set in the context will only be available in the same block of the template in which it was assigned. This behavior is intentional; it provides a scope for variables so that they don’t conflict with context in other blocks.
La respuesta seleccionada alude a una solución fácil para envolver una etiqueta dentro de otra en la plantilla secundaria para darles a ambos el mismo valor. Lo uso para imágenes sociales así.
Plantilla hijo:
Luego en el padre
base.html
:fuente
En twig puedes hacer esto como:
fuente