Я хочу использовать AngularJS с Django, но оба они используют {{ }}
в качестве тегов шаблонов. Есть ли простой способ изменить один из двух, чтобы использовать другой пользовательский шаблонный тег?
Для Angular 1.0 вы должны использовать api-интерполяциюProvider для настройки символов интерполяции: http://docs.angularjs.org/api/ng.$interpolateProvider.
Что-то вроде этого должно сделать трюк:
myModule.config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{[{');
$interpolateProvider.endSymbol('}]}');
});
Помните о двух вещах:
{{ }}
в своих шаблонах, тогда ваша конфигурация сломает их. (исправить ошибку)Пока мы ничего не можем сделать по первому вопросу, кроме предупреждения людей, нам нужно решить вторую проблему.
вы можете попробовать 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 %}
Если вы правильно разделили разделы страницы, вы можете легко использовать теги angularjs в области "raw".
В 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)
Итак, сегодня я получил большую помощь в канале IRC Angular. Оказывается, вы можете легко изменить теги шаблона Angular. Необходимые ниже фрагменты должны быть включены после включения 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()))
с Firefox (10.0.2) на Mac Я получил ужасно длинную ошибку вместо предполагаемой логики. < [] > прошел хорошо для меня, по крайней мере, до сих пор.
Изменить 2012-03-29: Обратите внимание, что $invalidWidgets устарело. Однако я бы использовал еще одну оболочку, чем двойные фигурные скобки. Для любой версии angular выше 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)
<p>{% ng location %}</p>
он будет отображаться как {{location}}
- да с фигурными скобками! Он не отображает значение $ scope.location, которое жестко задано в моем контроллере. Есть идеи, что мне не хватает?
Вы всегда можете использовать 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 в appengine, расширьте синтаксис django командой verbatim template, подобной этой...
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
from django import template
на: from google.appengine._internal.django import template
Затем в моем главном файле просто изменили имя файла: template.register_template_library('utilities.verbatim_template_tag')
Для AngularJS v1.3.3 вы должны определить свои собственные теги шаблонов, такие как
Модуль AngularJS
angular.module('myapp', []).config(function($interpolateProvider) {
$interpolateProvider.startSymbol('{$');
$interpolateProvider.endSymbol('$}');
});
страница
<a>{$ variable $}</a>
Вы можете указать Django для вывода {{
и }}
, а также других зарезервированных строк шаблонов с помощью тега {% templatetag %}
.
Например, использование {% templatetag openvariable %}
будет выводить {{
.
Я бы придерживался решения, которое использует как теги django {{}}, так и angularjs {{}} с дословным разделом или templatetag.
Это просто потому, что вы можете изменить способ работы angularjs (как упоминалось) через $interpolateProvider.startSymbol $interpolateProvider.endSymbol, но если вы начнете использовать другие компоненты angularjs, такие как ui-bootstrap, вы обнаружите, что некоторые из шаблонов УЖЕ построены со стандартными метками angularjs {{}}.
Например, посмотрите https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html.
Если вы выполняете любую интерполяцию на стороне сервера, правильный способ только - это <>
$interpolateProvider.startSymbol('<{').endSymbol('}>');
Все остальное - вектор XSS.
Это связано с тем, что любые разделители Angular, которые не экранируются Django, могут быть введены пользователем в интерполированную строку; если кто-то устанавливает свое имя пользователя как "{{evil_code}}", Angular будет с радостью запускать его. Если вы используете символ чем escape файлы Django, этого не произойдет.
templates
каталога, остальное я ставлю вstatic
. Таким образом, у вас нет помех. Вот учебник, который я написал здесь: coderwall.com/p/bzjuka/…