Bienvenue sur IndexError.

Ici vous pouvez poser des questions sur Python et le Framework Django.

Mais aussi sur les technos front comme React, Angular, Typescript et Javascript en général.

Consultez la FAQ pour améliorer vos chances d'avoir des réponses à vos questions.

Formatage des nombres en français avec jinja2

+2 votes

Je souhaiterais que tous les nombres à virgule passés à Jinja2 soient (par défaut) formatés à la française c'est à dire avec une virgule (2,3 au lieu de 2.3).
Comme je suis amené à mettre beaucoup de références vers des nombres à virgule je ne veux pas utiliser des filtres à chaque fois.
Dans la même famille de question, est-il possible aussi de fixer le nombre de chiffre après la virgule à afficher lors du rendu (pas lors des calculs)?

En cherchant un peu je suis tombé sur ça http://jinja.pocoo.org/docs/dev/extensions/#i18n-extension mais j'ai pas compris si ça pouvait répondre à ma première question...!

demandé 27-Jan-2016 par sPaz (306 points)
edité 29-Jan-2016 par sPaz

C'est pas du i18n qu'il te faut mais du l10n

avec django il y a https://docs.djangoproject.com/en/1.8/ref/templates/language/#custom-tag-and-filter-libraries

ca donne

{% load humanize %}

{{ 45000|intcomma }}

reste à trouver l'equivalent chez jinja

On ne peut pas ne pas utiliser soit un filtre, soit une fonction normale. En effet ça voudrait dire que jinja detecte chaque chose pour voir quel type c'est et si il voit que c'est un nombre, il le formate. Une telle détection n'est pas du tout désirable et serait très hasardeuse en plus d'être lente. La réponse de foxmask est la bonne : il faut marquer explicitement toute les choses qu'on souhaite formater, et après on rend le formatage automatique. Mais le marquage ne peut être évité.

En continuant à chercher c'est effectivement ce qui ressort.
Quand j'ai commencer à trop sérieusement penser qu'il faudrait que je monkeypatch les floats, je me suis dis que je faisais fausse route et qu'il allait falloir que je fasse sans...

2 Réponses

+4 votes

je tente une réponse après avoir longuement cherché, j'ai trouvé que seul babel gérait le l10n et que jinja2 s'interfacait avec.

du coup ensuite j'imagine qu'il doit etre possible de faire

>>> from babel.numbers import format_number, format_decimal
>>> format_decimal(1.2345, locale='en_US')
u'1.234'
>>> format_decimal(1.2345, locale='sv_SE')
u'1,234'

soit dans un template

{% format_decimal(.....) %}

enfin coté flask ca se gere avec un context processor

@app.context_processor
def utility_processor():
    def format_price(amount, currency=u'€'):
        return u'{0:.2f}{1}'.format(amount, currency)
    return dict(format_price=format_price)

du coup dans le template ca donne

{{ format_price(0.33) }}

un truc plus souple est d'en faire un template filter comme il est dit dans la doc.

répondu 28-Jan-2016 par foxmask (2,888 points)

Et est-ce qu'il serait possible de rendre ce formatage par defaut pour tous les nombres?
Utiliser une fonction ou un filtre est quelque chose que j'aimerai éviter.

Ça s'appelle vouloir le beurre et l'argent du beurre

Et surtout le cul de la crémière.

Mais vu que je veux que tous les nombres à virgules soient formaté de la même manière ce n'est pas plutôt du 'Do not repeat yourself"?

Jusqu'à preuve du contraire, un filtre c'est DRY.

Si je le mets à chaque fois que je fais référence à un nombre je me repète. Et comme j'ai besoin que tous les nombres soient formatés de la même manière, j'ai le risque d'en oublier.

+3 votes

pas mieux que Foxmask.

sur Flask, j'ai fait un petite bidouille pour grouper par milliers:

LOCAL_ENCODING = locale.getlocale()

def grouping_numbers(number):
    return locale.format("%d", number, grouping=True).decode(LOCAL_ENCODING[1])

# ajout de filtres perso a jinja
app.jinja_env.filters['grouping_numbers'] = grouping_numbers

et ca s'utilise comme ca dans le template:

{{ mon_chiffre|grouping_numbers }}

j'ai pas tout chamboule sur les chiffres (un de mes js devient tout choses sinon), mais le principe est la si tu veux un truc perso

répondu 28-Jan-2016 par ashgan (698 points)

Même question qu'au dessus!

Et est-ce qu'il serait possible de rendre ce formatage par defaut pour tous les nombres?
Utiliser une fonction ou un filtre est quelque chose que j'aimerai éviter.

C'est surtout éviter les filtres que j'aimerai réussir à mettre en place!

dans les snippets flask, j'ai vu ca: http://flask.pocoo.org/snippets/29/

ce qui reviens a peu près au même.

l'ennui du filtre/decorateur, c'est que tu finis avec un string au lieu d'un int/float. suivant ton use case, c'est pas forcement désirable, surtout si tu as du js derriere.

Je n'aurai pas ce problème, j'utilise jinja2 pour produire des fichiers latex.
Les seules "choses" qui liront ces valeurs dernière seront des élèves et pour eux un nombre à virgule ça doit avoir une virgule et pas un point sinon ils sont tout perdus!

...