Andriy Kornatskyy avatar Andriy Kornatskyy committed cfad9b1

Introduced quick start i18n project template.

Comments (0)

Files changed (19)

demos/quickstart-i18n/MANIFEST.in

 recursive-include content/static/img *.ico *.jpg *.gif *.png
 recursive-include content/static/js *.js
 recursive-include content/templates *.html
+recursive-include i18n *.po

demos/quickstart-i18n/Makefile

-.SILENT: env clean release run uwsgi gunicorn qa test nose-cover test-cover benchmark profile gropf
-.PHONY: env clean release run uwsgi gunicorn qa test nose-cover test-cover benchmark profile gropf
+.SILENT: env clean release po run uwsgi gunicorn qa test nose-cover test-cover benchmark profile gropf
+.PHONY: env clean release po run uwsgi gunicorn qa test nose-cover test-cover benchmark profile gropf
 
 VERSION=2.7
 PYPI=http://pypi.python.org/simple
 NOSE=$(ENV)/bin/nosetests-$(VERSION)
 
 
-all: clean nose-cover release
+all: clean po nose-cover release
 
 env:
 	PYTHON_EXE=/usr/local/bin/python$(VERSION); \
 	rm -rf src/*.egg-info/
 	$(PYTHON) setup.py -q egg_info sdist
 
+po:
+define FIX
+xargs grep -E "_\(['\"]" \
+		| sed -r "s/[u]?'#_\('([^']*)'\)'/_('\1')/g" \
+		| sed -r "s/[u]?'#_\(\"([^\"]*)\"\)'/_(\"\1\")/g" \
+		| sed -r "s/[u]?\"#_\('([^']*)'\)\"/_('\1')/g" \
+		| sed -r "s/[u]?\"#_\(\"([^\"]*)\"\)\"/_(\"\1\")/g" \
+		| sed -r "s/#_\('([^']*)'\)/_('\1')/g" \
+		| sed -r "s/#_\(\"([^\"]*)\"\)/_(\"\1\")/g"
+endef
+	find content/templates/shared -name '*.html' | $(FIX) \
+		| xgettext --join-existing --no-location --omit-header \
+		--language=Python -o i18n/en/LC_MESSAGES/shared.po - ; \
+	(find content/templates/public -name '*.html' ; \
+		find src/public -name '*.py') | $(FIX) \
+		| xgettext --join-existing --no-location --omit-header \
+		--language=Python -o i18n/en/LC_MESSAGES/public.po - ; \
+	for l in `ls -d i18n/*/ | cut -d / -f 2`; do \
+		echo -n "$$l => "; \
+		msgfmt -v i18n/$$l/LC_MESSAGES/public.po \
+			i18n/$$l/LC_MESSAGES/shared.po \
+			-o i18n/$$l/LC_MESSAGES/public.mo; \
+		msgfmt -v i18n/$$l/LC_MESSAGES/validation.po \
+			-o i18n/$$l/LC_MESSAGES/validation.mo; \
+	done
+
 run:
 	$(PYTHON) src/app.py
 

demos/quickstart-i18n/content/templates/public/home.html

 @extends("shared/master.html")
+@require(_)
 
 @def title():
-Home
+@_('Home')
 @end
 
 @def content():
 <div id="welcome">
-    <h2>Welcome!</h2>
+    <h2>@_('Welcome!')</h2>
     <p>
     Lorem ipsum dolor sit amet, consectetur adipiscing elit.
     </p>

demos/quickstart-i18n/content/templates/public/http400.html

 @extends("shared/master.html")
+@require(_)
 
 @def title():
-Bad Request
+@_('Bad Request')
 @end
 
 @def content():
 <div id="error">
-    <h2>Oops! Code 400. Sorry, we can't process your request.</h2>
+    <h2>@_("Oops! Code 400. Sorry, we can't process your request.")</h2>
     <p>
-    The 400 Bad Request error is an HTTP status code that
-    means that the request you sent to the website server (i.e.
-    a request to load a web page) was somehow malformed therefore
-    the server was unable to understand or process the request.
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
     </p>
 </div>
 @end

demos/quickstart-i18n/content/templates/public/http403.html

 @extends("shared/master.html")
+@require(_)
 
 @def title():
-Access Denied
+@_('Access Denied')
 @end
 
 @def content():
 <div id="error">
-    <h2>Oops! Code 403. Access is denied.</h2>
+    <h2>@_('Oops! Code 403. Access is denied.')</h2>
     <p>
-    You do not have permission to view this directory or page
-    using the credentials that you supplied.
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
     </p>
 </div>
 @end

demos/quickstart-i18n/content/templates/public/http404.html

 @extends("shared/master.html")
+@require(_)
 
 @def title():
-We are sorry, the page you requested cannot be found.
+@_('We are sorry, the page you requested cannot be found.')
 @end
 
 @def content():
 <div id="error">
-    <h2>Oops! Code 404. Sorry, we can't find that page.</h2>
+    <h2>@_("Oops! Code 404. Sorry, we can't find that page.")</h2>
     <p>
-    Unfortunately the page you are looking for may have been
-    removed, had its name changed, under construction or is
-    temporarily unavailable. Try checking the web address for
-    typos, please. We apologize for the inconvenience.
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
     </p>
 </div>
 @end

demos/quickstart-i18n/content/templates/public/http500.html

 @extends("shared/master.html")
+@require(_)
 
 @def title():
-We are sorry, we can not process your request.
+@_('We are sorry, we can not process your request.')
 @end
 
 @def content():
 <div id="error">
-    <h2>Oops! Code 500. Sorry, we can not process your request.</h2>
+    <h2>@_('Oops! Code 500. Sorry, we can not process your request.')</h2>
     <p>
-    The web server encountered an unexpected condition that
-    prevented it from fulfilling the request by the client for
-    access to the requested URL.
+    Lorem ipsum dolor sit amet, consectetur adipiscing elit.
     </p>
 </div>
 @end

demos/quickstart-i18n/content/templates/shared/master.html

-@require(path_for)
+@require(_, path_for)
 <!DOCTYPE html>
 <html>
     <head>
         @def title():
         @end
-        <title>My Site - @title()</title>
+        <title>@_('My Site') - @title()</title>
         <link href="@path_for('static', path='css/site.css')" type="text/css" rel="stylesheet" />
     </head>
     <body>
         <div class="page">
             <div id="header">
-                <h1><a href="@path_for('default')">My Site</a></h1>
+                <h1><a href="@path_for('default')">@_('My Site')</a></h1>
+                #include("shared/snippet/menu-locale.html")
             </div>
             <div id="main">
                 <div id="placeholder">
                     @def content():
                     @end
                     @content()\
-                </div>                
+                </div>
             </div>
-            <div id="footer">Version #__version__</div>
+            <div id="footer">@_('Version') #__version__</div>
         </div>
         #include("shared/snippet/script.html")
         @def script():

demos/quickstart-i18n/content/templates/shared/snippet/menu-locale.html

+@require(_, path_for, route_args)
+<i>
+    <a href="@path_for(route_args.route_name, locale='en')">@_('English')</a> | \
+    <a href="@path_for(route_args.route_name, locale='ru')">@_('Russian')</a>
+</i>

demos/quickstart-i18n/i18n/en/LC_MESSAGES/public.po

+msgid "Home"
+msgstr "Home"
+
+msgid "Welcome!"
+msgstr "Welcome!"
+
+msgid "We are sorry, we can not process your request."
+msgstr "We are sorry, we can not process your request."
+
+msgid "Oops! Code 500. Sorry, we can not process your request."
+msgstr "Oops! Code 500. Sorry, we can not process your request."
+
+msgid "Bad Request"
+msgstr "Bad Request"
+
+msgid "Oops! Code 400. Sorry, we can't process your request."
+msgstr "Oops! Code 400. Sorry, we can't process your request."
+
+msgid "We are sorry, the page you requested cannot be found."
+msgstr "We are sorry, the page you requested cannot be found."
+
+msgid "Oops! Code 404. Sorry, we can't find that page."
+msgstr "Oops! Code 404. Sorry, we can't find that page."
+
+msgid "Access Denied"
+msgstr "Access Denied"
+
+msgid "Oops! Code 403. Access is denied."
+msgstr "Oops! Code 403. Access is denied."

demos/quickstart-i18n/i18n/en/LC_MESSAGES/shared.po

+# Messages for ``quickstart-i18n``.
+# Copyright (C) 2013 Andriy Kornatskyy
+# Andriy Kornatskyy <andriy.kornatskyy@live.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: quickstart-i18n\n"
+"Report-Msgid-Bugs-To: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"POT-Creation-Date: 2013-01-16 10:03+0200\n"
+"PO-Revision-Date: 2013-01-16 10:03+0200\n"
+"Last-Translator: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"Language: US English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "My Site"
+msgstr "My Site"
+
+msgid "Version"
+msgstr "Version"
+
+msgid "English"
+msgstr "English"
+
+msgid "Russian"
+msgstr "Русский"

demos/quickstart-i18n/i18n/en/LC_MESSAGES/validation.po

+# Messages for ``wheezy.validation``.
+# Copyright (C) 2011 Andriy Kornatskyy
+# Andriy Kornatskyy <andriy.kornatskyy@live.com>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: wheezy.validation\n"
+"Report-Msgid-Bugs-To: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"POT-Creation-Date: 2011-11-02 14:13+0200\n"
+"PO-Revision-Date: 2012-05-23 11:14+0300\n"
+"Last-Translator: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"Language: US English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. thousands separator
+#: src/wheezy/validation/format.py:7
+msgid ","
+msgstr ","
+
+#. decimal point separator
+#: src/wheezy/validation/format.py:9
+msgid "."
+msgstr "."
+
+#. default date input format: 2008/5/18.
+#: src/wheezy/validation/format.py:11
+msgid "%Y/%m/%d"
+msgstr "%Y/%m/%d"
+
+#. fallback date input formats: 5/18/2008. Use | to separate multiple values.
+#: src/wheezy/validation/format.py:14 src/wheezy/validation/format.py:15
+msgid "%m/%d/%Y|%Y-%m-%d|%m/%d/%y"
+msgstr "%m/%d/%Y|%Y-%m-%d|%m/%d/%y"
+
+#. default time input format: 16:34.
+#: src/wheezy/validation/format.py:16 src/wheezy/validation/format.py:17
+msgid "%H:%M"
+msgstr "%H:%M"
+
+#. fallback time input formats: 16:34:52. Use | to separate multiple values.
+#: src/wheezy/validation/format.py:18 src/wheezy/validation/format.py:21
+msgid "%H:%M:%S"
+msgstr "%H:%M:%S"
+
+#. default datetime input format: 2008/5/18 16:34
+#: src/wheezy/validation/format.py:20 src/wheezy/validation/format.py:23
+msgid "%Y/%m/%d %H:%M"
+msgstr "%Y/%m/%d %H:%M"
+
+#. fallback datetime input formats: 2008/5/18 16:34:52. Use | to separate.
+#: src/wheezy/validation/format.py:23 src/wheezy/validation/format.py:27
+msgid ""
+"%Y/%m/%d %H:%M:%S|%m/%d/%Y %H:%M|%m/%d/%Y %H:%M:%S|%Y-%m-%d %H:%M|%Y-%m-%d "
+"%H:%M:%S|%m/%d/%y %H:%M|%m/%d/%y %H:%M:%S"
+msgstr ""
+"%Y/%m/%d %H:%M:%S|%m/%d/%Y %H:%M|%m/%d/%Y %H:%M:%S|%Y-%m-%d %H:%M|%Y-%m-%d "
+"%H:%M:%S|%m/%d/%y %H:%M|%m/%d/%y %H:%M:%S"
+
+#: src/wheezy/validation/model.py:131 src/wheezy/validation/model.py:135
+msgid "Multiple input was not in a correct format."
+msgstr "Multiple input was not in a correct format."
+
+#: src/wheezy/validation/model.py:144 src/wheezy/validation/model.py:161
+msgid "Input was not in a correct format."
+msgstr "Input was not in a correct format."
+
+#: src/wheezy/validation/rules.py:26
+msgid "Required field cannot be left blank."
+msgstr "Required field cannot be left blank."
+
+#: src/wheezy/validation/rules.py:79
+msgid "Field cannot have a value."
+msgstr "Field cannot have a value."
+
+#: src/wheezy/validation/rules.py:150
+#, python-format
+msgid "Required to be a minimum of %(min)d characters in length."
+msgstr "Required to be a minimum of %(min)d characters in length."
+
+#: src/wheezy/validation/rules.py:155
+#, python-format
+msgid "The length must be exactly %(len)d characters."
+msgstr "The length must be exactly %(len)d characters."
+
+#: src/wheezy/validation/rules.py:156 src/wheezy/validation/rules.py:161
+#, python-format
+msgid "The length must fall within the range %(min)d - %(max)d characters."
+msgstr "The length must fall within the range %(min)d - %(max)d characters."
+
+#: src/wheezy/validation/rules.py:163 src/wheezy/validation/rules.py:167
+#, python-format
+msgid "Exceeds maximum length of %(max)d."
+msgstr "Exceeds maximum length of %(max)d."
+
+#: src/wheezy/validation/rules.py:297 src/wheezy/validation/rules.py:330
+#, python-format
+msgid "The value failed equality comparison with \"%(comparand)s\"."
+msgstr "The value failed equality comparison with \"%(comparand)s\"."
+
+#: src/wheezy/validation/rules.py:303 src/wheezy/validation/rules.py:336
+#, python-format
+msgid "The value failed not equal comparison with \"%(comparand)s\"."
+msgstr "The value failed not equal comparison with \"%(comparand)s\"."
+
+#: src/wheezy/validation/rules.py:389 src/wheezy/validation/rules.py:422
+msgid "Required to satisfy validation predicate condition."
+msgstr "Required to satisfy validation predicate condition."
+
+#: src/wheezy/validation/rules.py:420 src/wheezy/validation/rules.py:453
+msgid "Required to not match validation pattern."
+msgstr "Required to not match validation pattern."
+
+#: src/wheezy/validation/rules.py:424 src/wheezy/validation/rules.py:457
+msgid "Required to match validation pattern."
+msgstr "Required to match validation pattern."
+
+#: src/wheezy/validation/rules.py:479 src/wheezy/validation/rules.py:512
+msgid ""
+"Invalid slug. The value must consist of letters, digits, underscopes and/or "
+"hyphens."
+msgstr ""
+"Invalid slug. The value must consist of letters, digits, underscopes and/or "
+"hyphens."
+
+#: src/wheezy/validation/rules.py:510 src/wheezy/validation/rules.py:512
+#: src/wheezy/validation/rules.py:545
+msgid "Required to be a valid email address."
+msgstr "Required to be a valid email address."
+
+#: src/wheezy/validation/rules.py:557 src/wheezy/validation/rules.py:559
+#: src/wheezy/validation/rules.py:592
+#, python-format
+msgid "Required to be greater or equal to %(min)s."
+msgstr "Required to be greater or equal to %(min)s."
+
+#: src/wheezy/validation/rules.py:562 src/wheezy/validation/rules.py:564
+#: src/wheezy/validation/rules.py:597
+#, python-format
+msgid "The value must fall within the range %(min)s - %(max)s"
+msgstr "The value must fall within the range %(min)s - %(max)s"
+
+#: src/wheezy/validation/rules.py:569 src/wheezy/validation/rules.py:571
+#: src/wheezy/validation/rules.py:604
+#, python-format
+msgid "Exceeds maximum allowed value of %(max)s."
+msgstr "Exceeds maximum allowed value of %(max)s."
+
+#: src/wheezy/validation/rules.py:810 src/wheezy/validation/rules.py:812
+#: src/wheezy/validation/rules.py:845
+msgid "The value does not belong to the list of known items."
+msgstr "The value does not belong to the list of known items."
+
+#: src/wheezy/validation/rules.py:841 src/wheezy/validation/rules.py:843
+#: src/wheezy/validation/rules.py:876
+msgid "Required to be above a minimum allowed."
+msgstr "Required to be above a minimum allowed."
+
+#: src/wheezy/validation/rules.py:846 src/wheezy/validation/rules.py:848
+#: src/wheezy/validation/rules.py:881
+msgid "Must fall within a valid range."
+msgstr "Must fall within a valid range."
+
+#: src/wheezy/validation/rules.py:852 src/wheezy/validation/rules.py:854
+#: src/wheezy/validation/rules.py:887
+msgid "Exceeds maximum allowed."
+msgstr "Exceeds maximum allowed."

demos/quickstart-i18n/i18n/ru/LC_MESSAGES/public.po

+msgid "Home"
+msgstr "Домашняя"
+
+msgid "Welcome!"
+msgstr "Добро пожаловать!"
+
+msgid "We are sorry, we can not process your request."
+msgstr "Извените, к сожалению, мы не можем обработать ваш запрос."
+
+msgid "Oops! Code 500. Sorry, we can not process your request."
+msgstr "Oops! Code 500. К сожалению, мы не можем обработать ваш запрос."
+
+msgid "Bad Request"
+msgstr "Неверный запрос"
+
+msgid "Oops! Code 400. Sorry, we can't process your request."
+msgstr "Oops! Code 400. К сожалению, мы не можем обработать ваш запрос."
+
+msgid "We are sorry, the page you requested cannot be found."
+msgstr "К сожалению, запрашиваемая страница не найдена."
+
+msgid "Oops! Code 404. Sorry, we can't find that page."
+msgstr "Oops! Ошибка 404. К сожалению, мы не можем найти эту страницу."
+
+msgid "Access Denied"
+msgstr "Доступ запрещен"
+
+msgid "Oops! Code 403. Access is denied."
+msgstr "Oops! Code 403. Доступ запрещен."

demos/quickstart-i18n/i18n/ru/LC_MESSAGES/shared.po

+# Messages for ``quickstart-i18n``.
+# Copyright (C) 2013 Andriy Kornatskyy
+# Andriy Kornatskyy <andriy.kornatskyy@live.com>, 2013.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: quickstart-i18n\n"
+"Report-Msgid-Bugs-To: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"POT-Creation-Date: 2013-01-16 10:03+0200\n"
+"PO-Revision-Date: 2013-01-16 10:03+0200\n"
+"Last-Translator: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"Language: Russian\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+msgid "My Site"
+msgstr "Мой сайт"
+
+msgid "Version"
+msgstr "Версия"
+
+msgid "English"
+msgstr "English"
+
+msgid "Russian"
+msgstr "Русский"

demos/quickstart-i18n/i18n/ru/LC_MESSAGES/validation.po

+# Messages for ``wheezy.validation``.
+# Copyright (C) 2011 Andriy Kornatskyy
+# Andriy Kornatskyy <andriy.kornatskyy@live.com>, 2011.
+#
+msgid ""
+msgstr ""
+"Project-Id-Version: wheezy.validation\n"
+"Report-Msgid-Bugs-To: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"POT-Creation-Date: 2011-11-02 14:13+0200\n"
+"PO-Revision-Date: 2012-05-23 11:14+0300\n"
+"Last-Translator: Andriy Kornatskyy <andriy.kornatskyy@live.com>\n"
+"Language: US English\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+#. thousands separator
+#: src/wheezy/validation/format.py:7
+msgid ","
+msgstr ","
+
+#. decimal point separator
+#: src/wheezy/validation/format.py:9
+msgid "."
+msgstr "."
+
+#. default date input format: 2008/5/18.
+#: src/wheezy/validation/format.py:11
+msgid "%Y/%m/%d"
+msgstr "%Y/%m/%d"
+
+#. fallback date input formats: 5/18/2008. Use | to separate multiple values.
+#: src/wheezy/validation/format.py:14 src/wheezy/validation/format.py:15
+msgid "%m/%d/%Y|%Y-%m-%d|%m/%d/%y"
+msgstr "%m/%d/%Y|%Y-%m-%d|%m/%d/%y"
+
+#. default time input format: 16:34.
+#: src/wheezy/validation/format.py:16 src/wheezy/validation/format.py:17
+msgid "%H:%M"
+msgstr "%H:%M"
+
+#. fallback time input formats: 16:34:52. Use | to separate multiple values.
+#: src/wheezy/validation/format.py:18 src/wheezy/validation/format.py:21
+msgid "%H:%M:%S"
+msgstr "%H:%M:%S"
+
+#. default datetime input format: 2008/5/18 16:34
+#: src/wheezy/validation/format.py:20 src/wheezy/validation/format.py:23
+msgid "%Y/%m/%d %H:%M"
+msgstr "%Y/%m/%d %H:%M"
+
+#. fallback datetime input formats: 2008/5/18 16:34:52. Use | to separate.
+#: src/wheezy/validation/format.py:23 src/wheezy/validation/format.py:27
+msgid ""
+"%Y/%m/%d %H:%M:%S|%m/%d/%Y %H:%M|%m/%d/%Y %H:%M:%S|%Y-%m-%d %H:%M|%Y-%m-%d "
+"%H:%M:%S|%m/%d/%y %H:%M|%m/%d/%y %H:%M:%S"
+msgstr ""
+"%Y/%m/%d %H:%M:%S|%m/%d/%Y %H:%M|%m/%d/%Y %H:%M:%S|%Y-%m-%d %H:%M|%Y-%m-%d "
+"%H:%M:%S|%m/%d/%y %H:%M|%m/%d/%y %H:%M:%S"
+
+#: src/wheezy/validation/model.py:131 src/wheezy/validation/model.py:135
+msgid "Multiple input was not in a correct format."
+msgstr "Multiple input was not in a correct format."
+
+#: src/wheezy/validation/model.py:144 src/wheezy/validation/model.py:161
+msgid "Input was not in a correct format."
+msgstr "Input was not in a correct format."
+
+#: src/wheezy/validation/rules.py:26
+msgid "Required field cannot be left blank."
+msgstr "Required field cannot be left blank."
+
+#: src/wheezy/validation/rules.py:79
+msgid "Field cannot have a value."
+msgstr "Field cannot have a value."
+
+#: src/wheezy/validation/rules.py:150
+#, python-format
+msgid "Required to be a minimum of %(min)d characters in length."
+msgstr "Required to be a minimum of %(min)d characters in length."
+
+#: src/wheezy/validation/rules.py:155
+#, python-format
+msgid "The length must be exactly %(len)d characters."
+msgstr "The length must be exactly %(len)d characters."
+
+#: src/wheezy/validation/rules.py:156 src/wheezy/validation/rules.py:161
+#, python-format
+msgid "The length must fall within the range %(min)d - %(max)d characters."
+msgstr "The length must fall within the range %(min)d - %(max)d characters."
+
+#: src/wheezy/validation/rules.py:163 src/wheezy/validation/rules.py:167
+#, python-format
+msgid "Exceeds maximum length of %(max)d."
+msgstr "Exceeds maximum length of %(max)d."
+
+#: src/wheezy/validation/rules.py:297 src/wheezy/validation/rules.py:330
+#, python-format
+msgid "The value failed equality comparison with \"%(comparand)s\"."
+msgstr "The value failed equality comparison with \"%(comparand)s\"."
+
+#: src/wheezy/validation/rules.py:303 src/wheezy/validation/rules.py:336
+#, python-format
+msgid "The value failed not equal comparison with \"%(comparand)s\"."
+msgstr "The value failed not equal comparison with \"%(comparand)s\"."
+
+#: src/wheezy/validation/rules.py:389 src/wheezy/validation/rules.py:422
+msgid "Required to satisfy validation predicate condition."
+msgstr "Required to satisfy validation predicate condition."
+
+#: src/wheezy/validation/rules.py:420 src/wheezy/validation/rules.py:453
+msgid "Required to not match validation pattern."
+msgstr "Required to not match validation pattern."
+
+#: src/wheezy/validation/rules.py:424 src/wheezy/validation/rules.py:457
+msgid "Required to match validation pattern."
+msgstr "Required to match validation pattern."
+
+#: src/wheezy/validation/rules.py:479 src/wheezy/validation/rules.py:512
+msgid ""
+"Invalid slug. The value must consist of letters, digits, underscopes and/or "
+"hyphens."
+msgstr ""
+"Invalid slug. The value must consist of letters, digits, underscopes and/or "
+"hyphens."
+
+#: src/wheezy/validation/rules.py:510 src/wheezy/validation/rules.py:512
+#: src/wheezy/validation/rules.py:545
+msgid "Required to be a valid email address."
+msgstr "Required to be a valid email address."
+
+#: src/wheezy/validation/rules.py:557 src/wheezy/validation/rules.py:559
+#: src/wheezy/validation/rules.py:592
+#, python-format
+msgid "Required to be greater or equal to %(min)s."
+msgstr "Required to be greater or equal to %(min)s."
+
+#: src/wheezy/validation/rules.py:562 src/wheezy/validation/rules.py:564
+#: src/wheezy/validation/rules.py:597
+#, python-format
+msgid "The value must fall within the range %(min)s - %(max)s"
+msgstr "The value must fall within the range %(min)s - %(max)s"
+
+#: src/wheezy/validation/rules.py:569 src/wheezy/validation/rules.py:571
+#: src/wheezy/validation/rules.py:604
+#, python-format
+msgid "Exceeds maximum allowed value of %(max)s."
+msgstr "Exceeds maximum allowed value of %(max)s."
+
+#: src/wheezy/validation/rules.py:810 src/wheezy/validation/rules.py:812
+#: src/wheezy/validation/rules.py:845
+msgid "The value does not belong to the list of known items."
+msgstr "The value does not belong to the list of known items."
+
+#: src/wheezy/validation/rules.py:841 src/wheezy/validation/rules.py:843
+#: src/wheezy/validation/rules.py:876
+msgid "Required to be above a minimum allowed."
+msgstr "Required to be above a minimum allowed."
+
+#: src/wheezy/validation/rules.py:846 src/wheezy/validation/rules.py:848
+#: src/wheezy/validation/rules.py:881
+msgid "Must fall within a valid range."
+msgstr "Must fall within a valid range."
+
+#: src/wheezy/validation/rules.py:852 src/wheezy/validation/rules.py:854
+#: src/wheezy/validation/rules.py:887
+msgid "Exceeds maximum allowed."
+msgstr "Exceeds maximum allowed."

demos/quickstart-i18n/src/config.py

 
 from wheezy.caching import MemoryCache
 from wheezy.core.collections import defaultdict
+from wheezy.core.i18n import TranslationsManager
 from wheezy.html.ext.template import WhitespaceExtension
 from wheezy.html.ext.template import WidgetExtension
 from wheezy.html.utils import format_value
     'XSRF_NAME': '_x',
     'RESUBMISSION_NAME': '_c'
 })
+
+translations = TranslationsManager(
+    directories=['i18n'],
+    default_lang='en')
+options.update({
+    'translations_manager': translations
+})

demos/quickstart-i18n/src/public/web/tests/test_views.py

     def test_home(self):
         """ Ensure home page is rendered.
         """
-        assert 200 == self.client.get('/home')
+        assert 200 == self.client.get('/en/home')
         assert '- Home</title>' in self.client.content
 
     def test_static_files(self):
     def test_error_400(self):
         """ Ensure bad request page is rendered.
         """
-        assert 400 == self.client.get('/error/400')
+        assert 400 == self.client.get('/en/error/400')
         assert 'Code 400' in self.client.content
 
     def test_error_403(self):
         """ Ensure forbidden page is rendered.
         """
-        assert 403 == self.client.get('/error/403')
+        assert 403 == self.client.get('/en/error/403')
         assert 'Code 403' in self.client.content
 
     def test_error_404(self):
         """ Ensure not found page is rendered.
         """
-        assert 404 == self.client.get('/error/404')
+        assert 404 == self.client.get('/en/error/404')
         assert 'Code 404' in self.client.content
 
     def test_route_not_found(self):
     def test_error_500(self):
         """ Ensure internal error page is rendered.
         """
-        assert 500 == self.client.get('/error/500')
+        assert 500 == self.client.get('/en/error/500')
         assert 'Code 500' in self.client.content

demos/quickstart-i18n/src/public/web/views.py

 
 from datetime import timedelta
 
+from wheezy.core.descriptors import attribute
 from wheezy.http import response_cache
 from wheezy.http.transforms import gzip_transform
 from wheezy.http.transforms import response_transforms
 from public.web.profile import static_cache_profile
 
 
-class WelcomeHandler(BaseHandler):
+class PublicHandler(BaseHandler):
+    """ Anything common for public area handlers goes here.
+    """
+
+    @attribute
+    def translation(self):
+        return self.translations['public']
+
+
+class WelcomeHandler(PublicHandler):
 
     @response_cache(public_cache_profile)
     @response_transforms(gzip_transform())
     def get(self):
+        # There are two entry points for this handler:
+        # one that respond to / and the other one with
+        # locale in path, e.g. /en. Stick with default
+        # route so menu locate properly reverse url for
+        # current route.
+        self.route_args['route_name'] = 'default'
         return self.render_response('public/home.html')
 
 
 wraps_handler = lambda p: lambda h: response_cache(p)(
     response_transforms(gzip_transform(compress_level=9))(h))
 
-#w = wraps_handler(public_cache_profile)
+extra = {
+    'translation_name': 'public'
+}
+
+#w = wraps_handler(public_cache_profile, **extra)
 #home = w(template_handler('public/home.html'))
 
 # cached by nginx
-http400 = template_handler('public/http400.html', status_code=400)
-http403 = template_handler('public/http403.html', status_code=403)
-http404 = template_handler('public/http404.html', status_code=404)
-http500 = template_handler('public/http500.html', status_code=500)
+http400 = template_handler('public/http400.html', status_code=400, **extra)
+http403 = template_handler('public/http403.html', status_code=403, **extra)
+http404 = template_handler('public/http404.html', status_code=404, **extra)
+http500 = template_handler('public/http500.html', status_code=500, **extra)
 
 w = wraps_handler(static_cache_profile)
 static_file = w(file_handler(root='content/static/', age=timedelta(hours=1)))

demos/quickstart-i18n/src/urls.py

 from public.web.urls import static_urls
 from public.web.views import WelcomeHandler
 
+locale_pattern = '{locale:(en|ru)}/'
+locale_defaults = {'locale': 'en'}
 
+locale_urls = []
+locale_urls += public_urls
+locale_urls.append(('error/', error_urls))
+locale_urls.append(('.*', lambda ignore: None))
 all_urls = [
-    url('', WelcomeHandler, name='default')
+    url('', WelcomeHandler, locale_defaults),
+    url(locale_pattern.rstrip('/'), WelcomeHandler, locale_defaults,
+        name='default'),
+    (locale_pattern, locale_urls, locale_defaults),
 ]
-all_urls += public_urls
-all_urls += [('error/', error_urls)]
 all_urls += static_urls
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.