AngularJS with Django - Conflicting template tags

2018-12-31 19:47发布

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 templating tag?

13条回答
冷夜・残月
2楼-- · 2018-12-31 20:09

If you did separate sections of page properly then you can easily use angularjs tags in "raw" tag scope.

In jinja2

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

In Django template (above 1.5)

{% verbatim %}    
    // here you can write angularjs template tags.
{% endverbatim %}
查看更多
十年一品温如言
3楼-- · 2018-12-31 20:11

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)
查看更多
谁念西风独自凉
4楼-- · 2018-12-31 20:11

I would stick with a solution that uses both django tags {{}} as well angularjs {{}} with a either a verbatim section or templatetag.

That is simply because you can change the way angularjs works (as mentioned) via the $interpolateProvider.startSymbol $interpolateProvider.endSymbol but if you start to use other angularjs components like the ui-bootstrap you will find that some of the templates are ALREADY built with standard angularjs tags {{ }}.

For example look at https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html.

查看更多
初与友歌
5楼-- · 2018-12-31 20:13

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.

查看更多
初与友歌
6楼-- · 2018-12-31 20:15

If you use django 1.5 and newer use:

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

If you are stuck with django 1.2 on appengine extend the django syntax with the verbatim template command like this ...

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

In your file use:

from google.appengine.ext.webapp import template
template.register_template_library('utilities.verbatim_template_tag')

Source: http://bamboobig.blogspot.co.at/2011/09/notebook-using-jquery-templates-in.html

查看更多
人间绝色
7楼-- · 2018-12-31 20:18

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.

查看更多
登录 后发表回答