Frage

Ich möchte AngularJs mit Django verwenden, aber beide verwenden {{ }} als ihre Vorlagen -Tags. Gibt es eine einfache Möglichkeit, einen der beiden zu ändern, um ein anderes benutzerdefiniertes Templating -Tag zu verwenden?

War es hilfreich?

Lösung

Für Angular 1.0 sollten Sie die $ interpolateProvider -APIs verwenden, um die Interpolationssymbole zu konfigurieren: http://docs.angularjs.org/api/ng.$interpolateProvider.

So etwas sollte den Trick machen:

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

Denken Sie an zwei Dinge:

  • Das Mischen serverseitiger und clientseitiger Vorlagen ist selten eine gute Idee und sollte mit Vorsicht verwendet werden. Die Hauptprobleme sind: Wartbarkeit (schwer zu lesen) und Sicherheit (doppelte Interpolation könnte einen neuen Sicherheitsvektor aufdecken - z. B. während der Entkommen von Serverside- und Clientside -Templatieren von selbst sicher sein, ihre Kombination ist möglicherweise nicht).
  • Wenn Sie anfangen, Drittanbieter-Direktiven (Komponenten) zu verwenden, die verwendet werden {{ }} In ihren Vorlagen wird Ihre Konfiguration sie brechen. (Fix anhängig)

Obwohl wir nichts gegen das erste Problem tun können, außer für die Warnung von Menschen, müssen wir das zweite Problem angehen.

Andere Tipps

Sie können es vielleicht versuchen wörtlich Django Template -Tag und verwenden Sie es wie folgt:

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

Wenn Sie ordnungsgemäß getrennte Seitenabschnitte gemacht haben, können Sie problemlos AngularJS -Tags in "RAW" -T -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 %}

Wir haben a geschaffen sehr Einfacher Filter in Django 'ng', der es einfach macht, die beiden zu mischen:

foo.html:

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

Das ng Filter sieht so 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)

Also habe ich heute im Winkel -IRC -Kanal große Hilfe bekommen. Es stellt sich heraus, dass Sie die Template -Tags von Angular sehr leicht ändern können. Die erforderlichen Ausschnitte unten sollten nach dem Einbeziehung Ihres Winkels enthalten sein (das angegebene Beispiel wird auf ihrem angezeigt Mailinglisten und würde verwenden (()) Als neue Vorlagen -Tags 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);
});

Außerdem wurde ich auf eine bevorstehende Verbesserung hingewiesen, die aufdecken wird startSymbol und endSymbol Eigenschaften, die auf alle gewünschten Tags eingestellt werden können.

Ich stimme gegen die Verwendung von Doppel -Klammern (()) als Vorlagen -Tag. Es kann gut funktionieren, solange kein Funktionsaufruf beteiligt ist, aber wenn er Folgendes ausprobiert hat

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

Mit Firefox (10.0.2) auf dem Mac habe ich einen schrecklich langen Fehler anstelle der beabsichtigten Logik. <[]> ging gut für mich, zumindest bis jetzt.

Bearbeiten 2012-03-29:Bitte beachten Sie, dass $ InvalidWidgets veraltet ist. Allerdings würde ich immer noch einen anderen Wrapper als Doppelklammern verwenden. Für jede Winkelversion über 0,10.7 (ich denke) können Sie die Wrapper in Ihrer App / Modul -Definition viel einfacher ändern:

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

API -Dokumente.

Ich fand den folgenden Code 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)

Sie könnten immer ng-bind anstelle von {{}} verwendenhttp://docs.angularjs.org/api/ng/directive/ngbind

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

Wenn Sie Django 1.5 und neuere Verwendung verwenden:

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

Wenn Sie mit Django 1.2 auf AppEngine festsitzen, erweitern Sie die Django -Syntax mit dem Befehl wörtlicher Vorlage wie diesem ...

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 Verwendung:

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

Sie können Django sagen, dass er ausgeben soll {{ und }}, sowie andere reservierte Vorlagenzeichenfolgen mit der Verwendung der {% templatetag %} Schild.

Zum Beispiel verwenden {% templatetag openvariable %} würde ausgeben {{.

Ich würde mich an eine Lösung halten, die beide Django -Tags {{}} sowie AngularJs {{}} mit einem wörtlichen Abschnitt oder einem Templatetag verwendet.

Dies liegt einfach daran, dass Sie die Art und Weise ändern können, wie AngularJs (wie erwähnt) über den $ interpolatProvider funktioniert. mit Standard AngularJS -Tags {{}}.

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

Wenn Sie eine serverseitige Interpolation durchführen, die nur Die richtige Art, dies zu tun, ist mit <>

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

Alles andere ist ein XSS -Vektor.

Dies liegt daran, dass alle Angular -Grenzwerte, die nicht von Django entkommen sind, vom Benutzer in die interpolierte Zeichenfolge eingegeben werden können. Wenn jemand seinen Benutzernamen als "{{Evil_code}}" festlegt, Angular wird es glücklich laufen lassen. Wenn Sie a verwenden Charakter als Django entkommt, Dies wird jedoch nicht passieren.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top