Ticket #70: forms-i18n.patch

File forms-i18n.patch, 17.5 kB (added by Matt Goodall <matt@pollenation.net>, 3 years ago)

Attached patch from Mathieu. (Thanks!)

  • forms/converters.py

    old new  
    66from nevow.compy import Adapter 
    77from forms import iforms, validation 
    88from zope.interface import implements 
     9from forms.i18n import i_ 
    910 
    10  
    1111class NullConverter(Adapter): 
    1212    implements( iforms.IStringConvertible ) 
    1313     
     
    3939        try: 
    4040            value = self.cast(value) 
    4141        except ValueError: 
    42             raise validation.FieldValidationError("Not a valid number"
     42            raise validation.FieldValidationError(i_("Not a valid number")
    4343        return value 
    4444         
    4545         
     
    6767        if not value: 
    6868            return None 
    6969        if value not in ('True', 'False'): 
    70             raise validation.FieldValidationError('%r should be either True or False'
     70            raise validation.FieldValidationError(i_"(%r should be either True or False")
    7171        return value == 'True' 
    7272     
    7373     
     
    9090        try: 
    9191            y, m, d = [int(p) for p in value.split('-')] 
    9292        except ValueError: 
    93             raise validation.FieldValidationError('Invalid date'
     93            raise validation.FieldValidationError(i_("Invalid date")
    9494        try: 
    9595            value = date(y, m, d) 
    9696        except ValueError, e: 
    97             raise validation.FieldValidationError('Invalid date: '+str(e)) 
     97            raise validation.FieldValidationError(i_("Invalid date")+': '+str(e)) 
    9898        return value 
    9999 
    100100 
     
    131131                h, m, s = parts 
    132132            h, m, s, ms = int(h), int(m), int(s), int(ms) 
    133133        except: 
    134             raise validation.FieldValidationError('Invalid time'
     134            raise validation.FieldValidationError(i_("Invalid time")
    135135         
    136136        try: 
    137137            value = time(h, m, s, ms) 
    138138        except ValueError, e: 
    139             raise validation.FieldValidationError('Invalid time: '+str(e)) 
     139            raise validation.FieldValidationError(i_("Invalid time")+': '+str(e)) 
    140140             
    141141        return value 
    142142         
     
    155155        try: 
    156156            value = date(*value) 
    157157        except (TypeError, ValueError), e: 
    158             raise validation.FieldValidationError('Invalid date: '+str(e)) 
     158            raise validation.FieldValidationError(i_("Invalid date")+': '+str(e)) 
    159159        return value 
    160160         
  • forms/validation.py

    old new  
    11import re 
    22from zope.interface import implements 
    33from forms import iforms 
     4#for internationalisation 
     5from forms.i18n import i_ 
    46 
    5  
    67class FormsError(Exception): 
    78    """ 
    89    Base class for all Forms errors. A single string, message, is accepted and 
     
    5455     
    5556    def validate(self, field, value): 
    5657        if value is None: 
    57             raise FieldRequiredError, 'Required' 
     58            raise FieldRequiredError, i_("Required") 
    5859 
    5960     
    6061class LengthValidator(object): 
     
    6970         
    7071    def validationErrorMessage(self, field): 
    7172        if self.min is not None and self.max is None: 
    72             return 'Must be longer than %r characters'%(self.min,) 
     73            return i_("Must be longer than %r characters")%self.min 
    7374        if self.min is None and self.max is not None: 
    74             return 'Must be shorter than %r characters'%(self.max,) 
    75         return 'Must be between %r and %r characters'%(self.min, self.max) 
     75            return i_("Must be shorter than %r characters")%self.max 
     76        return i_("Must be between %r and %r characters")%(self.min, self.max) 
    7677     
    7778    def validate(self, field, value): 
    7879        if value is None: 
     
    9697         
    9798    def validationErrorMessage(self, field): 
    9899        if self.min is not None and self.max is None: 
    99             return 'Must be greater than %r'%(self.min,) 
     100            return i_("Must be greater than %r")%(self.min,) 
    100101        if self.min is None and self.max is not None: 
    101             return 'Must be less than %r'%(self.max,) 
    102         return 'Must be between %r and %r'%(self.min, self.max) 
     102            return i_("Must be less than %r")%(self.max,) 
     103        return i_("Must be between %r and %r")%(self.min, self.max) 
    103104     
    104105    def validate(self, field, value): 
    105106        if value is None: 
     
    128129        if not hasattr(self.regex, 'match'): 
    129130            self.regex = re.compile(self.regex) 
    130131        if self.regex.match(value) is None: 
    131             raise FieldValidationError, 'Invalid format' 
     132            raise FieldValidationError, i_("Invalid format") 
    132133             
    133134     
    134135__all__ = [ 
  • forms/iforms.py

    old new  
    11from nevow.compy import Interface 
    22 
    3  
    43class IType(Interface): 
    54    def validate(self, value): 
    65        pass 
  • forms/form.py

    old new  
    99from forms import iforms, util, validation 
    1010from resourcemanager import ResourceManager 
    1111from zope.interface import implements 
     12#for internationalisation 
     13from forms.i18n import i_ 
    1214 
    13  
    1415SEPARATOR = '!!' 
    1516FORMS_KEY = '__nevow_form__' 
    1617WIDGET_RESOURCE_KEY = 'widget_resource' 
     
    8081 
    8182    def addField(self, name, type, widgetFactory=None, label=None, description=None, cssClass=None): 
    8283        if not util.validIdentifier(name): 
    83             raise ValueError('%r is an invalid field name'%name) 
     84            raise ValueError(i_(" %r is an invalid field name")%name) 
    8485        if self.items is None: 
    8586            self.items = [] 
    8687        type.name = name 
     
    9697        if self.actions is None: 
    9798            self.actions = [] 
    9899        if name in [action.name for action in self.actions]: 
    99             raise ValueError('Action with name %r already exists.' % name) 
     100            raise ValueError(i_("Action with name %r already exists.")%name) 
    100101        self.actions.append( Action(callback, name, validate, label) ) 
    101102 
    102103    def getField(self,fieldName): 
     
    156157                    break 
    157158 
    158159        if callback is None: 
    159             raise Exception('The form has no callback and no action was found.'
     160            raise Exception(i_("The form has no callback and no action was found.")
    160161 
    161162        # Store an errors object in the context 
    162163        errors = FormErrors(self.name) 
     
    381382 
    382383    def cacheForm( form, name ): 
    383384        if form is None: 
    384             raise Exception('Form %r not found'%name) 
     385            raise Exception(i_("Form %r not found")%name) 
    385386        form.name = name 
    386387        # Make it a known 
    387388        knownForms[name] = form 
     
    459460            if isinstance(error, validation.FieldError): 
    460461                name, type, label, description, cssClass = self.original.getField(error.fieldName) 
    461462                errorList[ T.li[ T.strong[ label, ' : ' ], error.message ] ] 
    462         return T.div(class_='errors')[ T.p['Please correct the following errors:'], errorList ] 
     463        return T.div(class_='errors')[ T.p[i_("Please correct the following errors:")], errorList ] 
    463464 
    464465    def _renderItems(self, ctx, data): 
    465466        if self.original.items is None: 
  • forms/types.py

    old new  
    55from forms import iforms, validation 
    66from zope.interface import implements 
    77 
    8  
    98class Type(object): 
    109 
    1110    implements( iforms.IType ) 
  • forms/util.py

    old new  
    33from nevow import inevow 
    44from forms import iforms 
    55 
    6  
    76_IDENTIFIER_REGEX = re.compile('^[a-zA-Z_][a-zA-Z0-9_]*$') 
    87 
    98 
  • forms/i18n.py

    old new  
     1# -*- coding: iso-8859-1 -*- 
     2""" 
     3i18n for forms 
     4""" 
     5 
     6import gettext 
     7import os 
     8import pkg_resources 
     9 
     10#the directory where is located forms' message dir (in absolute path) 
     11I18N_DIR = os.path.abspath(pkg_resources.resource_filename('forms', 'messages')) 
     12APP_NAME = 'forms' 
     13 
     14gettext.bindtextdomain (APP_NAME, I18N_DIR) 
     15gettext.textdomain(APP_NAME) 
     16def i_(msg): 
     17    return gettext.dgettext(APP_NAME,msg) 
     18 
     19 
  • forms/messages/fr/fr.po

    old new  
     1# French translations for forms package 
     2# Traduction anglaise du package forms. 
     3# Copyright (C) 2003 THE PACKAGE'S COPYRIGHT HOLDER 
     4# This file is distributed under the same license as the forms package. 
     5msgid "" 
     6msgstr "" 
     7"Project-Id-Version: forms 0.6.1\n" 
     8"POT-Creation-Date: 2006-01-25 15:41+0200\n" 
     9"PO-Revision-Date: 2006-01-25 17:04+0200\n" 
     10"Last-Translator: mathieu gaspard <mathieu.gaspard@ac-dijon.fr>\n" 
     11"Language-Team: French <traduc@traduc.org>\n" 
     12"MIME-Version: 1.0\n" 
     13"Content-Type: text/plain; charset=ISO-8859-15\n" 
     14"Content-Transfer-Encoding: 8bit\n" 
     15"Plural-Forms: nplurals=2; plural=(n > 1);\n" 
     16 
     17################################" 
     18#  form.py 
     19################################ 
     20#, python-format 
     21msgid "%r is an invalid field name" 
     22msgstr "%r est un nom de champ non valide" 
     23 
     24#, python-format 
     25msgid "Action with name %r already exists." 
     26msgstr "L'action %r existe déjà" 
     27 
     28 
     29msgid "The form has no callback and no action was found." 
     30msgstr "Le formulaire n'a aucun callback et aucune action n'a été trouvée" 
     31 
     32#, python-format 
     33msgid "Form %r not found" 
     34msgstr "Formulaire %r non trouvé" 
     35 
     36msgid "Please correct the following errors:" 
     37msgstr "Veuillez corriger les erreurs suivantes:" 
     38 
     39################################" 
     40#  validation.py 
     41################################ 
     42 
     43msgid "Required" 
     44msgstr "Requis" 
     45 
     46#, python-format 
     47msgid "Must be longer than %r characters" 
     48msgstr "Doit avoir plus de %r caractères" 
     49 
     50#, python-format 
     51msgid "Must be shorter than %r characters" 
     52msgstr "Doit avoir moins de %r caractères" 
     53 
     54#, python-format 
     55msgid "Must be between %r and %r characters" 
     56msgstr "Doit avoir entre %r et %r caractères" 
     57 
     58#, python-format 
     59msgid "Must be greater than %r" 
     60msgstr "Doit être plus grand que %r" 
     61 
     62#, python-format 
     63msgid "Must be less than %r" 
     64msgstr "Doit être plus petit que %r" 
     65 
     66#, python-format 
     67msgid "Must be between %r and %r" 
     68msgstr "Doit  être compris entre %r et %r" 
     69 
     70msgid "Invalid format" 
     71msgstr "Format non valide" 
     72 
     73################################" 
     74#  widgets.py 
     75################################ 
     76 
     77msgid "Please enter the password twice for confirmation." 
     78msgstr "Veuillez re-saisir le mot de passe pour confirmation" 
     79 
     80msgid "Passwords do not match." 
     81msgstr "Les mots de passe sont différents" 
     82 
     83msgid "Invalid date" 
     84msgstr "Date non valide" 
     85 
     86msgid "Please enter a 2 or 4 digit year" 
     87msgstr "Veuillez entrer une date à 2 ou 4 chiffres" 
     88 
     89msgid "Please enter a 4 digit year" 
     90msgstr "Veuillez entrer une date à 4 chiffres" 
     91 
     92msgid "Invalid year. Please enter a two-digit year." 
     93msgstr "Année non valide. Veuillez entrer une date à 2 chiffres" 
     94 
     95msgid "nothing uploaded" 
     96msgstr "rien envoyé" 
     97 
     98msgid "Nothing uploaded" 
     99msgstr "Rien envoyé" 
     100 
     101################################" 
     102#  converters.py 
     103################################ 
     104 
     105msgid "Not a valid number" 
     106msgstr "Nombre non valide" 
     107 
     108msgid "%r should be either True or False" 
     109msgstr "%r doit être Vrai ou Faux" 
     110 
     111msgid "Invalid time"  
     112msgstr "Heure non valide" 
  • forms/messages/fr/message_format.sh

    old new  
  • forms/resourcemanager.py

    old new  
    55from shutil import copyfileobj 
    66from exceptions import IOError, OSError 
    77 
    8  
    98class ResourceManagerException( Exception ): 
    109    def __init__( self, *args, **kwds ): 
    1110        super( ResourceManagerException, self ).__init__( *args, **kwds ) 
  • forms/widget.py

    old new  
    1111from forms.form import widgetResourceURL, widgetResourceURLFromContext 
    1212from zope.interface import implements 
    1313from twisted.internet import defer 
     14from forms.i18n import i_ 
    1415 
    15  
    1616# Marker object for args that are not supplied 
    1717_UNSET = object() 
    1818 
    19  
    2019class TextInput(object): 
    2120    """ 
    2221    A text input field. 
     
    180179        if len(pwds) == 0: 
    181180            pwd = '' 
    182181        elif len(pwds) == 1: 
    183             raise validation.FieldValidationError('Please enter the password twice for confirmation.'
     182            raise validation.FieldValidationError(i_("Please enter the password twice for confirmation.")
    184183        else: 
    185184            if pwds[0] != pwds[1]: 
    186                 raise validation.FieldValidationError('Passwords do not match.'
     185                raise validation.FieldValidationError(i_("Passwords do not match.")
    187186        return self.original.validate(pwds[0]) 
    188187 
    189188 
     
    504503        if not ymd: 
    505504            ymd = None 
    506505        elif len(ymd) != 3: 
    507             raise validation.FieldValidationError("Invalid date"
     506            raise validation.FieldValidationError(i_("Invalid date")
    508507        # So, we have what looks like a good attempt to enter a date. 
    509508        if ymd is not None: 
    510509            # If a 2-char year is allowed then prepend the century. 
     
    520519            # By now, we should have a year of at least 4 characters. 
    521520            if len(ymd[0]) < 4: 
    522521                if self.twoCharCutoffYear is not None: 
    523                     msg = "Please enter a 2 or 4 digit year" 
     522                    msg = i_("Please enter a 2 or 4 digit year") 
    524523                else: 
    525                     msg = "Please enter a 4 digit year" 
     524                    msg = i_("Please enter a 4 digit year") 
    526525                raise validation.FieldValidationError(msg) 
    527526            # Map to integers 
    528527            try: 
    529528                ymd = [int(p) for p in ymd] 
    530529            except ValueError, e: 
    531                 raise validation.FieldValidationError("Invalid date"
     530                raise validation.FieldValidationError(i_("Invalid date")
    532531        ymd = iforms.IDateTupleConvertible(self.original).toType(ymd) 
    533532        return self.original.validate(ymd) 
    534533 
     
    592591        if not value: 
    593592            value = None 
    594593        elif len(value) != 2: 
    595             raise validation.FieldValidationError("Invalid date"
     594            raise validation.FieldValidationError(i_("Invalid date")
    596595        if value is not None: 
    597596            try: 
    598597                value = [int(p) for p in value] 
    599598            except ValueError, e: 
    600                 raise validation.FieldValidationError("Invalid date"
     599                raise validation.FieldValidationError(i_("Invalid date")
    601600            if value[1] < 0 or value[1] > 99: 
    602                 raise validation.FieldValidationError("Invalid year. Please enter a two-digit year."
     601                raise validation.FieldValidationError(i_("Invalid year. Please enter a two-digit year.")
    603602            if value[0] > self.cutoffYear: 
    604603                value[0] = 1900 + value[0] 
    605604            else: 
     
    725724            else: 
    726725                yield T.p[value] 
    727726        else: 
    728             yield T.p[T.strong['nothing uploaded']] 
     727            yield T.p[T.strong[i_("nothing uploaded")]] 
    729728 
    730729        yield T.input(name=namer('value'),value=value,type='hidden') 
    731730        tag=T.input(name=key, id=keytocssid(ctx.key),type='file') 
     
    856855            yield T.p[T.img(src=tmpURL)] 
    857856        else: 
    858857            # No uploaded file, no original 
    859             yield T.p[T.strong['Nothing uploaded']] 
     858            yield T.p[T.strong[i_("Nothing uploaded")]] 
    860859 
    861860        yield T.input(name=key, id=keytocssid(ctx.key),type='file') 
    862861 
     
    889888            yield T.p[T.img(src=tmpURL)] 
    890889        else: 
    891890            # No uploaded file, no original 
    892             yield T.p[T.strong['Nothing uploaded']] 
     891            yield T.p[T.strong[i_("Nothing uploaded")]] 
    893892 
    894893        if originalKey: 
    895894            # key of the original that can be used to get a file later 
  • setup.py

    old new  
    1010    author_email='matt@pollenation.net', 
    1111    packages=find_packages(), 
    1212    package_data={ 
    13         'forms': ['forms.css', 'html/*', 'js/*'], 
     13        'forms': ['forms.css', 'html/*', 'js/*', 'messages/fr/*.po','messages/fr/*.sh','messages/fr/LC_MESSAGES/*'], 
     14        #'forms': ['forms.css', 'html/*', 'js/*'], 
    1415        }, 
    1516    zip_safe = True, 
    1617    )