带有Django的Angularjs-冲突模板标签
-
25-10-2019 - |
题
我想将Angularjs与Django一起使用,但是它们都使用 {{ }}
作为模板标签。是否有一种简单的方法可以更改两者中的一种使用其他自定义模板标签?
解决方案
对于Angular 1.0,您应该使用$ InterpelyProvider API来配置插值符号: http://docs.angularjs.org/api/ng.junterpalyprovider.
这样的事情应该解决问题:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
请记住两件事:
- 混合服务器端和客户端模板很少是一个好主意,应谨慎使用。主要问题是:可维护性(难以阅读)和安全性(双重插值可能会暴露新的安全向量 - 例如,在逃脱了Serveride和客户端本身的逃脱可能是安全的,它们的组合可能不会是安全的)。
- 如果您开始使用使用的第三方指令(组件)
{{ }}
在它们的模板中,您的配置将破坏它们。 ((修复未决)
虽然第一个问题我们无能为力,除了警告人们,我们确实需要解决第二期。
其他提示
你可以尝试 逐字 Django模板标签并以此为单位:
<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 %}
如果您正确地完成了页面的单独部分,则可以轻松地使用“ 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'ng'中的过滤器,可以轻松混合两者:
foo.html:
...
<div>
{{ django_context_var }}
{{ 'angularScopeVar' | ng }}
{{ 'angularScopeFunction()' | ng }}
</div>
...
这 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)
因此,我今天在Angular IRC频道中获得了一些很大的帮助。事实证明,您可以很容易地更改Angular的模板标签。在您的角度包含角度之后,应包括下面的必要片段(给定的示例出现在其上 邮件列表 并会使用 (())
作为新模板标签,代替您自己的标签):
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
可以设置为您想要的任何标签的属性。
我投票反对使用双括号((())作为模板标签。只要涉及无功能调用,它可能会很好地工作,但是在尝试以下操作时
ng:disabled=(($invalidWidgets.visible()))
Mac上的Firefox(10.0.2)有一个非常长的错误,而不是预期的逻辑。 <[]>至少到现在为止,对我来说一切都很好。
编辑2012-03-29:请注意,$无效的Widgets已弃用。但是,我仍然使用另一个包装纸,而不是双括号。对于任何高于0.10.7的角版本(我想),您可以在应用程序 /模块定义中更容易更改包装器:
angular.module('YourAppName', [], function ($interpolateProvider) {
$interpolateProvider.startSymbol('<[');
$interpolateProvider.endSymbol(']>');
});
我发现下面的代码很有帮助。我在这里找到了代码: 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)
您可以随时使用ng-bind而不是{{}}http://docs.angularjs.org/api/ng/directive/ngbind
<span ng-bind="name"></span>
如果您使用Django 1.5并较新的用途:
{% verbatim %}
{{if dying}}Still alive.{{/if}}
{% endverbatim %}
如果您在附录上遇到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')
资源:http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-jquery-templates-in.html
您可以告诉Django输出 {{
和 }}
, ,以及其他保留的模板字符串 {% templatetag %}
标签。
例如,使用 {% templatetag openvariable %}
会输出 {{
.
我会坚持使用django标签{{}}的解决方案,以及angularjs {{}}的解决方案。
这仅仅是因为您可以通过$ InterpalyProvider.startsymbol $ InterpalyProvider.endsymbol更改AngularJS的工作方式(如前所述),但是如果您开始使用其他AngularJS组件,例如UI-BootStrap,您会发现一些模板已经建立了使用标准的AngularJS标签{{}}。
例如看 https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html.
如果您执行任何服务器端插值, 只要 正确的方法是 <>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
其他任何东西都是XSS向量。
这是因为用户可以输入任何未被Django逃脱的角度分离器中的插值字符串;如果有人将其用户名设置为“ {{evil_code}}”, Angular会快乐地运行它. 。如果您使用 角色比Django逃脱, 但是,这不会发生。