AngularJS with Django - Conflicting template tags

前端 未结 12 2149
南笙
南笙 2020-11-22 13:39

I want to use AngularJS with Django however they both use {{ }} as their template tags. Is there an easy way to change one of the two to use some other custom

相关标签:
12条回答
  • 2020-11-22 14:19

    I found the code below helpful. I found the code here: 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)
    
    0 讨论(0)
  • 2020-11-22 14:24

    We created a very simple filter in Django 'ng' that makes it easy to mix the two:

    foo.html:

    ...
    <div>
      {{ django_context_var }}
      {{ 'angularScopeVar' | ng }}
      {{ 'angularScopeFunction()' | ng }}
    </div>
    ...
    

    The ng filter looks like this:

    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)
    
    0 讨论(0)
  • 2020-11-22 14:26

    So I got some great help in the Angular IRC channel today. It turns out you can change Angular's template tags very easily. The necessary snippets below should be included after your angular include (the given example appears on their mailing lists and would use (()) as the new template tags, substitute for your own):

    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);
    });
    

    Also, I was pointed to an upcoming enhancement that will expose startSymbol and endSymbol properties that can be set to whatever tags you desire.

    0 讨论(0)
  • 2020-11-22 14:27

    you can maybe try verbatim Django template tag and use it like this :

    <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 %}

    0 讨论(0)
  • 2020-11-22 14:27

    If you do any server-side interpolation, the only correct way to do this is with <>

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

    Anything else is an XSS vector.

    This is because any Angular delimiters which are not escaped by Django can be entered by the user into the interpolated string; if someone sets their username as "{{evil_code}}", Angular will happily run it. If you use a character than Django escapes, however, this won't happen.

    0 讨论(0)
  • 2020-11-22 14:31

    You can tell Django to output {{ and }}, as well as other reserved template strings by using the {% templatetag %} tag.

    For instance, using {% templatetag openvariable %} would output {{.

    0 讨论(0)
提交回复
热议问题