Ich möchte AngularJS mit Django verwenden, aber beide verwenden sie {{ }}
als Vorlagen-Tags. Gibt es eine einfache Möglichkeit, eines der beiden zu ändern, um ein anderes benutzerdefiniertes Vorlagen-Tag zu verwenden?
Ich möchte AngularJS mit Django verwenden, aber beide verwenden sie {{ }}
als Vorlagen-Tags. Gibt es eine einfache Möglichkeit, eines der beiden zu ändern, um ein anderes benutzerdefiniertes Vorlagen-Tag zu verwenden?
Antworten:
Für Angular 1.0 sollten Sie die Interpolationssymbole mit dem API $ interpolateProvider konfigurieren: http://docs.angularjs.org/api/ng.$interpolateProvider .
So etwas sollte den Trick machen:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Beachten Sie zwei Dinge:
{{ }}
in ihren Vorlagen verwendet werden, werden diese durch Ihre Konfiguration beschädigt. ( Fix ausstehend )Wir können zwar nichts gegen das erste Problem tun, außer Menschen zu warnen, aber wir müssen das zweite Problem angehen.
$interpolateProvider.startSymbol('{[{').endSymbol('}]}');
Sie können 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 Seitenabschnitte ordnungsgemäß getrennt haben, können Sie AngularJS-Tags problemlos im Bereich "Raw" -Tags verwenden.
In jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
In der Django-Vorlage (über 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Wir haben in Django 'ng' einen sehr einfachen Filter erstellt , der es einfach macht, beide zu mischen:
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)
Deshalb habe ich heute im Angular IRC-Kanal große Hilfe bekommen. Es stellt sich heraus, dass Sie Angulars Vorlagen-Tags sehr einfach ändern können. Die erforderlichen Snippets unten sollten nach Ihrem eckigen Include enthalten sein (das angegebene Beispiel wird in den Mailinglisten angezeigt und (())
als neue Vorlagen-Tags verwendet, die Ihre eigenen ersetzen):
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 verfügbar macht, startSymbol
und endSymbol
Eigenschaften, die auf beliebige Tags eingestellt werden können.
Ich stimme gegen die Verwendung von doppelten Klammern (()) als Vorlagen-Tag. Es kann gut funktionieren, solange kein Funktionsaufruf beteiligt ist, aber wenn Folgendes versucht wird
ng:disabled=(($invalidWidgets.visible()))
Mit Firefox (10.0.2) auf dem Mac habe ich einen furchtbar langen Fehler anstelle der beabsichtigten Logik erhalten. <[]> ist mir zumindest bis jetzt gut gegangen.
Edit 2012-03-29: Bitte beachten Sie, dass $ invalidWidgets veraltet ist. Ich würde jedoch immer noch einen anderen Wrapper als Doppelklammern verwenden. Für jede Winkelversion höher als 0.10.7 (ich denke) können Sie den Wrapper in Ihrer App / Modul-Definition viel einfacher ändern:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
(())
. Ich wollte nur die Trennzeichen konfigurieren können.
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)
<p>{% ng location %}</p>
Es wird gerendert als {{location}}
- ja mit geschweiften Klammern! Der Wert von $ scope.location, der in meinem Controller fest codiert ist, wird nicht gerendert. Irgendeine Idee, was ich vermisse?
Sie können jederzeit ng-bind anstelle von {{}} http://docs.angularjs.org/api/ng/directive/ngBind verwenden
<span ng-bind="name"></span>
Wenn Sie Django 1.5 und höher verwenden, verwenden Sie:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Wenn Sie mit Django 1.2 auf Appengine nicht weiterkommen, 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))
Verwenden Sie in Ihrer Datei:
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
from django import template
in: from google.appengine._internal.django import template
Dann, in meiner Hauptdatei, ändern Sie einfach den Dateinamen: template.register_template_library('utilities.verbatim_template_tag')
Mit dem Tag können Sie Django anweisen, {{
und }}
andere reservierte Vorlagenzeichenfolgen auszugeben {% templatetag %}
.
Zum Beispiel {% templatetag openvariable %}
würde using ausgeben {{
.
Ich würde mich an eine Lösung halten, die sowohl Django-Tags {{}} als auch Angularjs {{}} mit einem wörtlichen Abschnitt oder einem Templatetag verwendet.
Das liegt einfach daran, dass Sie die Funktionsweise von anglejs (wie erwähnt) über $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol ändern können. Wenn Sie jedoch andere angularjs-Komponenten wie den UI-Bootstrap verwenden, werden Sie feststellen, dass einige der Vorlagen BEREITS erstellt wurden mit Standard-Angularjs-Tags {{}}.
Schauen Sie sich zum Beispiel https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html an .
Wenn Sie eine serverseitige Interpolation durchführen, ist der einzig richtige Weg, dies zu tun<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Alles andere ist ein XSS-Vektor.
Dies liegt daran, dass alle Winkelbegrenzer, die nicht von Django maskiert werden, vom Benutzer in die interpolierte Zeichenfolge eingegeben werden können. Wenn jemand seinen Benutzernamen auf "{{evil_code}}" setzt, führt Angular ihn gerne aus . Wenn Sie einen Charakter verwenden, dem Django entkommt , wird dies jedoch nicht passieren.
templates
Verzeichnis, den Rest habe ich eingegebenstatic
. Auf diese Weise haben Sie keine Störungen. Es gibt ein Tutorial, das ich hier geschrieben habe: coderwall.com/p/bzjuka/…