Domanda

Voglio usare la stessa {% block %} due volte nello stesso django modello.Voglio che questo blocco di apparire più di una volta nel mio modello di 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>

E poi l'estensione:

# 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 %}

Farò un'eccezione, come Django vuole il blocco di apparire solo una volta:

TemplateSyntaxError a /

'blocco' di tag con il nome 'titolo' appare più di una volta

Una breve e veloce soluzione sarebbe duplicare il blocco titolo in title1 e title2:

# blog.html
{% extends 'base.html' %}
{% block title1 %}My Blog{% endblock %}
{% block title2 %}My Blog{% endblock %}

Ma questa è una violazione del LAVAGGIO linea di principio.Sarebbe molto difficile in quanto ho un sacco di ereditare i modelli, e anche perché non voglio andare all'inferno ;-)

C'è qualche trucco o di lavoro intorno a questo problema?Come posso ripetere lo stesso blocco nel mio modello, senza duplicazione di tutto il codice?

È stato utile?

Soluzione

Penso che l'uso del contesto processore è in questo caso un overkill.Si può facilmente fare questo:

#base.html
<html>
    <head>
        <title>{% block title %}My Cool Website{% endblock %}</title>
    </head>
    <body>
        {% block content %}{% endblock %}
    </body>
</html>

e poi:

# blog.html
{% extends 'base.html' %}
{% block content %}
    <h1>{% block title %}My Blog{% endblock %}</h1>
    Lorem ipsum here...
{% endblock %}

e così via...Sembra SECCO-compatibile.

Altri suggerimenti

Utilizzare il Django modello macro plugin:

http://www.djangosnippets.org/snippets/363/ (django < 1.4)

o

https://gist.github.com/1715202 (django >= 1.4)

Quindi,

# base.html
{% macro title %}
    {% block title %}My Cool Website{% endblock %}
{% endmacro %}

<html>
    <head>
        <title>{% usemacro title %}</title>
    </head>
    <body>
        <h1>{% usemacro title %}</h1>
    </body>
</html>

e

# blog.html
{% extends 'base.html' %}
{% block title %}My Blog{% endblock %}

Probabilmente in realtà non si vuole utilizzare un blocco, ma piuttosto di usare una variabile:

# base.html
<html>
    <head>
        <title>{{ title|default:"My Cool Website" }}</title>
    </head>
    <body>
        <h1>{{ title|default:"My Cool Website" }}</h1>
    </body>
</html>

Si imposta quindi il titolo attraverso il contesto.

è possibile utilizzare {% include subtemplate.html %} più di una volta.non è la stessa come blocchi, ma fa il trucco.

Ecco come ho scoperto quando cercando di fare la stessa cosa a me stesso:

# base_helper.html
<html>
    <head>
        <title>{% block _title1 %}{% endblock %}</title>
    </head>
    <body>
        <h1>{% block _title2 %}{% endblock %}</h1>
    </body>
</html>


# base.html
{% extends "base_helper.html" %}

# Copy title into _title1 & _title2, using "My Cool Website" as a default.
{% block _title1 %}{% block _title2 %}{% block title %}My Cool Website{% endblock %}{% endblock %}{% endblock %}

Richiede un file aggiuntivo, purtroppo, ma non richiede di passare il titolo da visualizzare.

Ci sono alcune discussioni qui:http://code.djangoproject.com/ticket/4529 Ovviamente django core team di rifiutare questo biglietto perché pensano che questo non è un comune scenario, tuttavia non sono d'accordo.

ripetere il blocco è semplice e pulito, questa implementazione:https://github.com/SmileyChris/django-repeatblock

modello macro è un altro, tuttavia l'autore citato non è accuratamente testato:http://www.djangosnippets.org/snippets/363/

Ho usato repeatblock.

Come aggiornamento per chi si imbatte in questo, ho preso il frammento di cui sopra e l'ha trasformata in un modello di libreria di tag, django-macro, rende la macro più potente e implementa anche un ripetuto pattern di blocco in modo esplicito: django-macro.

Qui è una soluzione leggera simile al precedente do_set e do_get tag modello di risposta.Django consente di passare l'intero modello di contesto in un tag che consentono di definire una variabile globale.

base.html:

<!DOCTYPE html>
<html lang="en">
<head>
  {% block head %}
    <title>{{ title }}</title>
  {% endblock %}
</head>
<body>
  <h1>{{ title }}</h1>
</body>
</html>

page.html:

{% extends "base.html" %}

{% block head %}
  {% define 'title' 'Homepage | title' %}
  {{ block.super }}
{% endblock %}

tag personalizzato (è venuta l'idea qui: https://stackoverflow.com/a/33564990/2747924):

@register.simple_tag(takes_context=True)
def define(context, key, value):
    context.dicts[0][key] = value
    return ''

Inoltre, non dimenticare di {% load %} il tag personalizzati o aggiungere al template opzioni builtins elenco di modo che non devi caricare in ogni modello.L'unica limitazione di questo approccio è l' {% define %} deve essere chiamato da un tag di blocco perché bambino template di render blocco di tag che corrispondono al genitore tag.Non sono sicuro se c'è un modo per aggirare.Inoltre, assicurarsi che il define chiamata prima si tenta di utilizzarlo, ovviamente.

Edificio su Van Gale suggerimento, si potrebbe creare get e set di tag aggiungendo il seguente templatetags.py file:

register = template.Library()

Stateful = {}
def do_set(parser, token):
    _, key = token.split_contents()
    nodelist = parser.parse(('endset',))
    parser.delete_first_token()  # from the example -- why?
    return SetStatefulNode(key,nodelist)

class SetStatefulNode(template.Node):
    def __init__(self, key, nodes):
        Stateful[key] = nodes
    def render(self, context):
        return ''
register.tag('set', do_set)

def do_get(parser, token):
    tag_name, key = token.split_contents()
    return GetStatefulNode(key)

class GetStatefulNode(template.Node):
    def __init__(self, key):
       self.key = key
    def render(self, context):
        return ''.join( [x.render(context) for x in Stateful[self.key]] )

register.tag('get', do_get)

Quindi, impostare i valori in un modello e via {% set foo %}put data here{% endset %} e farli via {% get foo %} in un'altra.

Anch'io ho incontrato le stesse necessità di un ripetuto {% block %} nel mio file di modello.Il problema è che io voglio un Django {% block %} per essere utilizzato in caso di Django condizionale, e voglio che il {% block %} per essere scrivibile da file successivi che possono estendere il file corrente.(Quindi, in questo caso, quello che voglio è sicuramente più di un blocco di una variabile, perché io non sono tecnicamente ri-uso, solo che appare su entrambe le estremità di un condizionale.

Il Problema:

I seguenti Django codice del template che si tradurrà in un Modello di Errore di Sintassi, ma penso che sia un valido "voglia" di avere una definita {% block %} ri-utilizzato in un condizionale (vale a dire, perché è il Django parser convalida di sintassi su ENTRAMBE le estremità di un condizionale, non solo convalidare il TRUTHY condizione?)

# This example shows a {{ DEBUG }} conditional that loads 
#   Uncompressed JavaScript files if TRUE 
#   and loads Asynchronous minified JavaScript files if FALSE.  

# BASE.html
{% if DEBUG %}
    <script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
    <script type="text/javascript">
        {% block page_js %}
            var page = new $site.Page();
        {% endblock page_js %}
    </script>
{% else %}
    <script type="text/javascript">
        // load in the PRODUCTION VERSION of the site
        // minified and asynchronosly loaded
        yepnope([
            {
                load : '{MEDIA_URL}}js/flatfiles.min.js',
                wait : true,
                complete : function() {
                    {% block page_js %} // NOTE THE PAGE_JS BLOCK
                        var page = new $site.Page();
                    {% endblock page_js %}
                }
            }
        )];
    </script>
{% endif %}

# ABOUT.html
{% extends 'pages/base.html' %}
{% block page_js %}
var page = new $site.Page.About();
{% endblock page_js %}

La Soluzione:

È possibile utilizzare un {% sono %} in modo condizionale inserire un {% block %} più di una volta.Questo ha funzionato per me, perché il Django controllo della sintassi include solo il TRUTHY {% sono %}.Vedere il risultato qui:

# partials/page.js
{% block page_js %}
    var page = new $site.Page();    
{% endblock %}

# base.html
{% if DEBUG %}
    <script src="{{MEDIA_URL}}js/flatfile.1.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.2.js"></script>
    <script src="{{MEDIA_URL}}js/flatfile.3.js"></script>
    <script type="text/javascript">
        {% include 'partials/page_js.html' %}
    </script>
{% else %}
    <script type="text/javascript">
        yepnope([
            {
                load : '{MEDIA_URL}}js/flatfiles.min.js',
                wait : true,
                complete : function() {
                    {% include 'partials/page_js.html' %}
                }
            }
        )];
    </script>
{% endif %}

Ci sono due soluzioni per questo.

Il modo più semplice è quello di mettere il titolo in un contesto variabile.È necessario impostare la variabile di contesto nel vostro punto di vista.

Se si utilizza qualcosa come generic vista e non hanno un views.py per le foto, gatti, etc.poi si può seguire la strada di un modello personalizzato tag che consente di impostare una variabile nel contesto.

Andare questo itinerario permette di fare qualcosa di simile:

{% extends "base.html" %}
{% load set_page_title %}
{% page_title "My Pictures" %}
...

Poi nel tuo base.html:

...
{% block title %}{{ page_title }}{% endblock %}
...
<h1>{{ page_title }}</h1>

Io uso questa risposta per mantenere le cose asciutte.

{% extends "base.html" %}

{% with "Entry Title" as title %}
    {% block title %}{{ title }}{% endblock %}
    {% block h1 %}{{ title }}{% endblock %}
{% endwith %}

In twig si può fare questo come:

# base.html
<html>
    <head>
        <title>{{ block('title') }}</title>
    </head>
    <body>
        <h1>{{ block('title') }}</h1>
    </body>
</html>

# 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 %}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top