我想将AngularJS与Django一起使用,但是他们都使用 {{ }} 作为模板标签 . 是否有一种简单的方法来改变其中一个使用其他自定义模板标签?
{{ }}
我们在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)
我反对使用双括号(())作为模板标签 . 只要不涉及函数调用但是在尝试以下时它可能会很好地工作
ng:disabled=(($invalidWidgets.visible()))
使用Mac上的Firefox(10.0.2)我得到了一个非常长的错误而不是预期的逻辑 . <[]>对我来说很顺利,至少到现在为止 .
Edit 2012-03-29: 请注意,不推荐使用$ invalidWidgets . 但是,我仍然使用另一个包装而不是双括号 . 对于任何高于0.10.7的角度版本(我猜),您可以在app /模块定义中更轻松地更改包装:
angular.module('YourAppName', [], function ($interpolateProvider) { $interpolateProvider.startSymbol('<['); $interpolateProvider.endSymbol(']>'); });
API docs .
所以今天我在Angular IRC Channels 得到了很多帮助 . 事实证明,您可以非常轻松地更改Angular的模板标签 . 在你的角度包含之后,应该包含下面必要的片段(给定的例子出现在他们的mailing lists上,并使用 (()) 作为新的模板标签,替换你自己的):
(())
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
对于Angular 1.0,您应该使用$ interpolateProvider apis来配置插值符号:http://docs.angularjs.org/api/ng.$interpolateProvider .
像这样的东西应该做的伎俩:
myModule.config(function($interpolateProvider) { $interpolateProvider.startSymbol('{[{'); $interpolateProvider.endSymbol('}]}'); });
请记住两件事:
混合服务器端和客户端模板很少是一个好主意,应谨慎使用 . 主要问题是:可维护性(难以阅读)和安全性(双插值可能暴露出新的安全性向量 - 例如,当服务器端和客户端模板本身的模板化可能是安全的时,它们的组合可能不是) .
如果您开始使用在其模板中使用 {{ }} 的第三方指令(组件),那么您的配置将破坏它们 . (fix pending)
虽然我们无法对第一个问题采取任何措施,但警告人员除外,我们确实需要解决第二个问题 .
对于AngularJS v1.3.3,您应该像这样定义自己的模板标签
AngularJS module
angular.module('myapp', []).config(function($interpolateProvider) { $interpolateProvider.startSymbol('{$'); $interpolateProvider.endSymbol('$}'); });
Webpage
<a>{$ variable $}</a>
您始终可以使用ng-bind而不是{{}} http://docs.angularjs.org/api/ng/directive/ngBind
<span ng-bind="name"></span>
你可以试试verbatim 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 %}
如果你使用django 1.5和更新的使用:
{% verbatim %} {{if dying}}Still alive.{{/if}} {% endverbatim %}
如果你坚持使用django 1.2 on appengine使用verbatim模板命令扩展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-templates-in.html
如果您进行任何服务器端插值, only 正确的方法是使用 <>
<>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
其他任何东西都是XSS向量 .
这是因为任何未被Django转义的角度分隔符都可以由用户输入到插值字符串中;如果有人将其用户名设置为"{}",Angular will happily run it . 但是,如果使用character than Django escapes,则不会发生这种情况 .
我发现下面的代码很有帮助 . 我在这里找到了代码: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)
您可以通过使用{% templatetag %}标记告诉Django输出 {{ 和 }} 以及其他保留的模板字符串 .
{{
}}
例如,使用 {% templatetag openvariable %} 将输出 {{ .
{% templatetag openvariable %}
如果你正确地分开了页面部分,那么你可以在“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 {{}}和逐字段或模板标签的解决方案 .
这只是因为您可以通过$ interpolateProvider.startSymbol $ interpolateProvider.endSymbol更改angularjs的工作方式(如上所述),但如果您开始使用其他angularjs组件(如ui-bootstrap),您会发现某些模板已经内置使用标准的angularjs标签{{}} .
例如,查看https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .
13 回答
我们在Django 'ng'中创建了一个非常简单的过滤器,可以很容易地将两者混合使用:
foo.html:
ng
过滤器如下所示:我反对使用双括号(())作为模板标签 . 只要不涉及函数调用但是在尝试以下时它可能会很好地工作
使用Mac上的Firefox(10.0.2)我得到了一个非常长的错误而不是预期的逻辑 . <[]>对我来说很顺利,至少到现在为止 .
Edit 2012-03-29: 请注意,不推荐使用$ invalidWidgets . 但是,我仍然使用另一个包装而不是双括号 . 对于任何高于0.10.7的角度版本(我猜),您可以在app /模块定义中更轻松地更改包装:
API docs .
所以今天我在Angular IRC Channels 得到了很多帮助 . 事实证明,您可以非常轻松地更改Angular的模板标签 . 在你的角度包含之后,应该包含下面必要的片段(给定的例子出现在他们的mailing lists上,并使用
(())
作为新的模板标签,替换你自己的):此外,我被指出即将推出的增强功能,它将公开
startSymbol
和endSymbol
属性,可以设置为您想要的任何标签 .对于Angular 1.0,您应该使用$ interpolateProvider apis来配置插值符号:http://docs.angularjs.org/api/ng.$interpolateProvider .
像这样的东西应该做的伎俩:
请记住两件事:
混合服务器端和客户端模板很少是一个好主意,应谨慎使用 . 主要问题是:可维护性(难以阅读)和安全性(双插值可能暴露出新的安全性向量 - 例如,当服务器端和客户端模板本身的模板化可能是安全的时,它们的组合可能不是) .
如果您开始使用在其模板中使用
{{ }}
的第三方指令(组件),那么您的配置将破坏它们 . (fix pending)虽然我们无法对第一个问题采取任何措施,但警告人员除外,我们确实需要解决第二个问题 .
对于AngularJS v1.3.3,您应该像这样定义自己的模板标签
AngularJS module
Webpage
您始终可以使用ng-bind而不是{{}} http://docs.angularjs.org/api/ng/directive/ngBind
你可以试试verbatim Django模板标签并像这样使用它:
如果你使用django 1.5和更新的使用:
如果你坚持使用django 1.2 on appengine使用verbatim模板命令扩展django语法,就像这样......
在您的文件中使用:
资料来源:http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html
如果您进行任何服务器端插值, only 正确的方法是使用
<>
其他任何东西都是XSS向量 .
这是因为任何未被Django转义的角度分隔符都可以由用户输入到插值字符串中;如果有人将其用户名设置为"{}",Angular will happily run it . 但是,如果使用character than Django escapes,则不会发生这种情况 .
我发现下面的代码很有帮助 . 我在这里找到了代码:http://djangosnippets.org/snippets/2787/
您可以通过使用{% templatetag %}标记告诉Django输出
{{
和}}
以及其他保留的模板字符串 .例如,使用
{% templatetag openvariable %}
将输出{{
.如果你正确地分开了页面部分,那么你可以在“raw”标签范围内轻松使用angularjs标签 .
在jinja2
在Django模板中(1.5以上)
我会坚持使用django标签{{}}以及angularjs {{}}和逐字段或模板标签的解决方案 .
这只是因为您可以通过$ interpolateProvider.startSymbol $ interpolateProvider.endSymbol更改angularjs的工作方式(如上所述),但如果您开始使用其他angularjs组件(如ui-bootstrap),您会发现某些模板已经内置使用标准的angularjs标签{{}} .
例如,查看https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .