我想使用AngularJS与Django,但他们都使用{{ }}作为他们的模板标签。是否有一种简单的方法来更改其中之一,以使用其他自定义模板标签?
{{ }}
你可以通过使用{% templatetag %}标签告诉Django输出\{\{和}},以及其他保留的模板字符串。
{% templatetag %}
\{\{
}}
例如,使用{% templatetag openvariable %}将输出\{\{。
{% templatetag openvariable %}
所以今天我在Angular IRC频道得到了很大的帮助。事实证明,你可以很容易地更改Angular的模板标签。下面的必要代码段应该包含在你的angular include之后(给定的例子出现在他们的邮件列表上,并且会使用(())作为新的模板标签,代替你自己的):
(())
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); });
此外,我还指出了一个即将到来的增强,它将公开startSymbol和endSymbol属性,可以将它们设置为您想要的任何标记。
startSymbol
endSymbol
我投票反对使用双括号(())作为模板标签。只要不涉及函数调用,它就可以很好地工作,但当尝试以下方法时
ng:disabled=(($invalidWidgets.visible()))
在Mac上使用Firefox(10.0.2)时,我得到了一个非常长的错误,而不是预期的逻辑。我过得很顺利,至少到目前为止是这样。
<强>编辑2012-03-29: 请注意,$invalidWidgets已弃用。然而,我仍然会使用另一种包装而不是双括号。对于任何高于0.10.7的angular版本(我猜),你可以在应用/模块定义中更容易地更改包装器:
angular.module('YourAppName', [], function ($interpolateProvider) { $interpolateProvider.startSymbol('<['); $interpolateProvider.endSymbol(']>'); });
API文档。
<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 %}
对于Angular 1.0,你应该使用$interpolateProvider api来配置插值符号:interpolateProvider美元http://docs.angularjs.org/api/ng。。
像这样的东西应该可以达到目的:
myModule.config(function($interpolateProvider) { $interpolateProvider.startSymbol('{[{'); $interpolateProvider.endSymbol('}]}'); });
请记住两件事:
\{\{ }}
虽然我们对第一个问题无能为力,除了警告人们,但我们确实需要解决第二个问题。
我们在Django 'ng'中创建了非常简单过滤器,可以很容易地将两者混合:
foo.html:
... <div> \{\{ django_context_var }} \{\{ 'angularScopeVar' | ng }} \{\{ 'angularScopeFunction()' | ng }} </div> ...
ng过滤器看起来像这样:
ng
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)
我发现下面的代码很有用。我在这里找到了代码: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)
如果你使用django 1.5及更新版本:
{% verbatim %} \{\{if dying}}Still alive.\{\{/if}} {% endverbatim %}
如果你还在使用appengine上的django 1.2,可以使用下面的命令来扩展django语法…
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))
在你的文件中使用:
from google.appengine.ext.webapp import template template.register_template_library('utilities.verbatim_template_tag')
如果你正确地分离了页面的各个部分,那么你可以很容易地在“raw”标签范围内使用angularjs标签。
在jinja2
{% raw %} // here you can write angularjs template tags. {% endraw %}
在Django模板中(1.5以上)
{% verbatim %} // here you can write angularjs template tags. {% endverbatim %}
我会坚持使用一个解决方案,既使用django标签\{\{}},也使用angularjs\{\{}},并使用一个逐字section或templatetag。
这只是因为你可以通过$interpolateProvider改变angularjs的工作方式(如上所述)。startSymbol interpolateProvider美元。但是如果你开始使用其他angularjs组件,比如ui-bootstrap,你会发现一些模板已经用标准angularjs标签\{\{}}构建了。
例如,查看https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html。
你总是可以使用ng-bind而不是\{\{}} http://docs.angularjs.org/api/ng/directive/ngBind < / p >
<span ng-bind="name"></span>
如果你做任何服务器端插值,正确的方法是用<>
<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
其他任何向量都是XSS向量。
这是因为任何没有被Django转义的Angular分隔符都可以被用户输入到插入的字符串中;如果有人将他们的用户名设置为“\{\{evil_code}}”,Angular会很乐意运行它。然而,如果你使用而不是Django,这就不会发生。