Django가있는 AngularJS-템플릿 태그 충돌


302

Django와 함께 AngularJS를 사용하고 싶지만 둘 다 {{ }}템플릿 태그로 사용 합니다. 다른 맞춤 템플릿 태그를 사용하기 위해 두 가지 중 하나를 쉽게 변경할 수 있습니까?


1
django templates디렉토리 에서 하나의 템플릿 만 렌더링 하고 나머지는 내가 넣었습니다 static. 그렇게하면 간섭이 없습니다. 내가 여기에 쓴 튜토리얼이있다 : coderwall.com/p/bzjuka/...는
코너 거머리

angular2와 jinja2 사이에 데이터를 전달하는 방법은 무엇입니까? 어떤 도움
Narendra

@ Narendra 그것은이 질문과 관련이없는 다른 문제입니다. 검색하여 답변을 찾지 못하면 새 질문으로 질문하십시오.
Endophage

답변:


299

Angular 1.0의 경우 $ interpolateProvider API를 사용하여 보간 기호를 구성해야합니다 ( http://docs.angularjs.org/api/ng.$interpolateProvider) .

이와 같은 것이 트릭을 수행해야합니다.

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

다음 두 가지를 명심하십시오.

  • 서버 측 템플릿과 클라이언트 측 템플릿을 혼합하는 것은 좋은 생각이 아니며주의해서 사용해야합니다. 주요 문제는 유지 관리 성 (읽기 어려운) 및 보안 (이중 보간으로 인해 새로운 보안 벡터가 노출 될 수 있음)입니다.
  • {{ }}템플릿에서 사용하는 타사 지시문 (구성 요소)을 사용하기 시작하면 구성이 중단됩니다. ( 수정 보류 중 )

경고 문제를 제외하고 첫 번째 문제에 대해 할 수있는 일은 없지만 두 번째 문제를 해결해야합니다.


4
첫 번째 요점을 설명해 주시겠습니까 (유지 관리, 보안 및 서버 측 템플릿과 클라이언트 측 템플릿을 혼합 할 때의 기타 우려 사항)? 좀 더 설명이 도움이 될 것입니다.
Brian

1
@ btlachance-답을 넓혔습니다.
Igor Minar

12
setter로 사용될 때 $ interpolateProvider가 자기 자신을 반환하기 때문에 다음은 약간 더 간결한 버전입니다. $interpolateProvider.startSymbol('{[{').endSymbol('}]}');
Mark Rajcok

5
"수정"이 닫혀있는 것 같습니다. 이제 타사 구성 요소를 사용하는 것이 안전하지 않습니까?
Alex Okrushko

1
원시 출력을 위해 $ interpolateProvider를 업데이트하는 방법도 있습니까? 예 : {{{foo}}}가 {{[{foo}]}}가 되었습니까?
테스터

122

당신은 어쩌면 시도 할 수 있습니다 그대로 장고 템플릿 태그와 같이 사용 :

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


이것이 매우 유효한 솔루션이지만 서버의 데이터로 뷰를 부트 스트랩 할 수 있기를 원할 경우가 있습니다. 사용자의 사용자 이름과 같은 것을 생각하십시오. 변경되지 않을 것이므로 서버의 템플릿에 씁니다.하지만 그 주위에 각도로 쓸 조각이있을 수 있습니다.
Endophage

16
Verbatim은 버전 1.5 이후 Django 코어 태그의 일부입니다. docs.djangoproject.com/en/dev/ref/templates/builtins/…
Pratyush

11
Django 1.7에서는 표준 태그 라이브러리에 있기 때문에 그대로로드 할 필요가 없습니다. 태그 자체 만 사용하면됩니다.
highpost

1
장고 기본 괄호를 설정에서 변경하는 방법이 좋을 것입니다. 그러나 이것은 작동합니다.
Adrian Lopez

42

페이지의 섹션을 올바르게 분리했다면 "원시"태그 범위에서 angularjs 태그를 쉽게 사용할 수 있습니다.

jinja2에서

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

장고 템플릿 (1.5 이상)

{% verbatim %}    
    // here you can write angularjs template tags.
{% endverbatim %}

1
이 솔루션은 외부 패키지가 허용되는 답변을 선호 할 때 호환성을 손상시키지 않습니다.
partizanos

30

우리는 만든 아주 쉽게 두 혼합 할 수 있습니다 장고 '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)

그것을 수행하는 또 다른 매우 유효한 방법이지만, 필터를 여러 개 추가하는 것보다 한곳에서 태그를 변경하고 싶습니다.
Endophage

1
ng 필터는 어떻게 만듭니 까? 예를 추가 할 수 있습니까?
Ben Liyanage 2014

답변이 업데이트되었습니다. 나는이 @Endophage 많은 차라리 장고 사람을 업데이트 할 것, 그래서 내가 장고 {{}} 쌍을 가지고보다 더 많은 각도 {{}} 쌍을.
Wes Alvaro

@WesAlvaro 불행히도 나는 단 하나의 대답 만 받아 들일 수 있습니다.
Endophage

26

그래서 오늘 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);
});

또한 앞으로 나올 향상된 기능 startSymbolendSymbol원하는 태그로 설정할 수있는 속성을 지적했습니다 .


17
그리고 이것은 당신이 angularjs 1.0에서하는 방법입니다 : var m = angular.module ( 'myApp', []); m.config (function ($ interpolateProvider) {$ interpolateProvider.startSymbol ( '(('); $ interpolateProvider.endSymbol ( '))');});
idursun

각도 IRC 채널. 누구에게나 fangw, 나는 #angularjs에서 하나를 발견했다
Shanimal

17

템플릿 태그로 큰 괄호 (())를 사용하는 것에 반대합니다. 함수 호출이 포함되지 않는 한 다음을 시도 할 때 제대로 작동 할 수 있습니다.

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

Mac에서 Firefox (10.0.2)를 사용하면 의도 된 논리 대신 매우 긴 오류가 발생했습니다. <[]>는, 적어도 지금까지는 나에게 잘 어울렸다.

2012-03-29 수정 : $ invalidWidgets는 더 이상 사용되지 않습니다. 그러나 여전히 이중 괄호가 아닌 다른 래퍼를 사용합니다. 0.10.7보다 높은 각 버전의 경우 앱 / 모듈 정의에서 래퍼를 훨씬 쉽게 변경할 수 있습니다.

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

API 문서 .


페어 포인트. 나는 그것을 생각하지 못했지만 특히을 사용하여 옹호하지는 않았지만 (())구분 기호를 구성하고 싶었습니다.
Endophage

15

아래 코드가 도움이되었다는 것을 알았습니다. 여기에서 코드를 찾았습니다 : 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 값을 렌더링하지 않습니다. 내가 뭘 놓치고 있는지 알아?
Keshav Agrawal


11

django 1.5 이상을 사용하는 경우 :

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

appengine에 django 1.2가 붙어 있으면 다음과 같은 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


고마워 ... 마침내이 작업을했지만 1) 새로운 파이썬 모듈을 만들어야했습니다. 나는 그것을 utilties라고 명명하고 그 안에 verbatim_templatetag.py 파일을 넣었다. (VerbatimNode 클래스가 정의 된 위의 파일). 2) import 문을 다음에서 다음 from django import template 으로 변경하십시오 . from google.appengine._internal.django import template 그런 다음 주 파일에서 파일 이름을 변경하십시오. template.register_template_library('utilities.verbatim_template_tag')
Roger

7

당신은 출력에 장고를 말할 수 {{}}뿐만 아니라 사용하여 다른 예약 템플릿 문자열 {% templatetag %}태그를.

예를 들어 using을 사용 {% templatetag openvariable %}하면 output이 출력 {{됩니다.


3
나는 그것이 가능하다는 것을 알고 있지만 지저분합니다 ... 템플릿 태그가 프레임 워크 중 하나에서 구성 할 수있는 것이 훨씬 깨끗합니다 (그리고 너무 크지 않은 것처럼 보입니다). 하루가 끝날 무렵에는 무대 뒤에서 문자열 매칭을하고 있습니다.
Endophage

3

나는 django 태그 {{}}와 angularjs {{}}를 구두 섹션 또는 templatetag와 함께 사용하는 솔루션을 고수합니다.

$ interpolateProvider.startSymbol $ interpolateProvider.endSymbol을 통해 angularjs의 작동 방식을 변경할 수 있기 때문에 ui-bootstrap과 같은 다른 angularjs 구성 요소를 사용하기 시작하면 일부 템플릿이 이미 빌드되어 있음을 알 수 있습니다 표준 angularjs 태그로 {{}}.

예를 들어 https://github.com/angular-ui/bootstrap/blob/master/template/dialog/message.html을보십시오 .


좋은 지적. PyPI에는 django-angular 패키지가있어 두 가지를 함께 사용하기가 쉽지만 템플릿 태그 문제를 얼마나 완화 시킬지는 고려하지 않았습니다.
Endophage 2016 년

0

당신은 어떤 서버 측 보간을 수행하는 경우 에만 할 수있는 올바른 방법을이 함께<>

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

다른 것은 XSS 벡터입니다.

Django가 이스케이프하지 않은 Angular 구분 기호는 보간 된 문자열에 사용자가 입력 할 수 있기 때문입니다. 누군가 자신의 사용자 이름을 "{{evil_code}}"로 설정하면 Angular는이를 행복하게 실행합니다 . 그러나 Django escapes보다 문자 를 사용하면 이런 일이 발생하지 않습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.