From: <sub...@co...> - 2006-10-02 19:04:52
|
Author: gh Date: 2006-10-02 13:04:46 -0600 (Mon, 02 Oct 2006) New Revision: 1968 Added: FormEncode/branches/gettext-enabled/docs/i18n.txt FormEncode/branches/gettext-enabled/formencode/i18n/ FormEncode/branches/gettext-enabled/formencode/i18n/FormEncode.pot FormEncode/branches/gettext-enabled/formencode/i18n/de/ FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/ FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.mo FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.po FormEncode/branches/gettext-enabled/tests/test_i18n.py Modified: FormEncode/branches/gettext-enabled/formencode/api.py FormEncode/branches/gettext-enabled/formencode/validators.py FormEncode/branches/gettext-enabled/tests/test_cc_expires.py FormEncode/branches/gettext-enabled/tests/test_cc_validator.py FormEncode/branches/gettext-enabled/tests/test_schema.py FormEncode/branches/gettext-enabled/tests/test_sqlschema.py Log: added basic i18n code and german translation Added: FormEncode/branches/gettext-enabled/docs/i18n.txt =================================================================== --- FormEncode/branches/gettext-enabled/docs/i18n.txt (rev 0) +++ FormEncode/branches/gettext-enabled/docs/i18n.txt 2006-10-02 19:04:46 UTC (rev 1968) @@ -0,0 +1,32 @@ +FormEncode Internationalization (gettext) ++++++++++++++++++++++++++++++++++++++++++ + +There are different translation options available: + +Domain "FormEncode" +^^^^^^^^^^^^^^^^^^^ + +for standalone use of FormEncode, just place the compiled files in /usr/share/locale/<lang>/LC_MESSAGES/FormEncode.mo The language to use is determined out of the local system (see gettext documentation http://docs.python.org/lib/node733.html). Optionally you can also set the language or the domain explicitly with the function + +example: +formencode.api.set_stdtranslation(domain="FormEncode", languages=["de"]) + +state._ +^^^^^^^ +A custom _ gettext function provided as attribute of the state object. + +__builtins__._ +^^^^^^^^^^^^^^ +A custom _ gettext function provided in the builtin namespace. +This function is only used when: + +Validator.use_builtin_gettext == True (True is default) + + +Without translation +^^^^^^^^^^^^^^^^^^^ + +If no translation mechanism is found a fallback returns the plain string. + + +Gregor Horvath, 2006 gh...@gr... Modified: FormEncode/branches/gettext-enabled/formencode/api.py =================================================================== --- FormEncode/branches/gettext-enabled/formencode/api.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/formencode/api.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -5,10 +5,32 @@ import declarative import textwrap import re +import os +import formencode __all__ = ['NoDefault', 'Invalid', 'Validator', 'Identity', 'FancyValidator', 'is_validator'] +import gettext + +def set_stdtranslation(domain="FormEncode", languages=None, \ + localedir = "%s%s%s" % \ + (os.path.dirname(formencode.__file__), os.path.sep, "i18n")): + print localedir + t = gettext.translation(domain=domain, \ + languages=languages, \ + localedir=localedir, fallback=True) + global _stdtrans + _stdtrans = t.ugettext + +set_stdtranslation() + +#def _(s): return s # dummy i18n translation function, nothing is translated here. + # Instead this is actually done in api.Validator.message. + # The surrounding _("string") of the strings is only for extracting + # the strings automatically + # if you run pygettext with this source comment this function out temporarly + class NoDefault: pass @@ -117,7 +139,10 @@ if_missing = NoDefault repeating = False compound = False - + gettextargs = {} + use_builtins_gettext = True #In case you dont want to use __builtins__._ + #altough it may be definied, set this to False + __singletonmethods__ = ('to_python', 'from_python') def __classinit__(cls, new_attrs): @@ -141,8 +166,21 @@ return value def message(self, msgName, state, **kw): + #determine translation function try: - return self._messages[msgName] % kw + trans = state._ + except AttributeError: + try: + if self.use_builtins_gettext: + import __builtin__ + trans = __builtin__._ + else: + trans = _stdtrans + except AttributeError: + trans = _stdtrans + + try: + return trans(self._messages[msgName], **self.gettextargs) % kw except KeyError, e: raise KeyError( "Key not found (%s) for %r=%r %% %r (from: %s)" @@ -294,9 +332,9 @@ strip = False messages = { - 'empty': "Please enter a value", - 'badType': "The input must be a string (not a %(type)s: %(value)r)", - 'noneType': "The input must be a string (not None)", + 'empty': _("Please enter a value"), + 'badType': _("The input must be a string (not a %(type)s: %(value)r)"), + 'noneType': _("The input must be a string (not None)"), } def to_python(self, value, state=None): Added: FormEncode/branches/gettext-enabled/formencode/i18n/FormEncode.pot =================================================================== --- FormEncode/branches/gettext-enabled/formencode/i18n/FormEncode.pot (rev 0) +++ FormEncode/branches/gettext-enabled/formencode/i18n/FormEncode.pot 2006-10-02 19:04:46 UTC (rev 1968) @@ -0,0 +1,325 @@ +# SOME DESCRIPTIVE TITLE. +# Copyright (C) YEAR ORGANIZATION +# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. +# +msgid "" +msgstr "" +"Project-Id-Version: PACKAGE VERSION\n" +"POT-Creation-Date: 2006-10-02 20:59+CEST\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" +"Language-Team: LANGUAGE <LL...@li...>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=CHARSET\n" +"Content-Transfer-Encoding: ENCODING\n" +"Generated-By: pygettext.py 1.5\n" + + +#: api.py:335 validators.py:433 +msgid "Please enter a value" +msgstr "" + +#: api.py:336 +msgid "The input must be a string (not a %(type)s: %(value)r)" +msgstr "" + +#: api.py:337 +msgid "The input must be a string (not None)" +msgstr "" + +#: validators.py:160 +msgid "%(object)r is not a subclass of %(subclass)s" +msgstr "" + +#: validators.py:161 +msgid "%(object)r is not a subclass of one of the types %(subclassList)s" +msgstr "" + +#: validators.py:162 +msgid "%(object)r must be one of the types %(typeList)s" +msgstr "" + +#: validators.py:163 +msgid "%(object)r must be of the type %(type)s" +msgstr "" + +#: validators.py:344 +msgid "Enter a value less than %(maxLength)i characters long" +msgstr "" + +#: validators.py:345 validators.py:399 +msgid "Invalid value (value with length expected)" +msgstr "" + +#: validators.py:398 +msgid "Enter a value at least %(minLength)i characters long" +msgstr "" + +#: validators.py:458 +msgid "You cannot enter a value here" +msgstr "" + +#: validators.py:509 +msgid "The input is not valid" +msgstr "" + +#: validators.py:565 +msgid "Enter only letters, numbers, or _ (underscore)" +msgstr "" + +#: validators.py:604 +msgid "Invalid value" +msgstr "" + +#: validators.py:605 +msgid "Value must be one of: %(items)s (not %(value)r)" +msgstr "" + +#: validators.py:668 +msgid "Choose something" +msgstr "" + +#: validators.py:669 +msgid "Enter a value from: %(items)s" +msgstr "" + +#: validators.py:670 +msgid "That value is not known" +msgstr "" + +#: validators.py:671 +msgid "Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s" +msgstr "" + +#: validators.py:732 +msgid "Must be an integer index" +msgstr "" + +#: validators.py:733 +msgid "Index out of range" +msgstr "" + +#: validators.py:734 +msgid "Item %(value)s was not found in the list" +msgstr "" + +#: validators.py:809 +msgid "Date must be after %(date)s" +msgstr "" + +#: validators.py:810 +msgid "Date must be before %(date)s" +msgstr "" + +#: validators.py:812 +msgid "%%A, %%d %%B %%Y" +msgstr "" + +#: validators.py:813 +msgid "The date must be sometime in the future" +msgstr "" + +#: validators.py:913 +msgid "Please enter an integer value" +msgstr "" + +#: validators.py:945 +msgid "Please enter a number" +msgstr "" + +#: validators.py:998 +msgid "Enter a value less than %(max)i characters long" +msgstr "" + +#: validators.py:999 +msgid "Enter a value %(min)i characters long or more" +msgstr "" + +#: validators.py:1050 +msgid "Invalid data or incorrect encoding" +msgstr "" + +#: validators.py:1178 +msgid "Please enter an email address" +msgstr "" + +#: validators.py:1179 +msgid "An email address must contain a single @" +msgstr "" + +#: validators.py:1180 +msgid "The username portion of the email address is invalid (the portion before the @: %(username)s)" +msgstr "" + +#: validators.py:1181 validators.py:1294 +msgid "An error occured when trying to connect to the server: %(error)s" +msgstr "" + +#: validators.py:1182 +msgid "The domain portion of the email address is invalid (the portion after the @: %(domain)s)" +msgstr "" + +#: validators.py:1183 +msgid "The domain of the email address does not exist (the portion after the @: %(domain)s)" +msgstr "" + +#: validators.py:1291 +msgid "You must start your URL with http://, https://, etc" +msgstr "" + +#: validators.py:1292 +msgid "That is not a valid URL" +msgstr "" + +#: validators.py:1293 +msgid "An error occurred when trying to access the URL: %(error)s" +msgstr "" + +#: validators.py:1295 +msgid "The server responded that the page could not be found" +msgstr "" + +#: validators.py:1296 +msgid "The server responded with a bad status code (%(status)s)" +msgstr "" + +#: validators.py:1399 +msgid "Please enter a state code" +msgstr "" + +#: validators.py:1400 +msgid "Please enter a state code with TWO letters" +msgstr "" + +#: validators.py:1401 +msgid "That is not a valid state code" +msgstr "" + +#: validators.py:1452 +msgid "Please enter a number, with area code, in the form ###-###-####, optionally with \"ext.####\"" +msgstr "" + +#: validators.py:1614 validators.py:1622 +msgid "Please enter the date in the form %(format)s" +msgstr "" + +#: validators.py:1615 +msgid "Please enter a month from 1 to 12" +msgstr "" + +#: validators.py:1616 +msgid "Please enter a valid day" +msgstr "" + +#: validators.py:1617 +msgid "That month only has %(days)i days" +msgstr "" + +#: validators.py:1618 +msgid "That is not a valid day (%(exception)s)" +msgstr "" + +#: validators.py:1619 +msgid "Unknown month name: %(month)s" +msgstr "" + +#: validators.py:1620 +msgid "Please enter a number for the year" +msgstr "" + +#: validators.py:1621 +msgid "Please enter a four-digit year" +msgstr "" + +#: validators.py:1800 +msgid "You must indicate AM or PM" +msgstr "" + +#: validators.py:1801 +msgid "There are too many :'s" +msgstr "" + +#: validators.py:1802 +msgid "You may not enter seconds" +msgstr "" + +#: validators.py:1803 +msgid "You must enter seconds" +msgstr "" + +#: validators.py:1804 +msgid "You must enter minutes (after a :)" +msgstr "" + +#: validators.py:1805 +msgid "The %(part)s value you gave is not a number: %(number)r" +msgstr "" + +#: validators.py:1806 +msgid "You must enter an hour in the range %(range)s" +msgstr "" + +#: validators.py:1807 +msgid "You must enter a minute in the range 0-59" +msgstr "" + +#: validators.py:1808 +msgid "You must enter a second in the range 0-59" +msgstr "" + +#: validators.py:1962 +msgid "Please enter a zip code (5 digits)" +msgstr "" + +#: validators.py:1986 +msgid "The name %(name)s is missing" +msgstr "" + +#: validators.py:2027 +msgid "Value should be %(true)r or %(false)r" +msgstr "" + +#: validators.py:2062 +msgid "Value does not contain a signature" +msgstr "" + +#: validators.py:2063 +msgid "Signature is not correct" +msgstr "" + +#: validators.py:2185 +msgid "Fields do not match (should be %(match)s)" +msgstr "" + +#: validators.py:2186 +msgid "Fields do not match" +msgstr "" + +#: validators.py:2248 +msgid "Please enter only the number, no other characters" +msgstr "" + +#: validators.py:2249 +msgid "You did not enter a valid number of digits" +msgstr "" + +#: validators.py:2250 +msgid "That number is not valid" +msgstr "" + +#: validators.py:2365 +msgid "Please enter numbers only for month and year" +msgstr "" + +#: validators.py:2366 +msgid "Invalid Expiration Date" +msgstr "" + +#: validators.py:2435 +msgid "Please enter numbers only for credit card security code" +msgstr "" + +#: validators.py:2436 +msgid "Invalid credit card security code length" +msgstr "" + Added: FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.mo =================================================================== (Binary files differ) Property changes on: FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.mo ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Added: FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.po =================================================================== --- FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.po (rev 0) +++ FormEncode/branches/gettext-enabled/formencode/i18n/de/LC_MESSAGES/FormEncode.po 2006-10-02 19:04:46 UTC (rev 1968) @@ -0,0 +1,325 @@ +# German strings for FormEncode +# Copyright (C) 2006 Gregor Horvath, licence: LGPL V2.0 +# Gregor Horvath <gh...@gr...>, 2006. +# +msgid "" +msgstr "" +"Project-Id-Version: FormEncode 0.5.1\n" +"POT-Creation-Date: 2006-09-26 07:57+CEST\n" +"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" +"Last-Translator: Gregor Horvath <gh...@gr...>\n" +"Language-Team: Gregor Horvath <gh...@gr...>\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=ISO8859-1\n" +"Content-Transfer-Encoding: ISO8859-1\n" +"Generated-By: pygettext.py 1.5\n" + + +#: api.py:319 validators.py:433 +msgid "Please enter a value" +msgstr "Bitte einen Wert eingeben" + +#: api.py:320 +msgid "The input must be a string (not a %(type)s: %(value)r)" +msgstr "Die Eingabe mueine Zeichenfolge sein (nicht ein %(type)s: %(value)r)" + +#: api.py:321 +msgid "The input must be a string (not None)" +msgstr "Die Eingabe mueine Zeichenfolge sein (nicht Nichts)" + +#: validators.py:160 +msgid "%(object)r is not a subclass of %(subclass)s" +msgstr "%(object)r ist keine Unterklasse von %(subclass)s" + +#: validators.py:161 +msgid "%(object)r is not a subclass of one of the types %(subclassList)s" +msgstr "%(object)r ist keine Unterklasse von einer der Klassen %(subclassList)s" + +#: validators.py:162 +msgid "%(object)r must be one of the types %(typeList)s" +msgstr "%(object)r Typ muvon eine von diesen sein: %(typeList)s" + +#: validators.py:163 +msgid "%(object)r must be of the type %(type)s" +msgstr "%(object)r muvom Typ %(type)s sein" + +#: validators.py:344 +msgid "Enter a value less than %(maxLength)i characters long" +msgstr "Geben Sie einen Wert kals %(maxLength)i Zeichen ein." + +#: validators.py:345 validators.py:399 +msgid "Invalid value (value with length expected)" +msgstr "Ungr Wert (Wert mit Le erwartet)" + +#: validators.py:398 +msgid "Enter a value at least %(minLength)i characters long" +msgstr "Geben Sie einen Wert mit mindestens %(minLength)i Zeichen ein." + +#: validators.py:458 +msgid "You cannot enter a value here" +msgstr "Sie kn hier keinen Wert eingeben" + +#: validators.py:509 +msgid "The input is not valid" +msgstr "Die Eingabe ist ung + +#: validators.py:565 +msgid "Enter only letters, numbers, or _ (underscore)" +msgstr "Geben Sie nur Buchstaben, Nummern oder _ (Unterstriche) ein." + +#: validators.py:604 +msgid "Invalid value" +msgstr "Ungr Wert" + +#: validators.py:605 +msgid "Value must be one of: %(items)s (not %(value)r)" +msgstr "Wert mueiner von diesen sein: %(items)s (nicht %(value)r) " + +#: validators.py:668 +msgid "Choose something" +msgstr "Etwas auswen" + +#: validators.py:669 +msgid "Enter a value from: %(items)s" +msgstr "Geben Sie einen Wert aus %(items)s ein." + +#: validators.py:670 +msgid "That value is not known" +msgstr "Dieser Wert ist unbekannt" + +#: validators.py:671 +msgid "Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s" +msgstr "Mein Wrbuch enth nicht den Wert: %(value)s. We einen Wert aus: %(items)s" + +#: validators.py:732 +msgid "Must be an integer index" +msgstr "Muein Ganzahlindex sein." + +#: validators.py:733 +msgid "Index out of range" +msgstr "Index ausserhalb des Bereiches" + +#: validators.py:734 +msgid "Item %(value)s was not found in the list" +msgstr "Wert %(value)s wurde in der Liste nicht gefunden" + +#: validators.py:809 +msgid "Date must be after %(date)s" +msgstr "Datum munach %(date)s sein" + +#: validators.py:810 +msgid "Date must be before %(date)s" +msgstr "Datum muvor %(date)s sein" + +#: validators.py:812 +msgid "%%A, %%d %%B %%Y" +msgstr "%%A, %%d %%B %%Y" + +#: validators.py:813 +msgid "The date must be sometime in the future" +msgstr "Das Datum muin der Zukunft liegen" + +#: validators.py:913 +msgid "Please enter an integer value" +msgstr "Bitte einen Ganzzahlwert eingeben" + +#: validators.py:945 +msgid "Please enter a number" +msgstr "Bitte eine Zahl eingeben" + +#: validators.py:998 +msgid "Enter a value less than %(max)i characters long" +msgstr "Bitte einen Wert kals %(max)i Zeichen eingeben." + +#: validators.py:999 +msgid "Enter a value %(min)i characters long or more" +msgstr "Bitte einen Wert mit %(min)i oder mehr Zeichen eingeben" + +#: validators.py:1050 +msgid "Invalid data or incorrect encoding" +msgstr "Ung Daten oder falsche Kodierung" + +#: validators.py:1178 +msgid "Please enter an email address" +msgstr "Bitte eine E-mail Adresse eingeben" + +#: validators.py:1179 +msgid "An email address must contain a single @" +msgstr "Eine E-mail Adresse muein einzelnes @ Zeichen enthalten" + +#: validators.py:1180 +msgid "The username portion of the email address is invalid (the portion before the @: %(username)s)" +msgstr "Der Benutzer Teil der E-mail Adresse is ung(Der Teil vor dem @: %(username)s)" + +#: validators.py:1181 validators.py:1294 +msgid "An error occured when trying to connect to the server: %(error)s" +msgstr "Ein Fehler ist beim Verbindungsversuch mit dem Server aufgetreten: %(error)s" + +#: validators.py:1182 +msgid "The domain portion of the email address is invalid (the portion after the @: %(domain)s)" +msgstr "Der Domain Teil der E-mail Adresse ist ung(Der Teil nach dem @: %(domain)s)" + +#: validators.py:1183 +msgid "The domain of the email address does not exist (the portion after the @: %(domain)s)" +msgstr "Die Domaine der E-mail Adresse existiert nicht (Der Teil nach dem @: %(domain)s)" + +#: validators.py:1291 +msgid "You must start your URL with http://, https://, etc" +msgstr "Die URL mumit http://, https://, etc beginnen" + +#: validators.py:1292 +msgid "That is not a valid URL" +msgstr "Das ist eine ung URL" + +#: validators.py:1293 +msgid "An error occurred when trying to access the URL: %(error)s" +msgstr "Beim Versuch die URL zu erreichen ist ein Fehler aufgetreten: %(error)s" + +#: validators.py:1295 +msgid "The server responded that the page could not be found" +msgstr "Der Server hat geantwortet, dass die Seite nicht gefunden werden konnte" + +#: validators.py:1296 +msgid "The server responded with a bad status code (%(status)s)" +msgstr "Der Server antwortete mit einem schlechten Statuskode (%(status)s)" + +#: validators.py:1399 +msgid "Please enter a state code" +msgstr "Bitte eine Landeskeingeben" + +#: validators.py:1400 +msgid "Please enter a state code with TWO letters" +msgstr "Bitte ein Landeskmit 2 Buchstaben eingeben" + +#: validators.py:1401 +msgid "That is not a valid state code" +msgstr "Das ist kein gs Landesk + +#: validators.py:1452 +msgid "Please enter a number, with area code, in the form ###-###-####, optionally with \"ext.####\"" +msgstr "Bitte geben Sie eine Nummer mit Gebietskode in der Form ###-###-####, alternativ mit \"ext.####\ ein" + +#: validators.py:1614 validators.py:1622 +msgid "Please enter the date in the form %(format)s" +msgstr "Bitte geben Sie das Datum in der Form %(format)s ein." + +#: validators.py:1615 +msgid "Please enter a month from 1 to 12" +msgstr "Bitte ein Monat von 1 bis 12 eingeben." + +#: validators.py:1616 +msgid "Please enter a valid day" +msgstr "Bitte einen gn Tag eingeben" + +#: validators.py:1617 +msgid "That month only has %(days)i days" +msgstr "Dieser Monat hat nur %(days)i Tage" + +#: validators.py:1618 +msgid "That is not a valid day (%(exception)s)" +msgstr "Das ist kein gr Tag (%(exception)s)" + +#: validators.py:1619 +msgid "Unknown month name: %(month)s" +msgstr "Unbekannter Monatsname: %(month)s" + +#: validators.py:1620 +msgid "Please enter a number for the year" +msgstr "Bitte eine Zahl f Jahr eingeben" + +#: validators.py:1621 +msgid "Please enter a four-digit year" +msgstr "Bitte eine vierstellige Jahreszahl eingeben." + +#: validators.py:1800 +msgid "You must indicate AM or PM" +msgstr "Sie mAM oder PM angeben" + +#: validators.py:1801 +msgid "There are too many :'s" +msgstr "Hier sind zu viele :'s" + +#: validators.py:1802 +msgid "You may not enter seconds" +msgstr "Keine Sekunden eingeben" + +#: validators.py:1803 +msgid "You must enter seconds" +msgstr "Sie mSekunden eingeben" + +#: validators.py:1804 +msgid "You must enter minutes (after a :)" +msgstr "Sie mMinuten eingeben (nach a :)" + +#: validators.py:1805 +msgid "The %(part)s value you gave is not a number: %(number)r" +msgstr "Der %(part)s Wert den Sie angaben ist keine Nummer: %(number)r" + +#: validators.py:1806 +msgid "You must enter an hour in the range %(range)s" +msgstr "Sie meine Stunde im Bereich %(range)s eingeben." + +#: validators.py:1807 +msgid "You must enter a minute in the range 0-59" +msgstr "Sie meine Minute im Bereich 0-59 eingeben." + +#: validators.py:1808 +msgid "You must enter a second in the range 0-59" +msgstr "Sie meine Sekunde im Bereicg 0-59 eingeben." + +#: validators.py:1962 +msgid "Please enter a zip code (5 digits)" +msgstr "Bitte eine Postleitzahl eingeben (5 Stellen)" + +#: validators.py:1986 +msgid "The name %(name)s is missing" +msgstr "Der Name %(name)s fehlt" + +#: validators.py:2027 +msgid "Value should be %(true)r or %(false)r" +msgstr "Wert sollte %(true)r oder %(false)r sein" + +#: validators.py:2062 +msgid "Value does not contain a signature" +msgstr "Wert enth keine Signatur" + +#: validators.py:2063 +msgid "Signature is not correct" +msgstr "Signatur ist nicht korrekt" + +#: validators.py:2185 +msgid "Fields do not match (should be %(match)s)" +msgstr "Felder stimmen nicht n (sollten sein %(match)s)" + +#: validators.py:2186 +msgid "Fields do not match" +msgstr "Felder stimmen nicht n" + +#: validators.py:2248 +msgid "Please enter only the number, no other characters" +msgstr "Bitte nur die Nummer, keine anderen Zeichen eingeben." + +#: validators.py:2249 +msgid "You did not enter a valid number of digits" +msgstr "Sie haben keine g Zahl aus Ziffern eingegeben" + +#: validators.py:2250 +msgid "That number is not valid" +msgstr "Diese Nummer ist ung + +#: validators.py:2365 +msgid "Please enter numbers only for month and year" +msgstr "Bitte Nummern nur f Monat und Jahr eingeben" + +#: validators.py:2366 +msgid "Invalid Expiration Date" +msgstr "Ungs Ablaufdatum" + +#: validators.py:2435 +msgid "Please enter numbers only for credit card security code" +msgstr "Bitte Nummern nur f Kreditkarten Sicherheitskode eingeben." + +#: validators.py:2436 +msgid "Invalid credit card security code length" +msgstr "Ung Kreditkartensicherheitscodele" + Modified: FormEncode/branches/gettext-enabled/formencode/validators.py =================================================================== --- FormEncode/branches/gettext-enabled/formencode/validators.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/formencode/validators.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -44,6 +44,12 @@ True, False = (1==1), (0==1) +#def _(s): return s # dummy translation function, nothing is translated here. + # Instead this is actually done in api.message. + # The surrounding _("string") of the strings is only for extracting + # the strings automatically + # if you run pygettext with this source comment this function out temporarly + ############################################################ ## Utility methods ############################################################ @@ -151,10 +157,10 @@ type = None messages = { - 'subclass': "%(object)r is not a subclass of %(subclass)s", - 'inSubclass': "%(object)r is not a subclass of one of the types %(subclassList)s", - 'inType': "%(object)r must be one of the types %(typeList)s", - 'type': "%(object)r must be of the type %(type)s", + 'subclass': _("%(object)r is not a subclass of %(subclass)s"), + 'inSubclass': _("%(object)r is not a subclass of one of the types %(subclassList)s"), + 'inType': _("%(object)r must be one of the types %(typeList)s"), + 'type': _("%(object)r must be of the type %(type)s"), } def __init__(self, *args, **kw): @@ -335,8 +341,8 @@ __unpackargs__ = ('maxLength',) messages = { - 'tooLong': "Enter a value less than %(maxLength)i characters long", - 'invalid': "Invalid value (value with length expected)", + 'tooLong': _("Enter a value less than %(maxLength)i characters long"), + 'invalid': _("Invalid value (value with length expected)"), } def validate_python(self, value, state): @@ -389,8 +395,8 @@ __unpackargs__ = ('minLength',) messages = { - 'tooShort': "Enter a value at least %(minLength)i characters long", - 'invalid': "Invalid value (value with length expected)", + 'tooShort': _("Enter a value at least %(minLength)i characters long"), + 'invalid': _("Invalid value (value with length expected)"), } def validate_python(self, value, state): @@ -424,7 +430,7 @@ not_empty = True messages = { - 'empty': "Please enter a value", + 'empty': _("Please enter a value"), } def validate_python(self, value, state): @@ -449,7 +455,7 @@ """ messages = { - 'notEmpty': "You cannot enter a value here", + 'notEmpty': _("You cannot enter a value here"), } def validate_python(self, value, state): @@ -500,7 +506,7 @@ __unpackargs__ = ('regex',) messages = { - 'invalid': "The input is not valid", + 'invalid': _("The input is not valid"), } def __init__(self, *args, **kw): @@ -556,7 +562,7 @@ regex = r"^[a-zA-Z_\-0-9]*$" messages = { - 'invalid': 'Enter only letters, numbers, or _ (underscore)', + 'invalid': _('Enter only letters, numbers, or _ (underscore)'), } class OneOf(FancyValidator): @@ -595,8 +601,8 @@ __unpackargs__ = ('list',) messages = { - 'invalid': "Invalid value", - 'notIn': "Value must be one of: %(items)s (not %(value)r)", + 'invalid': _("Invalid value"), + 'notIn': _("Value must be one of: %(items)s (not %(value)r)"), } def validate_python(self, value, state): @@ -659,10 +665,10 @@ __unpackargs__ = ('dict',) messages = { - 'keyNotFound': "Choose something", - 'chooseKey': "Enter a value from: %(items)s", - 'valueNotFound': "That value is not known", - 'chooseValue': "Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s", + 'keyNotFound': _("Choose something"), + 'chooseKey': _("Enter a value from: %(items)s"), + 'valueNotFound': _("That value is not known"), + 'chooseValue': _("Nothing in my dictionary goes by the value %(value)s. Choose one of: %(items)s"), } def _to_python(self, value, state): @@ -723,9 +729,9 @@ __unpackargs__ = ('list',) messages = { - 'integer': "Must be an integer index", - 'outOfRange': "Index out of range", - 'notFound': "Item %(value)s was not found in the list", + 'integer': _("Must be an integer index"), + 'outOfRange': _("Index out of range"), + 'notFound': _("Item %(value)s was not found in the list"), } def _to_python(self, value, state): @@ -800,11 +806,11 @@ datetime_module = None messages = { - 'after': "Date must be after %(date)s", - 'before': "Date must be before %(date)s", + 'after': _("Date must be after %(date)s"), + 'before': _("Date must be before %(date)s"), # Double %'s, because this will be substituted twice: - 'date_format': "%%A, %%d %%B %%Y", - 'future': "The date must be sometime in the future", + 'date_format': _("%%A, %%d %%B %%Y"), + 'future': _("The date must be sometime in the future"), } def validate_python(self, value, state): @@ -904,7 +910,7 @@ """ messages = { - 'integer': "Please enter an integer value", + 'integer': _("Please enter an integer value"), } def _to_python(self, value, state): @@ -936,7 +942,7 @@ """ messages = { - 'number': "Please enter a number", + 'number': _("Please enter a number"), } def _to_python(self, value, state): @@ -989,8 +995,8 @@ not_empty = None messages = { - 'tooLong': "Enter a value less than %(max)i characters long", - 'tooShort': "Enter a value %(min)i characters long or more", + 'tooLong': _("Enter a value less than %(max)i characters long"), + 'tooShort': _("Enter a value %(min)i characters long or more"), } def __initargs__(self, new_attrs): @@ -1041,7 +1047,7 @@ """ encoding = 'utf-8' messages = { - 'badEncoding' : "Invalid data or incorrect encoding", + 'badEncoding' : _("Invalid data or incorrect encoding"), } def __init__(self, inputEncoding=None, outputEncoding=None, **kw): @@ -1169,12 +1175,12 @@ domainRE = re.compile(r"^[a-z0-9][a-z0-9\.\-_]*\.[a-z]+$", re.I) messages = { - 'empty': 'Please enter an email address', - 'noAt': 'An email address must contain a single @', - 'badUsername': 'The username portion of the email address is invalid (the portion before the @: %(username)s)', - 'socketError': 'An error occured when trying to connect to the server: %(error)s', - 'badDomain': 'The domain portion of the email address is invalid (the portion after the @: %(domain)s)', - 'domainDoesNotExist': 'The domain of the email address does not exist (the portion after the @: %(domain)s)', + 'empty': _('Please enter an email address'), + 'noAt': _('An email address must contain a single @'), + 'badUsername': _('The username portion of the email address is invalid (the portion before the @: %(username)s)'), + 'socketError': _('An error occured when trying to connect to the server: %(error)s'), + 'badDomain': _('The domain portion of the email address is invalid (the portion after the @: %(domain)s)'), + 'domainDoesNotExist': _('The domain of the email address does not exist (the portion after the @: %(domain)s)'), } def __init__(self, *args, **kw): @@ -1282,12 +1288,12 @@ scheme_re = re.compile(r'^[a-zA-Z]+:') messages = { - 'noScheme': 'You must start your URL with http://, https://, etc', - 'badURL': 'That is not a valid URL', - 'httpError': 'An error occurred when trying to access the URL: %(error)s', - 'socketError': 'An error occured when trying to connect to the server: %(error)s', - 'notFound': 'The server responded that the page could not be found', - 'status': 'The server responded with a bad status code (%(status)s)', + 'noScheme': _('You must start your URL with http://, https://, etc'), + 'badURL': _('That is not a valid URL'), + 'httpError': _('An error occurred when trying to access the URL: %(error)s'), + 'socketError': _('An error occured when trying to connect to the server: %(error)s'), + 'notFound': _('The server responded that the page could not be found'), + 'status': _('The server responded with a bad status code (%(status)s)'), } def _to_python(self, value, state): @@ -1390,9 +1396,9 @@ __unpackargs__ = ('extra_states',) messages = { - 'empty': 'Please enter a state code', - 'wrongLength': 'Please enter a state code with TWO letters', - 'invalid': 'That is not a valid state code', + 'empty': _('Please enter a state code'), + 'wrongLength': _('Please enter a state code with TWO letters'), + 'invalid': _('That is not a valid state code'), } def validate_python(self, value, state): @@ -1443,7 +1449,7 @@ _phoneRE = re.compile(r'^\s*(?:1-)?(\d\d\d)[\- \.]?(\d\d\d)[\- \.]?(\d\d\d\d)(?:\s*ext\.?\s*(\d+))?\s*$', re.I) messages = { - 'phoneFormat': 'Please enter a number, with area code, in the form ###-###-####, optionally with "ext.####"', + 'phoneFormat': _('Please enter a number, with area code, in the form ###-###-####, optionally with "ext.####"'), } def _to_python(self, value, state): @@ -1605,15 +1611,15 @@ 9: 30, 10: 31, 11: 30, 12: 31} messages = { - 'badFormat': 'Please enter the date in the form %(format)s', - 'monthRange': 'Please enter a month from 1 to 12', - 'invalidDay': 'Please enter a valid day', - 'dayRange': 'That month only has %(days)i days', - 'invalidDate': 'That is not a valid day (%(exception)s)', - 'unknownMonthName': "Unknown month name: %(month)s", - 'invalidYear': 'Please enter a number for the year', - 'fourDigitYear': 'Please enter a four-digit year', - 'wrongFormat': 'Please enter the date in the form %(format)s', + 'badFormat': _('Please enter the date in the form %(format)s'), + 'monthRange': _('Please enter a month from 1 to 12'), + 'invalidDay': _('Please enter a valid day'), + 'dayRange': _('That month only has %(days)i days'), + 'invalidDate': _('That is not a valid day (%(exception)s)'), + 'unknownMonthName': _("Unknown month name: %(month)s"), + 'invalidYear': _('Please enter a number for the year'), + 'fourDigitYear': _('Please enter a four-digit year'), + 'wrongFormat': _('Please enter the date in the form %(format)s'), } def _to_python(self, value, state): @@ -1791,15 +1797,15 @@ datetime_module = None messages = { - 'noAMPM': 'You must indicate AM or PM', - 'tooManyColon': 'There are too many :\'s', - 'noSeconds': 'You may not enter seconds', - 'secondsRequired': 'You must enter seconds', - 'minutesRequired': 'You must enter minutes (after a :)', - 'badNumber': 'The %(part)s value you gave is not a number: %(number)r', - 'badHour': 'You must enter an hour in the range %(range)s', - 'badMinute': 'You must enter a minute in the range 0-59', - 'badSecond': 'You must enter a second in the range 0-59', + 'noAMPM': _('You must indicate AM or PM'), + 'tooManyColon': _('There are too many :\'s'), + 'noSeconds': _('You may not enter seconds'), + 'secondsRequired': _('You must enter seconds'), + 'minutesRequired': _('You must enter minutes (after a :)'), + 'badNumber': _('The %(part)s value you gave is not a number: %(number)r'), + 'badHour': _('You must enter an hour in the range %(range)s'), + 'badMinute': _('You must enter a minute in the range 0-59'), + 'badSecond': _('You must enter a second in the range 0-59'), } def _to_python(self, value, state): @@ -1953,7 +1959,7 @@ strip = True messages = { - 'invalid': 'Please enter a zip code (5 digits)', + 'invalid': _('Please enter a zip code (5 digits)'), } class StripField(FancyValidator): @@ -1977,7 +1983,7 @@ __unpackargs__ = ('name',) messages = { - 'missing': 'The name %(name)s is missing', + 'missing': _('The name %(name)s is missing'), } def _to_python(self, valueDict, state): @@ -2018,7 +2024,7 @@ true_values = ['true', 't', 'yes', 'y', 'on', '1'] false_values = ['false', 'f', 'no', 'n', 'off', '0'] - messages = { "string" : "Value should be %(true)r or %(false)r" } + messages = { "string" : _("Value should be %(true)r or %(false)r") } def _to_python(self, value, state): if isinstance(value, (str, unicode)): @@ -2053,8 +2059,8 @@ """ messages = { - 'malformed': 'Value does not contain a signature', - 'badsig': 'Signature is not correct', + 'malformed': _('Value does not contain a signature'), + 'badsig': _('Signature is not correct'), } secret = None @@ -2176,8 +2182,8 @@ __unpackargs__ = ('*', 'field_names') messages = { - 'invalid': "Fields do not match (should be %(match)s)", - 'invalidNoMatch': "Fields do not match", + 'invalid': _("Fields do not match (should be %(match)s)"), + 'invalidNoMatch': _("Fields do not match"), } def validate_partial(self, field_dict, state): @@ -2239,9 +2245,9 @@ __unpackargs__ = ('cc_type_field', 'cc_number_field') messages = { - 'notANumber': "Please enter only the number, no other characters", - 'badLength': "You did not enter a valid number of digits", - 'invalidNumber': "That number is not valid", + 'notANumber': _("Please enter only the number, no other characters"), + 'badLength': _("You did not enter a valid number of digits"), + 'invalidNumber': _("That number is not valid"), } def validate_partial(self, field_dict, state): @@ -2356,8 +2362,8 @@ datetime_module = None messages = { - 'notANumber': "Please enter numbers only for month and year", - 'invalidNumber': "Invalid Expiration Date", + 'notANumber': _("Please enter numbers only for month and year"), + 'invalidNumber': _("Invalid Expiration Date"), } def validate_partial(self, field_dict, state): @@ -2426,8 +2432,8 @@ __unpackargs__ = ('cc_type_field', 'cc_code_field') messages = { - 'notANumber': "Please enter numbers only for credit card security code", - 'badLength': "Invalid credit card security code length", + 'notANumber': _("Please enter numbers only for credit card security code"), + 'badLength': _("Invalid credit card security code length"), } def validate_partial(self, field_dict, state): Modified: FormEncode/branches/gettext-enabled/tests/test_cc_expires.py =================================================================== --- FormEncode/branches/gettext-enabled/tests/test_cc_expires.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/tests/test_cc_expires.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -9,11 +9,11 @@ except Invalid, e: return e.unpack_errors()['ccExpiresMonth'] -messages = CreditCardExpires._messages +messages = ed.message def test_ed(): assert validate('11', '2250') is None - assert validate('11', 'test') == messages['notANumber'] - assert validate('test', '2250') == messages['notANumber'] - assert validate('10', '2005') == messages['invalidNumber'] - assert validate('10', '05') == messages['invalidNumber'] + assert validate('11', 'test') == messages('notANumber', None) + assert validate('test', '2250') == messages('notANumber', None) + assert validate('10', '2005') == messages('invalidNumber', None) + assert validate('10', '05') == messages('invalidNumber', None) Modified: FormEncode/branches/gettext-enabled/tests/test_cc_validator.py =================================================================== --- FormEncode/branches/gettext-enabled/tests/test_cc_validator.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/tests/test_cc_validator.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -9,11 +9,11 @@ except Invalid, e: return e.unpack_errors()['ccNumber'] -messages = CreditCardValidator._messages +messages = cc.message def test_cc(): assert validate('visa', '4'+('1'*15)) is None - assert validate('visa', '5'+('1'*12)) == messages['invalidNumber'] - assert validate('visa', '4'+('1'*11) + '2') == messages['invalidNumber'] - assert validate('visa', 'test') == messages['notANumber'] - assert validate('visa', '4'+('1'*10)) == messages['badLength'] + assert validate('visa', '5'+('1'*12)) == messages('invalidNumber', None) + assert validate('visa', '4'+('1'*11) + '2') == messages('invalidNumber', None) + assert validate('visa', 'test') == messages('notANumber', None) + assert validate('visa', '4'+('1'*10)) == messages('badLength', None) Added: FormEncode/branches/gettext-enabled/tests/test_i18n.py =================================================================== --- FormEncode/branches/gettext-enabled/tests/test_i18n.py (rev 0) +++ FormEncode/branches/gettext-enabled/tests/test_i18n.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -0,0 +1,64 @@ +import formencode + +import os + +ne = formencode.validators.NotEmpty() + +def _test_builtins(func): + def dummy(s): + return "builtins dummy" + import __builtin__ + __builtin__._ = dummy + + try: + ne.to_python("") + except formencode.api.Invalid, e: + func(e) + + del __builtin__._ + +def test_builtins(): + def withbuiltins(e): + assert str(e) == "builtins dummy" + + _test_builtins(withbuiltins) + + +def test_bultins_disabled(): + def withoutbuiltins(e): + assert str(e) <> "builtins dummy" + + ne.use_builtins_gettext = False + _test_builtins(withoutbuiltins) + + + +def test_state(): + class st(object): + def _(self, s): + return "state dummy" + + try: + ne.to_python("", state=st()) + except formencode.api.Invalid, e: + assert str(e) == "state dummy" + + +def _test_lang(language, notemptytext): + + formencode.api.set_stdtranslation(languages=[language]) + + try: + ne.to_python("") + except formencode.api.Invalid, e: + assert str(e) == notemptytext + + formencode.api.set_stdtranslation() #set back to defaults + + +def test_de(): + _test_lang("de", u"Bitte einen Wert eingeben") + + + + Modified: FormEncode/branches/gettext-enabled/tests/test_schema.py =================================================================== --- FormEncode/branches/gettext-enabled/tests/test_schema.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/tests/test_schema.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -4,6 +4,23 @@ from formencode.variabledecode import NestedVariables import cgi + +def setup_module(module): + """Disable i18n translation + """ + def notranslation(s): return s + import __builtin__ + __builtin__._ = notranslation + + + +def teardown_module(module): + """Remove translation function + """ + import __builtin__ + del __builtin__._ + + def d(**kw): return kw def cgi_parse(qs): @@ -114,9 +131,11 @@ text="The input field 'whatever' was not expected.") def test_this(): + for case in all_cases: yield case.test + def test_merge(): assert (merge_dicts(dict(a='a'), dict(b='b')) == dict(a='a', b='b')) @@ -128,4 +147,5 @@ c='foo')) == dict(a=['a1\naa1', 'a2'], b=['b\nbb', 'bbb'], c=['c'])) - + + Modified: FormEncode/branches/gettext-enabled/tests/test_sqlschema.py =================================================================== --- FormEncode/branches/gettext-enabled/tests/test_sqlschema.py 2006-10-02 14:23:09 UTC (rev 1967) +++ FormEncode/branches/gettext-enabled/tests/test_sqlschema.py 2006-10-02 19:04:46 UTC (rev 1968) @@ -3,6 +3,22 @@ from formencode import validators from datetime import datetime, date +def setup_module(module): + """Disable i18n translation + """ + def notranslation(s): return s + import __builtin__ + __builtin__._ = notranslation + + + +def teardown_module(module): + """Remove translation function + """ + import __builtin__ + del __builtin__._ + + sqlhub.processConnection = connectionForURI('sqlite:/:memory:') class EventObject(SQLObject): |