webentwicklung-frage-antwort-db.com.de

AngularJS with Django - Widersprüchliche Vorlagen-Tags

Ich möchte AngularJS mit Django verwenden, beide verwenden jedoch {{ }} als Template-Tags. Gibt es eine einfache Möglichkeit, eines der beiden zu ändern, um ein anderes benutzerdefiniertes Template zu verwenden?

292
Endophage

Für Angular 1.0 sollten Sie die Interpolationssymbole mit dem $ interpolateProvider apis konfigurieren: http://docs.angularjs.org/api/ng.$interpolateProvider .

So etwas sollte den Trick tun:

myModule.config(function($interpolateProvider) {
  $interpolateProvider.startSymbol('{[{');
  $interpolateProvider.endSymbol('}]}');
});

Denken Sie an zwei Dinge:

  • das Mischen von serverseitigen und clientseitigen Vorlagen ist selten eine gute Idee und sollte mit Vorsicht verwendet werden. Die Hauptprobleme sind: Wartbarkeit (schwer lesbar) und Sicherheit (durch doppelte Interpolation könnte ein neuer Sicherheitsvektor sichtbar gemacht werden - wenn beispielsweise das Auslagern von Seiten des Servers und des Clients auf der eigenen Seite sicher ist, ist ihre Kombination möglicherweise nicht sicher).
  • wenn Sie mit der Verwendung von Direktiven (Komponenten) von Drittanbietern beginnen, die {{ }} in ihren Vorlagen verwenden, werden diese durch Ihre Konfiguration beschädigt. ( Fix ausstehend )

Während wir an der ersten Ausgabe nichts tun können, abgesehen von der Warnung der Menschen, müssen wir uns mit der zweiten Ausgabe befassen.

295
Igor Minar

sie können vielleicht verbatim Django template tag versuchen und so verwenden:

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

{% verbatim %}
<div ng-app="">
    <p>10 is {{ 5 + 5 }}</p>
</div>
{% endverbatim %}

116

Wenn Sie Teile der Seite richtig getrennt haben, können Sie die "anglejs" -Tags einfach im "raw" -Tag-Bereich verwenden.

In Jinja2

{% raw %}
    // here you can write angularjs template tags.
{% endraw %}

In Django-Vorlage (über 1,5)

{% verbatim %}    
    // here you can write angularjs template tags.
{% endverbatim %}
42
thanksnote

Wir haben einen einfachen very -Filter in Django 'ng' erstellt, der das Mischen der beiden erleichtert:

foo.html:

...
<div>
  {{ Django_context_var }}
  {{ 'angularScopeVar' | ng }}
  {{ 'angularScopeFunction()' | ng }}
</div>
...

Der ng-Filter sieht folgendermaßen aus:

from Django import template
from Django.utils import safestring

register = template.Library()


@register.filter(name='ng')
def Angularify(value):
  return safestring.mark_safe('{{%s}}' % value)
29
Wes Alvaro

Ich habe heute im Angular IRC -Kanal große Hilfe erhalten. Es stellt sich heraus, dass Sie die Vorlagen-Tags von Angular sehr einfach ändern können. Die unten aufgeführten erforderlichen Ausschnitte sollten nach dem Angle-Include eingefügt werden (das angegebene Beispiel wird in den Mailing-Listen aufgeführt und würde (()) als neue Vorlagen-Tags verwenden, ersetzen Sie Ihre eigenen):

angular.markup('(())', function(text, textNode, parentElement){
  if (parentElement[0].nodeName.toLowerCase() == 'script') return;
  text = text.replace(/\(\(/g,'{{').replace(/\)\)/g, '}}');
  textNode.text(text);
  return angular.markup('{{}}').call(this, text, textNode, parentElement);
});

angular.attrMarkup('(())', function(value, name, element){
    value = value.replace(/\(\(/g,'{{').replace(/\)\)/, '}}');
    element[0].setAttribute(name, value);
    return angular.attrMarkup('{{}}').call(this, value, name, element);
});

Ich wurde auch auf eine bevorstehende Erweiterung hingewiesen, die startSymbol- und endSymbol -Eigenschaften aufzeigt, die auf beliebige Tags gesetzt werden können.

26
Endophage

Ich stimme gegen die Verwendung von doppelten Klammern (()) als Vorlagen-Tag. Es kann gut funktionieren, solange es keinen Funktionsaufruf gibt, aber wenn Folgendes versucht wird

ng:disabled=(($invalidWidgets.visible()))

mit Firefox (10.0.2) auf dem Mac habe ich statt der beabsichtigten Logik einen furchtbar langen Fehler erhalten. <[]> lief bisher gut für mich.

Bearbeiten 2012-03-29: Beachten Sie, dass $ invalidWidgets nicht mehr empfohlen wird. Ich würde jedoch immer noch eine andere Hülle als doppelte Zahnspange verwenden. Bei einer Winkelversion über 0.10.7 (schätze ich) könnten Sie den Wrapper in Ihrer App/Modul-Definition viel einfacher ändern:

angular.module('YourAppName', [], function ($interpolateProvider) {
    $interpolateProvider.startSymbol('<[');
    $interpolateProvider.endSymbol(']>');
}); 

API-Dokumente .

17
Lukas Bünger

Ich fand den Code unten hilfreich. Ich habe den Code hier gefunden: http://djangosnippets.org/snippets/2787/

"""
filename: angularjs.py

Usage:
    {% ng Some.angular.scope.content %}

e.g.
    {% load angularjs %}
    <div ng-init="yourName = 'foobar'">
        <p>{% ng yourName %}</p>
    </div>
"""

from Django import template

register = template.Library()

class AngularJS(template.Node):
    def __init__(self, bits):
        self.ng = bits

    def render(self, ctx):
        return "{{%s}}" % " ".join(self.ng[1:])

def do_angular(parser, token):
    bits = token.split_contents()
    return AngularJS(bits)

register.tag('ng', do_angular)
15
nu everest

Sie können ng-bind immer anstelle von {{}} http://docs.angularjs.org/api/ng/directive/ngBind verwenden.

<span ng-bind="name"></span>
14
Indomitable

Wenn Sie Django 1.5 und neuer verwenden, verwenden Sie:

  {% verbatim %}
    {{if dying}}Still alive.{{/if}}
  {% endverbatim %}

Wenn Sie mit Django 1.2 auf Appengine stecken bleiben, erweitern Sie die Django-Syntax mit dem Befehl "wörtliche Vorlage" wie folgt ...

from Django import template

register = template.Library()

class VerbatimNode(template.Node):

    def __init__(self, text):
        self.text = text

    def render(self, context):
        return self.text

@register.tag
def verbatim(parser, token):
    text = []
    while 1:
        token = parser.tokens.pop(0)
        if token.contents == 'endverbatim':
            break
        if token.token_type == template.TOKEN_VAR:
            text.append('{{')
        Elif token.token_type == template.TOKEN_BLOCK:
            text.append('{%')
        text.append(token.contents)
        if token.token_type == template.TOKEN_VAR:
            text.append('}}')
        Elif token.token_type == template.TOKEN_BLOCK:
            text.append('%}')
    return VerbatimNode(''.join(text))

In Ihrer Datei verwenden Sie:

from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')

Quelle: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html

11
cat

Für AngularJS v1.3.3 sollten Sie Ihre eigenen Vorlagen-Tags so definieren

AngularJS-Modul

angular.module('myapp', []).config(function($interpolateProvider) {
    $interpolateProvider.startSymbol('{$');
    $interpolateProvider.endSymbol('$}');
});

Website

<a>{$ variable $}</a> 
9
Alex Jolig

Sie können Django anweisen, {{ und }} sowie andere reservierte Vorlagenzeichenfolgen mithilfe des Tags {% templatetag %} auszugeben.

Die Verwendung von {% templatetag openvariable %} würde beispielsweise {{ ausgeben.

7
Thomas Orozco

Ich würde bei einer Lösung bleiben, die sowohl Django-Tags {{}} als auch anglejs {{}} mit einem wörtlichen Abschnitt oder einem Templatetag verwendet. 

Das liegt einfach daran, dass Sie die Funktionsweise von anglejs (wie erwähnt) über das $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol ändern können. Wenn Sie jedoch andere anglejs-Komponenten wie den ui-bootstrap verwenden, werden Sie feststellen, dass einige Vorlagen bereits erstellt wurden mit standard anglejs-Tags {{}}. 

Siehe zum Beispiel https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html

3
silviud

Wenn Sie serverseitige Interpolation durchführen, ist der richtige Weg, only, dies mit <>.

$interpolateProvider.startSymbol('<{').endSymbol('}>');

Alles andere ist ein XSS-Vektor.

Dies liegt daran, dass Angular-Trennzeichen, die nicht von Django geschützt werden, vom Benutzer in die interpolierte Zeichenfolge eingegeben werden können. Wenn jemand seinen Benutzernamen auf "{{evil_code}}" setzt, wird Angular es gerne ausführen . Wenn Sie ein Zeichen verwenden, als Django entgeht , geschieht dies nicht.

0
Dan