Question

Je veux utiliser AngularJS avec Django mais ils ont tous deux {{ }} utilisent comme leurs balises de modèle. Est-il un moyen facile de changer l'un des deux à utiliser une autre balise templating personnalisé?

Était-ce utile?

La solution

Pour Angular 1.0, vous devez utiliser le $ interpolateProvider apis pour configurer les symboles d'interpolation: http: //docs.angularjs. org / api / ng. $ interpolateProvider .

Quelque chose comme ça devrait faire l'affaire:

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

Gardez à l'esprit deux choses:

  • mélange côté serveur et des modèles côté client est rarement une bonne idée et doit être utilisé avec prudence. Les principaux problèmes sont les suivants:. Maintenabilité (difficile à lire) et la sécurité (à double interpolation pourrait exposer un nouveau vecteur de sécurité - par exemple tout en échappant de Serverside et clientside par eux-mêmes templating pourrait être sûr, leur combinaison peut-être pas)
  • si vous commencez à utiliser des directives tiers (composants) qui {{ }} d'utiliser dans leurs modèles, alors votre configuration les casser. ( fix en attente)

Bien qu'il n'y ait rien que nous pouvons faire à la première question, à l'exception des personnes en garde, nous devons répondre à la deuxième question.

Autres conseils

vous pouvez peut-être essayer verbatim Django tag modèle et l'utiliser comme ceci:

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

Si vous avez des sections distinctes de la page correctement alors vous pouvez facilement utiliser les balises AngularJS portée tag « brut ».

Dans jinja2

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

modèle Django (supérieure à 1,5)

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

Nous avons créé un très Filtre simple dans Django 'ng' qui le rend facile de mélanger les deux:

foo.html:

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

Le filtre de ng ressemble à ceci:

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)

Je suis une grande aide dans le canal IRC angulaire aujourd'hui. Il se trouve que vous pouvez modifier les balises de modèle de angulaire très facilement. Les extraits ci-dessous nécessaires devraient être inclus après votre angulaire inclure (l'exemple donné apparaît sur leur listes de diffusion et utiliseraient (()) que les nouvelles balises de modèle, de remplacement pour votre propre):

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

En outre, je montrai une amélioration à venir qui exposera les propriétés de startSymbol et endSymbol qui peuvent être réglées à ce que les balises que vous désirez.

Je vote contre l'utilisation de doubles parenthèses (()) comme étiquette de modèle. Il se pourrait bien travailler aussi longtemps qu'aucun appel de fonction est impliqué mais quand essayé ce qui suit

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

avec Firefox (10.0.2) sur Mac j'ai eu une erreur terriblement long au lieu de la logique prévue. <[]> Est allé bien pour moi, au moins jusqu'à présent.

Modifier 2012-03-29: S'il vous plaît noter que $ invalidWidgets est dépréciée. Cependant, je serais toujours utiliser un autre emballage que des accolades doubles. Pour toute version angulaire supérieure à 0.10.7 (je suppose), vous pouvez changer l'emballage beaucoup plus facile dans votre définition app / Module:

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

API docs .

J'ai trouvé le code ci-dessous utile. Je trouve ici le code: 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)

Vous pouvez toujours utiliser au lieu de lier ng-{{}} http://docs.angularjs.org/api/ng/directive/ngBind

<span ng-bind="name"></span>

Si vous utilisez django 1.5 et plus récente utilisation:

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

Si vous êtes coincé avec django 1.2 sur AppEngine étendre la syntaxe django avec la commande de modèle pour mot comme ceci ...

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

Dans votre utilisation du fichier:

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

Vous pouvez dire à Django à la sortie {{ et }}, ainsi que d'autres chaînes de modèle réservés en utilisant le {% templatetag %} balise.

Par exemple, en utilisant {% templatetag openvariable %} serait {{ de sortie.

Je collerait une solution qui utilise à la fois les balises {{django}} et {{AngularJS}} avec soit une section in extenso ou templatetag.

C'est tout simplement parce que vous pouvez changer la façon dont fonctionne AngularJS (comme mentionné) via le interpolateProvider.endSymbol interpolateProvider.startSymbol $ $, mais si vous commencez à utiliser d'autres composants comme le AngularJS ui-bootstrap, vous trouverez que certains des modèles sont déjà construits avec des balises standards AngularJS {{}}.

Par exemple consulter https: // GitHub. com / angulaire ui / bootstrap / blob / maître / template / dialogue / message.html .

Si vous faites une interpolation côté serveur, le uniquement bonne façon de le faire est avec <>

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

Tout est bien un vecteur XSS.

En effet, tout délimiteurs angulaire qui ne sont pas échappés par Django peuvent être saisies par l'utilisateur dans la chaîne interpolée; si quelqu'un fixe leur nom d'utilisateur comme « {{evil_code}} », angulaire se fera un plaisir courir . Si vous utilisez un caractère que Django échappe cependant, cela ne se produira pas.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top