Je souhaite utiliser AngularJS avec Django, mais ils utilisent tous les deux {{ }}
comme balises de modèle. Existe-t-il un moyen simple de changer l’un des deux pour utiliser une autre balise de modèle personnalisée?
Pour Angular 1.0, utilisez l’API $ interpolateProvider pour configurer les symboles d’interpolation: http://docs.angularjs.org/api/ng.$interpolateProvider .
Quelque chose comme ça devrait faire l'affaire:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Gardez à l'esprit deux choses:
{{ }}
dans leurs modèles, votre configuration les supprimera. ( correction en attente )Bien que nous ne puissions rien faire à propos du premier problème, à part avertir les gens, nous devons nous attaquer au deuxième problème.
vous pouvez peut-être essayer verbatim balise de modèle Django .__ et l'utiliser comme ceci:
<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 %}
Si vous avez bien séparé les sections de page, vous pouvez facilement utiliser les balises angularjs dans la portée des balises "raw".
Dans jinja2
{% raw %}
// here you can write angularjs template tags.
{% endraw %}
Dans le modèle Django (au dessus de 1.5)
{% verbatim %}
// here you can write angularjs template tags.
{% endverbatim %}
Nous avons créé un filtre very simple dans Django 'ng' qui facilite le mélange des deux:
foo.html:
...
<div>
{{ Django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
Le filtre ng
ressemble à ceci:
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)
J'ai donc eu une aide précieuse dans le canal angulaire IRC aujourd'hui. Il s'avère que vous pouvez très facilement changer les balises de template d'Angular. Les extraits nécessaires ci-dessous doivent être inclus après votre inclusion angulaire (l'exemple donné apparaît sur leurs listes de diffusion et utiliserait (())
comme nouvelle balise de modèle, remplaçant la votre)
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);
});
De plus, on m'a signalé une amélioration à venir qui exposerait les propriétés startSymbol
et endSymbol
pouvant être définies sur les balises de votre choix.
Je vote contre l'utilisation de doubles parenthèses (()) comme balise modèle. Cela peut bien fonctionner tant qu’aucun appel de fonction n’est impliqué, mais lorsque vous essayez, procédez comme suit:
ng:disabled=(($invalidWidgets.visible()))
avec Firefox (10.0.2) sur Mac j'ai eu une erreur terriblement longue au lieu de la logique prévue. <[]> s'est bien passé pour moi, du moins jusqu'à maintenant.
Edit 2012-03-29: Veuillez noter que $ invalidWidgets est obsolète. Cependant, j'utiliserais encore un autre wrapper que les doubles accolades. Pour toute version angulaire supérieure à 0.10.7 (je suppose), vous pouvez changer l'encapsuleur beaucoup plus facilement dans la définition de votre application/module:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
J'ai trouvé le code ci-dessous utile. J'ai trouvé le code ici: 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)
Vous pouvez toujours utiliser ng-bind au lieu de {{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
Si vous utilisez Django 1.5 et plus récent, utilisez:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
Si vous êtes coincé avec Django 1.2 sur Appengine, étendez la syntaxe de Django avec la commande de modèle verbatim comme ceci ...
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))
Dans votre fichier, utilisez:
from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')
Source: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
Pour AngularJS v1.3.3, vous devez définir vos propres balises de modèle, comme ceci
Module AngularJS
angular.module('myapp', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
});
Page Web
<a>{$ variable $}</a>
Vous pouvez indiquer à Django de générer {{
et }}
, ainsi que d'autres chaînes de modèle réservées, en utilisant la balise {% templatetag %}
.
Par exemple, utiliser {% templatetag openvariable %}
générerait {{
.
Je préférerais utiliser une solution qui utilise les deux balises Django {{}} ainsi que angularjs {{}} avec une section ou une balise de type verbatim.
C’est simplement parce que vous pouvez modifier le fonctionnement d’angularjs (comme indiqué) via $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol, mais si vous commencez à utiliser d’autres composants angularjs comme ui-bootstrap, vous constaterez que certains modèles sont déjà construits avec les balises angularjs standard {{}}.
Par exemple, consultez https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
Si vous effectuez une interpolation côté serveur, la méthode correcte pour uniquement consiste à utiliser <>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Tout le reste est un vecteur XSS.
En effet, tout délimiteur angulaire non échappé par Django peut être saisi par l'utilisateur dans la chaîne interpolée. si quelqu'un définit son nom d'utilisateur comme "{{evil_code}}", Angular le fera fonctionner avec plaisir Si vous utilisez un caractère que Django échappe , cependant, cela n'arrivera pas.