AngularJS с Django - конфликтующие шаблоны тегов

javascript django django-templates angularjs

73034 просмотра

12 ответа

14065 Репутация автора

Я хочу использовать AngularJS с Django, однако оба они используют в {{ }}качестве шаблонов тегов. Есть ли простой способ изменить один из двух, чтобы использовать какой-либо другой пользовательский шаблонный тег?

Автор: Endophage Источник Размещён: 28.11.2011 09:55

Ответы (12)


7 плюса

38429 Репутация автора

Вы можете указать Django выводить {{и }}, а также другие зарезервированные строки шаблона, используя {% templatetag %}тег.

Например, используя {% templatetag openvariable %}бы вывод {{.

Автор: Thomas Orozco Размещён: 29.11.2011 02:26

26 плюса

14065 Репутация автора

Так что сегодня я получил большую помощь на канале 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свойства, которые могут быть установлены для любых тегов, которые вы хотите.

Автор: Endophage Размещён: 10.12.2011 01:51

17 плюса

171 Репутация автора

Я голосую против использования двойных скобок (()) в качестве тега шаблона. Это может работать хорошо до тех пор, пока не задействован вызов функции, но при попытке выполнить следующее

ng:disabled=(($invalidWidgets.visible()))

с Firefox (10.0.2) на Mac я получил ужасно длинную ошибку вместо предполагаемой логики. <[]> хорошо для меня, по крайней мере, до сих пор.

Изменить 2012-03-29: Обратите внимание, что $ invalidWidgets устарела. Однако я бы по-прежнему использовал другую обертку, чем двойные скобки. Для любой угловой версии выше 0.10.7 (я полагаю) вы могли бы изменить оболочку намного проще в определении вашего приложения / модуля:

angular.module('YourAppName', [], function ($interpolateProvider) {
    $interpolateProvider.startSymbol('<[');
    $interpolateProvider.endSymbol(']>');
}); 

API документы .

Автор: Lukas Bünger Размещён: 07.03.2012 08:26

120 плюса

1213 Репутация автора

Вы можете, возможно, попробовать дословно тег шаблона 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 %}

Автор: Bessoufi Mounir Размещён: 30.05.2012 08:30

296 плюса

9464 Репутация автора

Решение

Для Angular 1.0 вы должны использовать apis $ interpolateProvider для настройки символов интерполяции: http://docs.angularjs.org/api/ng.$interpolateProvider .

Нечто подобное должно сделать свое дело:

myModule.config(function($interpolateProvider) {
  $interpolateProvider.startSymbol('{[{');
  $interpolateProvider.endSymbol('}]}');
});

Имейте в виду две вещи:

  • Смешивание серверных и клиентских шаблонов редко является хорошей идеей и должно использоваться с осторожностью. Основные проблемы: удобство сопровождения (трудно читаемое) и безопасность (двойная интерполяция может обнажить новый вектор безопасности - например, если экранирование на стороне сервера и на стороне клиента само по себе может быть безопасным, их комбинация может и не быть).
  • если вы начнете использовать сторонние директивы (компоненты), которые используют {{ }}в своих шаблонах, ваша конфигурация нарушит их. ( исправление ожидается )

Хотя с первым вопросом мы ничего не можем поделать, кроме как предупреждать людей, нам нужно решить второй вопрос.

Автор: Igor Minar Размещён: 19.06.2012 07:55

29 плюса

507 Репутация автора

Мы создали очень простой фильтр в 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)
Автор: Wes Alvaro Размещён: 24.08.2012 01:01

15 плюса

4524 Репутация автора

Я нашел код ниже полезным. Я нашел код здесь: 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)
Автор: nu everest Размещён: 11.11.2012 12:34

11 плюса

2213 Репутация автора

Если вы используете django 1.5 и новее, используйте:

  {% verbatim %}
    {{if dying}}Still alive.{{/if}}
  {% endverbatim %}

Если вы застряли с django 1.2 в appengine, расширьте синтаксис django с помощью команды шаблонов verbatim, как это ...

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

Автор: cat Размещён: 04.02.2013 02:16

42 плюса

922 Репутация автора

Если вы правильно сделали отдельные разделы страницы, то вы можете легко использовать теги angularjs в области «необработанных» тегов.

В jinja2

{% raw %}
    // here you can write angularjs template tags.
{% endraw %}

В шаблоне Django (выше 1.5)

{% verbatim %}    
    // here you can write angularjs template tags.
{% endverbatim %}
Автор: thanksnote Размещён: 31.05.2013 02:39

3 плюса

603 Репутация автора

Я бы остановился на решении, которое использует как теги django {{}}, так и angularjs {{}} либо с дословным разделом, либо с тегом шаблона.

Это просто потому, что вы можете изменить способ работы angularjs (как уже упоминалось) с помощью $ interpolateProvider.startSymbol $ interpolateProvider.endSymbol, но если вы начнете использовать другие компоненты angularjs, такие как ui-bootstrap, вы обнаружите, что некоторые шаблоны уже построены со стандартными тегами angularjs {{}}.

Например, посмотрите на https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html .

Автор: silviud Размещён: 29.06.2013 08:42

14 плюса

669 Репутация автора

Вы всегда можете использовать ng-bind вместо {{}} http://docs.angularjs.org/api/ng/directive/ngBind

<span ng-bind="name"></span>
Автор: Indomitable Размещён: 27.02.2014 02:45

0 плюса

7669 Репутация автора

Если вы делаете какую-либо серверную интерполяцию, единственный правильный способ сделать это с<>

$interpolateProvider.startSymbol('<{').endSymbol('}>');

Все остальное является вектором XSS.

Это связано с тем, что любые угловые разделители, которые не экранированы Django, могут быть введены пользователем в интерполированную строку; если кто-то установит свое имя пользователя как "{{evil_code}}", Angular с удовольствием его запустит . Если вы используете персонажа, то Django убегает , однако этого не произойдет.

Автор: Dan Размещён: 21.02.2016 05:49
Вопросы из категории :
32x32