Version 0.1.0 0.1.0
authorThierry Florac <thierry.florac@onf.fr>
Wed, 17 Jun 2015 09:57:04 +0200
changeset 9 017ad36cc2ba
parent 8 44a92dc178ce
child 10 3ea177e986a6
Version 0.1.0
.installed.cfg
buildout.cfg
setup.py
src/pyams_i18n.egg-info/SOURCES.txt
src/pyams_i18n.egg-info/requires.txt
src/pyams_i18n/attr.py
src/pyams_i18n/expr.py
src/pyams_i18n/index.py
src/pyams_i18n/interfaces/__init__.py
src/pyams_i18n/interfaces/schema.py
src/pyams_i18n/interfaces/widget.py
src/pyams_i18n/resources/img/flags/aa.png
src/pyams_i18n/resources/img/flags/ab.png
src/pyams_i18n/resources/img/flags/ae.png
src/pyams_i18n/resources/img/flags/af.png
src/pyams_i18n/resources/img/flags/ak.png
src/pyams_i18n/resources/img/flags/am.png
src/pyams_i18n/resources/img/flags/an.png
src/pyams_i18n/resources/img/flags/arn.png
src/pyams_i18n/resources/img/flags/as.png
src/pyams_i18n/resources/img/flags/ast.png
src/pyams_i18n/resources/img/flags/av.png
src/pyams_i18n/resources/img/flags/ay.png
src/pyams_i18n/resources/img/flags/az.png
src/pyams_i18n/resources/img/flags/ba.png
src/pyams_i18n/resources/img/flags/ber.png
src/pyams_i18n/resources/img/flags/bh.png
src/pyams_i18n/resources/img/flags/bi.png
src/pyams_i18n/resources/img/flags/bm.png
src/pyams_i18n/resources/img/flags/bn.png
src/pyams_i18n/resources/img/flags/bo.png
src/pyams_i18n/resources/img/flags/br.png
src/pyams_i18n/resources/img/flags/bs.png
src/pyams_i18n/resources/img/flags/ca.png
src/pyams_i18n/resources/img/flags/ce.png
src/pyams_i18n/resources/img/flags/ch.png
src/pyams_i18n/resources/img/flags/co.png
src/pyams_i18n/resources/img/flags/cr.png
src/pyams_i18n/resources/img/flags/cs.png
src/pyams_i18n/resources/img/flags/cu.png
src/pyams_i18n/resources/img/flags/cv.png
src/pyams_i18n/resources/img/flags/cy.png
src/pyams_i18n/resources/img/flags/da.png
src/pyams_i18n/resources/img/flags/dv.png
src/pyams_i18n/resources/img/flags/dz.png
src/pyams_i18n/resources/img/flags/ee.png
src/pyams_i18n/resources/img/flags/el.png
src/pyams_i18n/resources/img/flags/eu.png
src/pyams_i18n/resources/img/flags/fa.png
src/pyams_i18n/resources/img/flags/fil.png
src/pyams_i18n/resources/img/flags/fj.png
src/pyams_i18n/resources/img/flags/ga.png
src/pyams_i18n/resources/img/flags/gbz.png
src/pyams_i18n/resources/img/flags/gd.png
src/pyams_i18n/resources/img/flags/gl.png
src/pyams_i18n/resources/img/flags/gsw.png
src/pyams_i18n/resources/img/flags/gu.png
src/pyams_i18n/resources/img/flags/ha.png
src/pyams_i18n/resources/img/flags/he.png
src/pyams_i18n/resources/img/flags/hi.png
src/pyams_i18n/resources/img/flags/hr.png
src/pyams_i18n/resources/img/flags/hy.png
src/pyams_i18n/resources/img/flags/id.png
src/pyams_i18n/resources/img/flags/ii.png
src/pyams_i18n/resources/img/flags/iu.png
src/pyams_i18n/resources/img/flags/kk.png
src/pyams_i18n/resources/img/flags/kl.png
src/pyams_i18n/resources/img/flags/km.png
src/pyams_i18n/resources/img/flags/kn.png
src/pyams_i18n/resources/img/flags/kok.png
src/pyams_i18n/resources/img/flags/kw.png
src/pyams_i18n/resources/img/flags/ky.png
src/pyams_i18n/resources/img/flags/lb.png
src/pyams_i18n/resources/img/flags/lo.png
src/pyams_i18n/resources/img/flags/mi.png
src/pyams_i18n/resources/img/flags/mk.png
src/pyams_i18n/resources/img/flags/ml.png
src/pyams_i18n/resources/img/flags/mn.png
src/pyams_i18n/resources/img/flags/moh.png
src/pyams_i18n/resources/img/flags/mr.png
src/pyams_i18n/resources/img/flags/ms.png
src/pyams_i18n/resources/img/flags/my.png
src/pyams_i18n/resources/img/flags/nb.png
src/pyams_i18n/resources/img/flags/ne.png
src/pyams_i18n/resources/img/flags/nl.png
src/pyams_i18n/resources/img/flags/nn.png
src/pyams_i18n/resources/img/flags/ns.png
src/pyams_i18n/resources/img/flags/oc.png
src/pyams_i18n/resources/img/flags/or.png
src/pyams_i18n/resources/img/flags/pa.png
src/pyams_i18n/resources/img/flags/ps.png
src/pyams_i18n/resources/img/flags/que.png
src/pyams_i18n/resources/img/flags/qut.png
src/pyams_i18n/resources/img/flags/rm.png
src/pyams_i18n/resources/img/flags/rw.png
src/pyams_i18n/resources/img/flags/sa.png
src/pyams_i18n/resources/img/flags/sah.png
src/pyams_i18n/resources/img/flags/si.png
src/pyams_i18n/resources/img/flags/sl.png
src/pyams_i18n/resources/img/flags/sma.png
src/pyams_i18n/resources/img/flags/smj.png
src/pyams_i18n/resources/img/flags/smn.png
src/pyams_i18n/resources/img/flags/sms.png
src/pyams_i18n/resources/img/flags/sq.png
src/pyams_i18n/resources/img/flags/sr.png
src/pyams_i18n/resources/img/flags/sv.png
src/pyams_i18n/resources/img/flags/sw.png
src/pyams_i18n/resources/img/flags/syr.png
src/pyams_i18n/resources/img/flags/ta.png
src/pyams_i18n/resources/img/flags/te.png
src/pyams_i18n/resources/img/flags/tg.png
src/pyams_i18n/resources/img/flags/th.png
src/pyams_i18n/resources/img/flags/tk.png
src/pyams_i18n/resources/img/flags/tn.png
src/pyams_i18n/resources/img/flags/tr.png
src/pyams_i18n/resources/img/flags/tt.png
src/pyams_i18n/resources/img/flags/ug.png
src/pyams_i18n/resources/img/flags/uk.png
src/pyams_i18n/resources/img/flags/ur.png
src/pyams_i18n/resources/img/flags/uz.png
src/pyams_i18n/resources/img/flags/vi.png
src/pyams_i18n/resources/img/flags/wee.png
src/pyams_i18n/resources/img/flags/wen.png
src/pyams_i18n/resources/img/flags/wo.png
src/pyams_i18n/resources/img/flags/xh.png
src/pyams_i18n/resources/img/flags/yo.png
src/pyams_i18n/resources/img/flags/zh.png
src/pyams_i18n/resources/img/flags/zu.png
src/pyams_i18n/schema.py
src/pyams_i18n/vocabulary.py
src/pyams_i18n/widget/__init__.py
src/pyams_i18n/widget/templates/i18n-input.pt
src/pyams_i18n/zmi/language.py
--- a/.installed.cfg	Wed May 20 12:25:29 2015 +0200
+++ b/.installed.cfg	Wed Jun 17 09:57:04 2015 +0200
@@ -1,19 +1,21 @@
 [buildout]
 installed_develop_eggs = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-file.egg-link
+	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/lingua.egg-link
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-i18n.egg-link
+	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-catalog.egg-link
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-utils.egg-link
 parts = package i18n pyflakes test
 
 [package]
 __buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pyams_upgrade
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/proutes
+	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/prequest
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pshell
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pviews
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pdistreport
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pcreate
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/prequest
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pserve
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/ptweens
+	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pviews
+	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/pcreate
 __buildout_signature__ = zc.recipe.egg-2.0.1-py3.4.egg setuptools-14.3-py3.4.egg zc.buildout-2.3.1-py3.4.egg
 _b = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin
 _d = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs
@@ -22,6 +24,7 @@
 develop-eggs-directory = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs
 eggs = pyams_i18n
 	persistent
+	pyams_catalog
 	pyams_file
 	pyams_utils
 	pyramid
@@ -67,7 +70,7 @@
 [test]
 __buildout_installed__ = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/parts/test
 	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/test
-__buildout_signature__ = zc.recipe.testrunner-2.0.0-py3.4.egg zc.recipe.egg-2.0.1-py3.4.egg setuptools-14.3-py3.4.egg zope.testrunner-4.4.6-py3.4.egg zc.buildout-2.3.1-py3.4.egg zope.interface-4.1.2-py3.4-linux-x86_64.egg zope.exceptions-4.0.7-py3.4.egg six-1482e89f68d85eea27f4ed7749df2819
+__buildout_signature__ = zc.recipe.testrunner-2.0.0-py3.4.egg zc.recipe.egg-2.0.1-py3.4.egg setuptools-14.3-py3.4.egg zope.testrunner-4.4.6-py3.4.egg zc.buildout-2.3.1-py3.4.egg zope.interface-4.1.2-py3.4-linux-x86_64.egg zope.exceptions-4.0.7-py3.4.egg six-e6b62e54b4df360c40dfcbb76c1ecf1a
 _b = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin
 _d = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs
 _e = /var/local/env/pyams/eggs
@@ -78,21 +81,3 @@
 location = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/parts/test
 recipe = zc.recipe.testrunner
 script = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/bin/test
-
-[buildout]
-installed_develop_eggs = /home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-file.egg-link
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/lingua.egg-link
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-i18n.egg-link
-	/home/tflorac/Dropbox/src/PyAMS/pyams_i18n/develop-eggs/pyams-utils.egg-link
-
-[buildout]
-parts = i18n pyflakes test package
-
-[buildout]
-parts = pyflakes test package i18n
-
-[buildout]
-parts = test package i18n pyflakes
-
-[buildout]
-parts = package i18n pyflakes test
--- a/buildout.cfg	Wed May 20 12:25:29 2015 +0200
+++ b/buildout.cfg	Wed Jun 17 09:57:04 2015 +0200
@@ -19,6 +19,7 @@
 src = src
 develop = .
           /var/local/src/pyams/ext/lingua
+          ../pyams_catalog
           ../pyams_file
           ../pyams_utils
 parts =
@@ -32,6 +33,7 @@
 eggs =
     pyams_i18n
     persistent
+    pyams_catalog
     pyams_file
     pyams_utils
     pyramid
--- a/setup.py	Wed May 20 12:25:29 2015 +0200
+++ b/setup.py	Wed Jun 17 09:57:04 2015 +0200
@@ -60,6 +60,7 @@
           'setuptools',
           # -*- Extra requirements: -*-
           'persistent',
+          'pyams_catalog',
           'pyams_file',
           'pyams_utils',
           'pyramid',
--- a/src/pyams_i18n.egg-info/SOURCES.txt	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n.egg-info/SOURCES.txt	Wed Jun 17 09:57:04 2015 +0200
@@ -4,7 +4,9 @@
 docs/README.txt
 src/pyams_i18n/__init__.py
 src/pyams_i18n/attr.py
-src/pyams_i18n/configure.zcml
+src/pyams_i18n/expr.py
+src/pyams_i18n/include.py
+src/pyams_i18n/index.py
 src/pyams_i18n/language.py
 src/pyams_i18n/negotiator.py
 src/pyams_i18n/property.py
@@ -25,12 +27,19 @@
 src/pyams_i18n/locales/pyams_i18n.pot
 src/pyams_i18n/locales/fr/LC_MESSAGES/pyams_i18n.mo
 src/pyams_i18n/locales/fr/LC_MESSAGES/pyams_i18n.po
+src/pyams_i18n/resources/img/flags/aa.png
 src/pyams_i18n/resources/img/flags/aa_ET.png
+src/pyams_i18n/resources/img/flags/ab.png
 src/pyams_i18n/resources/img/flags/ab_GE.png
+src/pyams_i18n/resources/img/flags/ae.png
 src/pyams_i18n/resources/img/flags/ae_IR.png
+src/pyams_i18n/resources/img/flags/af.png
 src/pyams_i18n/resources/img/flags/af_ZA.png
+src/pyams_i18n/resources/img/flags/ak.png
 src/pyams_i18n/resources/img/flags/ak_GH.png
+src/pyams_i18n/resources/img/flags/am.png
 src/pyams_i18n/resources/img/flags/am_ET.png
+src/pyams_i18n/resources/img/flags/an.png
 src/pyams_i18n/resources/img/flags/an_ES.png
 src/pyams_i18n/resources/img/flags/ar.png
 src/pyams_i18n/resources/img/flags/ar_AE.png
@@ -49,39 +58,64 @@
 src/pyams_i18n/resources/img/flags/ar_SY.png
 src/pyams_i18n/resources/img/flags/ar_TN.png
 src/pyams_i18n/resources/img/flags/ar_YE.png
+src/pyams_i18n/resources/img/flags/arn.png
 src/pyams_i18n/resources/img/flags/arn_CL.png
+src/pyams_i18n/resources/img/flags/as.png
 src/pyams_i18n/resources/img/flags/as_IN.png
+src/pyams_i18n/resources/img/flags/ast.png
 src/pyams_i18n/resources/img/flags/ast_ES.png
+src/pyams_i18n/resources/img/flags/av.png
 src/pyams_i18n/resources/img/flags/av_RU.png
+src/pyams_i18n/resources/img/flags/ay.png
 src/pyams_i18n/resources/img/flags/ay_BO.png
+src/pyams_i18n/resources/img/flags/az.png
 src/pyams_i18n/resources/img/flags/az_AZ-Cyrl.png
 src/pyams_i18n/resources/img/flags/az_AZ-Latn.png
+src/pyams_i18n/resources/img/flags/ba.png
 src/pyams_i18n/resources/img/flags/ba_RU.png
 src/pyams_i18n/resources/img/flags/be.png
 src/pyams_i18n/resources/img/flags/be_BY.png
+src/pyams_i18n/resources/img/flags/ber.png
 src/pyams_i18n/resources/img/flags/ber_DZ.png
 src/pyams_i18n/resources/img/flags/bg.png
 src/pyams_i18n/resources/img/flags/bg_BG.png
+src/pyams_i18n/resources/img/flags/bh.png
 src/pyams_i18n/resources/img/flags/bh_IN.png
+src/pyams_i18n/resources/img/flags/bi.png
 src/pyams_i18n/resources/img/flags/bi_VU.png
+src/pyams_i18n/resources/img/flags/bm.png
 src/pyams_i18n/resources/img/flags/bm_ML.png
+src/pyams_i18n/resources/img/flags/bn.png
 src/pyams_i18n/resources/img/flags/bn_IN.png
+src/pyams_i18n/resources/img/flags/bo.png
 src/pyams_i18n/resources/img/flags/bo_BT.png
 src/pyams_i18n/resources/img/flags/bo_CN.png
+src/pyams_i18n/resources/img/flags/br.png
 src/pyams_i18n/resources/img/flags/br_FR.png
+src/pyams_i18n/resources/img/flags/bs.png
 src/pyams_i18n/resources/img/flags/bs_BA-Cyrl.png
 src/pyams_i18n/resources/img/flags/bs_BA-Latn.png
+src/pyams_i18n/resources/img/flags/ca.png
 src/pyams_i18n/resources/img/flags/ca_AD.png
 src/pyams_i18n/resources/img/flags/ca_ES.png
 src/pyams_i18n/resources/img/flags/ca_FR.png
+src/pyams_i18n/resources/img/flags/ce.png
 src/pyams_i18n/resources/img/flags/ce_RU.png
+src/pyams_i18n/resources/img/flags/ch.png
 src/pyams_i18n/resources/img/flags/ch_US.png
+src/pyams_i18n/resources/img/flags/co.png
 src/pyams_i18n/resources/img/flags/co_FR.png
+src/pyams_i18n/resources/img/flags/cr.png
 src/pyams_i18n/resources/img/flags/cr_CA.png
+src/pyams_i18n/resources/img/flags/cs.png
 src/pyams_i18n/resources/img/flags/cs_CZ.png
+src/pyams_i18n/resources/img/flags/cu.png
 src/pyams_i18n/resources/img/flags/cu_BG.png
+src/pyams_i18n/resources/img/flags/cv.png
 src/pyams_i18n/resources/img/flags/cv_RU.png
+src/pyams_i18n/resources/img/flags/cy.png
 src/pyams_i18n/resources/img/flags/cy_GB.png
+src/pyams_i18n/resources/img/flags/da.png
 src/pyams_i18n/resources/img/flags/da_DK.png
 src/pyams_i18n/resources/img/flags/de.png
 src/pyams_i18n/resources/img/flags/de_AT.png
@@ -89,9 +123,13 @@
 src/pyams_i18n/resources/img/flags/de_DE.png
 src/pyams_i18n/resources/img/flags/de_LI.png
 src/pyams_i18n/resources/img/flags/de_LU.png
+src/pyams_i18n/resources/img/flags/dv.png
 src/pyams_i18n/resources/img/flags/dv_MV.png
+src/pyams_i18n/resources/img/flags/dz.png
 src/pyams_i18n/resources/img/flags/dz_BT.png
+src/pyams_i18n/resources/img/flags/ee.png
 src/pyams_i18n/resources/img/flags/ee_GH.png
+src/pyams_i18n/resources/img/flags/el.png
 src/pyams_i18n/resources/img/flags/el_GR.png
 src/pyams_i18n/resources/img/flags/en.png
 src/pyams_i18n/resources/img/flags/en_AU.png
@@ -132,11 +170,15 @@
 src/pyams_i18n/resources/img/flags/es_US.png
 src/pyams_i18n/resources/img/flags/es_VE.png
 src/pyams_i18n/resources/img/flags/et_EE.png
+src/pyams_i18n/resources/img/flags/eu.png
 src/pyams_i18n/resources/img/flags/eu_ES.png
+src/pyams_i18n/resources/img/flags/fa.png
 src/pyams_i18n/resources/img/flags/fa_IR.png
 src/pyams_i18n/resources/img/flags/fi.png
 src/pyams_i18n/resources/img/flags/fi_FI.png
+src/pyams_i18n/resources/img/flags/fil.png
 src/pyams_i18n/resources/img/flags/fil_PH.png
+src/pyams_i18n/resources/img/flags/fj.png
 src/pyams_i18n/resources/img/flags/fj_FJ.png
 src/pyams_i18n/resources/img/flags/fo.png
 src/pyams_i18n/resources/img/flags/fo_FO.png
@@ -148,27 +190,41 @@
 src/pyams_i18n/resources/img/flags/fr_LU.png
 src/pyams_i18n/resources/img/flags/fr_MC.png
 src/pyams_i18n/resources/img/flags/fy_NL.png
+src/pyams_i18n/resources/img/flags/ga.png
 src/pyams_i18n/resources/img/flags/ga_IE.png
+src/pyams_i18n/resources/img/flags/gbz.png
 src/pyams_i18n/resources/img/flags/gbz_AF.png
+src/pyams_i18n/resources/img/flags/gd.png
 src/pyams_i18n/resources/img/flags/gd_GB.png
+src/pyams_i18n/resources/img/flags/gl.png
 src/pyams_i18n/resources/img/flags/gl_ES.png
+src/pyams_i18n/resources/img/flags/gsw.png
 src/pyams_i18n/resources/img/flags/gsw_FR.png
+src/pyams_i18n/resources/img/flags/gu.png
 src/pyams_i18n/resources/img/flags/gu_IN.png
+src/pyams_i18n/resources/img/flags/ha.png
 src/pyams_i18n/resources/img/flags/ha_NG-Latn.png
+src/pyams_i18n/resources/img/flags/he.png
 src/pyams_i18n/resources/img/flags/he_IL.png
+src/pyams_i18n/resources/img/flags/hi.png
 src/pyams_i18n/resources/img/flags/hi_IN.png
+src/pyams_i18n/resources/img/flags/hr.png
 src/pyams_i18n/resources/img/flags/hr_BA.png
 src/pyams_i18n/resources/img/flags/hr_HR.png
 src/pyams_i18n/resources/img/flags/hu.png
 src/pyams_i18n/resources/img/flags/hu_HU.png
+src/pyams_i18n/resources/img/flags/hy.png
 src/pyams_i18n/resources/img/flags/hy_AM.png
+src/pyams_i18n/resources/img/flags/id.png
 src/pyams_i18n/resources/img/flags/id_ID.png
+src/pyams_i18n/resources/img/flags/ii.png
 src/pyams_i18n/resources/img/flags/ii_CN.png
 src/pyams_i18n/resources/img/flags/is.png
 src/pyams_i18n/resources/img/flags/is_IS.png
 src/pyams_i18n/resources/img/flags/it.png
 src/pyams_i18n/resources/img/flags/it_CH.png
 src/pyams_i18n/resources/img/flags/it_IT.png
+src/pyams_i18n/resources/img/flags/iu.png
 src/pyams_i18n/resources/img/flags/iu_CA-Cans.png
 src/pyams_i18n/resources/img/flags/iu_CA-Latn.png
 src/pyams_i18n/resources/img/flags/ja.png
@@ -177,112 +233,175 @@
 src/pyams_i18n/resources/img/flags/ka_GE.png
 src/pyams_i18n/resources/img/flags/kh.png
 src/pyams_i18n/resources/img/flags/kh_KH.png
+src/pyams_i18n/resources/img/flags/kk.png
 src/pyams_i18n/resources/img/flags/kk_KZ.png
+src/pyams_i18n/resources/img/flags/kl.png
 src/pyams_i18n/resources/img/flags/kl_GL.png
+src/pyams_i18n/resources/img/flags/km.png
 src/pyams_i18n/resources/img/flags/km_KH.png
+src/pyams_i18n/resources/img/flags/kn.png
 src/pyams_i18n/resources/img/flags/kn_IN.png
 src/pyams_i18n/resources/img/flags/ko.png
 src/pyams_i18n/resources/img/flags/ko_KR.png
+src/pyams_i18n/resources/img/flags/kok.png
 src/pyams_i18n/resources/img/flags/kok_IN.png
+src/pyams_i18n/resources/img/flags/kw.png
 src/pyams_i18n/resources/img/flags/kw_GB.png
+src/pyams_i18n/resources/img/flags/ky.png
 src/pyams_i18n/resources/img/flags/ky_KG.png
+src/pyams_i18n/resources/img/flags/lb.png
 src/pyams_i18n/resources/img/flags/lb_LU.png
+src/pyams_i18n/resources/img/flags/lo.png
 src/pyams_i18n/resources/img/flags/lo_LA.png
 src/pyams_i18n/resources/img/flags/lt.png
 src/pyams_i18n/resources/img/flags/lt_LT.png
 src/pyams_i18n/resources/img/flags/lv.png
 src/pyams_i18n/resources/img/flags/lv_LV.png
+src/pyams_i18n/resources/img/flags/mi.png
 src/pyams_i18n/resources/img/flags/mi_NZ.png
+src/pyams_i18n/resources/img/flags/mk.png
 src/pyams_i18n/resources/img/flags/mk_MK.png
+src/pyams_i18n/resources/img/flags/ml.png
 src/pyams_i18n/resources/img/flags/ml_IN.png
+src/pyams_i18n/resources/img/flags/mn.png
 src/pyams_i18n/resources/img/flags/mn_CN.png
 src/pyams_i18n/resources/img/flags/mn_MN.png
+src/pyams_i18n/resources/img/flags/moh.png
 src/pyams_i18n/resources/img/flags/moh_CA.png
+src/pyams_i18n/resources/img/flags/mr.png
 src/pyams_i18n/resources/img/flags/mr_IN.png
+src/pyams_i18n/resources/img/flags/ms.png
 src/pyams_i18n/resources/img/flags/ms_BN.png
 src/pyams_i18n/resources/img/flags/ms_MY.png
 src/pyams_i18n/resources/img/flags/mt.png
 src/pyams_i18n/resources/img/flags/mt_MT.png
+src/pyams_i18n/resources/img/flags/my.png
 src/pyams_i18n/resources/img/flags/my_MM.png
+src/pyams_i18n/resources/img/flags/nb.png
 src/pyams_i18n/resources/img/flags/nb_NO.png
+src/pyams_i18n/resources/img/flags/ne.png
 src/pyams_i18n/resources/img/flags/ne_NP.png
+src/pyams_i18n/resources/img/flags/nl.png
 src/pyams_i18n/resources/img/flags/nl_BE.png
 src/pyams_i18n/resources/img/flags/nl_NL.png
+src/pyams_i18n/resources/img/flags/nn.png
 src/pyams_i18n/resources/img/flags/nn_NO.png
+src/pyams_i18n/resources/img/flags/ns.png
 src/pyams_i18n/resources/img/flags/ns_ZA.png
+src/pyams_i18n/resources/img/flags/oc.png
 src/pyams_i18n/resources/img/flags/oc_FR.png
+src/pyams_i18n/resources/img/flags/or.png
 src/pyams_i18n/resources/img/flags/or_IN.png
 src/pyams_i18n/resources/img/flags/other.png
+src/pyams_i18n/resources/img/flags/pa.png
 src/pyams_i18n/resources/img/flags/pa_IN.png
 src/pyams_i18n/resources/img/flags/pl.png
 src/pyams_i18n/resources/img/flags/pl_PL.png
+src/pyams_i18n/resources/img/flags/ps.png
 src/pyams_i18n/resources/img/flags/ps_AF.png
 src/pyams_i18n/resources/img/flags/pt.png
 src/pyams_i18n/resources/img/flags/pt_BR.png
 src/pyams_i18n/resources/img/flags/pt_PT.png
+src/pyams_i18n/resources/img/flags/que.png
 src/pyams_i18n/resources/img/flags/que_BO.png
 src/pyams_i18n/resources/img/flags/que_EC.png
 src/pyams_i18n/resources/img/flags/que_PE.png
+src/pyams_i18n/resources/img/flags/qut.png
 src/pyams_i18n/resources/img/flags/qut_GT.png
+src/pyams_i18n/resources/img/flags/rm.png
 src/pyams_i18n/resources/img/flags/rm_CH.png
 src/pyams_i18n/resources/img/flags/ro.png
 src/pyams_i18n/resources/img/flags/ro_RO.png
 src/pyams_i18n/resources/img/flags/ru.png
 src/pyams_i18n/resources/img/flags/ru_RU.png
+src/pyams_i18n/resources/img/flags/rw.png
 src/pyams_i18n/resources/img/flags/rw_RW.png
+src/pyams_i18n/resources/img/flags/sa.png
 src/pyams_i18n/resources/img/flags/sa_IN.png
+src/pyams_i18n/resources/img/flags/sah.png
 src/pyams_i18n/resources/img/flags/sah_RU.png
 src/pyams_i18n/resources/img/flags/se.png
 src/pyams_i18n/resources/img/flags/se_FI.png
 src/pyams_i18n/resources/img/flags/se_NO.png
 src/pyams_i18n/resources/img/flags/se_SE.png
+src/pyams_i18n/resources/img/flags/si.png
 src/pyams_i18n/resources/img/flags/si_LK.png
 src/pyams_i18n/resources/img/flags/sk.png
 src/pyams_i18n/resources/img/flags/sk_SK.png
+src/pyams_i18n/resources/img/flags/sl.png
 src/pyams_i18n/resources/img/flags/sl_SI.png
+src/pyams_i18n/resources/img/flags/sma.png
 src/pyams_i18n/resources/img/flags/sma_NO.png
 src/pyams_i18n/resources/img/flags/sma_SE.png
+src/pyams_i18n/resources/img/flags/smj.png
 src/pyams_i18n/resources/img/flags/smj_NO.png
 src/pyams_i18n/resources/img/flags/smj_SE.png
+src/pyams_i18n/resources/img/flags/smn.png
 src/pyams_i18n/resources/img/flags/smn_FI.png
+src/pyams_i18n/resources/img/flags/sms.png
 src/pyams_i18n/resources/img/flags/sms_FI.png
+src/pyams_i18n/resources/img/flags/sq.png
 src/pyams_i18n/resources/img/flags/sq_AL.png
+src/pyams_i18n/resources/img/flags/sr.png
 src/pyams_i18n/resources/img/flags/sr_BA-Cyrl.png
 src/pyams_i18n/resources/img/flags/sr_BA-Latn.png
 src/pyams_i18n/resources/img/flags/sr_SP-Cyrl.png
 src/pyams_i18n/resources/img/flags/sr_SP-Latn.png
+src/pyams_i18n/resources/img/flags/sv.png
 src/pyams_i18n/resources/img/flags/sv_FI.png
 src/pyams_i18n/resources/img/flags/sv_SE.png
+src/pyams_i18n/resources/img/flags/sw.png
 src/pyams_i18n/resources/img/flags/sw_KE.png
+src/pyams_i18n/resources/img/flags/syr.png
 src/pyams_i18n/resources/img/flags/syr_SY.png
+src/pyams_i18n/resources/img/flags/ta.png
 src/pyams_i18n/resources/img/flags/ta_IN.png
+src/pyams_i18n/resources/img/flags/te.png
 src/pyams_i18n/resources/img/flags/te_IN.png
+src/pyams_i18n/resources/img/flags/tg.png
 src/pyams_i18n/resources/img/flags/tg_TJ-Cyrl.png
+src/pyams_i18n/resources/img/flags/th.png
 src/pyams_i18n/resources/img/flags/th_TH.png
+src/pyams_i18n/resources/img/flags/tk.png
 src/pyams_i18n/resources/img/flags/tk_TM.png
+src/pyams_i18n/resources/img/flags/tn.png
 src/pyams_i18n/resources/img/flags/tn_ZA.png
+src/pyams_i18n/resources/img/flags/tr.png
 src/pyams_i18n/resources/img/flags/tr_TR.png
+src/pyams_i18n/resources/img/flags/tt.png
 src/pyams_i18n/resources/img/flags/tt_RU.png
+src/pyams_i18n/resources/img/flags/ug.png
 src/pyams_i18n/resources/img/flags/ug_CN.png
+src/pyams_i18n/resources/img/flags/uk.png
 src/pyams_i18n/resources/img/flags/uk_UA.png
+src/pyams_i18n/resources/img/flags/ur.png
 src/pyams_i18n/resources/img/flags/ur_IN.png
 src/pyams_i18n/resources/img/flags/ur_PK.png
+src/pyams_i18n/resources/img/flags/uz.png
 src/pyams_i18n/resources/img/flags/uz_UZ-Cyrl.png
 src/pyams_i18n/resources/img/flags/uz_UZ-Latn.png
+src/pyams_i18n/resources/img/flags/vi.png
 src/pyams_i18n/resources/img/flags/vi_VN.png
+src/pyams_i18n/resources/img/flags/wee.png
 src/pyams_i18n/resources/img/flags/wee_DE.png
+src/pyams_i18n/resources/img/flags/wen.png
 src/pyams_i18n/resources/img/flags/wen_DE.png
+src/pyams_i18n/resources/img/flags/wo.png
 src/pyams_i18n/resources/img/flags/wo_SN.png
+src/pyams_i18n/resources/img/flags/xh.png
 src/pyams_i18n/resources/img/flags/xh_ZA.png
+src/pyams_i18n/resources/img/flags/yo.png
 src/pyams_i18n/resources/img/flags/yo_NG.png
+src/pyams_i18n/resources/img/flags/zh.png
 src/pyams_i18n/resources/img/flags/zh_CN.png
 src/pyams_i18n/resources/img/flags/zh_HK.png
 src/pyams_i18n/resources/img/flags/zh_MO.png
 src/pyams_i18n/resources/img/flags/zh_SG.png
 src/pyams_i18n/resources/img/flags/zh_TW.png
+src/pyams_i18n/resources/img/flags/zu.png
 src/pyams_i18n/resources/img/flags/zu_ZA.png
 src/pyams_i18n/widget/__init__.py
 src/pyams_i18n/widget/templates/i18n-input.pt
 src/pyams_i18n/zmi/__init__.py
-src/pyams_i18n/zmi/configure.zcml
+src/pyams_i18n/zmi/language.py
 src/pyams_i18n/zmi/negotiator.py
\ No newline at end of file
--- a/src/pyams_i18n.egg-info/requires.txt	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n.egg-info/requires.txt	Wed Jun 17 09:57:04 2015 +0200
@@ -1,5 +1,6 @@
 setuptools
 persistent
+pyams_catalog
 pyams_file
 pyams_utils
 pyramid
--- a/src/pyams_i18n/attr.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/attr.py	Wed Jun 17 09:57:04 2015 +0200
@@ -16,10 +16,13 @@
 # import standard library
 
 # import interfaces
+from pyams_i18n.interfaces import II18n, INegotiator
 from zope.traversing.interfaces import ITraversable
 
 # import packages
-from pyams_utils.adapter import ContextAdapter, adapter_config
+from pyams_utils.adapter import adapter_config, ContextAdapter
+from pyams_utils.registry import query_utility
+from pyams_utils.request import check_request
 from pyramid.exceptions import NotFound
 from zope.interface import Interface
 
@@ -34,3 +37,33 @@
             return getattr(self.context, attr, {}).get(lang)
         except AttributeError:
             raise NotFound
+
+
+@adapter_config(context=Interface, provides=II18n)
+class I18nAttributeAdapter(ContextAdapter):
+    """I18n attribute adapter"""
+
+    def get_attribute(self, attribute, lang=None, request=None, default=None):
+        result = getattr(self.context, attribute)
+        if not isinstance(result, dict):
+            return default
+        if lang is None:
+            if request is None:
+                request = check_request()
+            lang = request.locale_name
+        return result.get(lang, default)
+
+    def query_attribute(self, attribute, lang=None, request=None):
+        result = getattr(self.context, attribute)
+        if not isinstance(result, dict):
+            return result
+        if lang is None:
+            if request is None:
+                request = check_request()
+            lang = request.locale_name
+        value = result.get(lang)
+        if not value:
+            negotiator = query_utility(INegotiator)
+            if (negotiator is not None) and (negotiator.server_language != lang):
+                value = result.get(negotiator.server_language)
+        return value
--- a/src/pyams_i18n/expr.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/expr.py	Wed Jun 17 09:57:04 2015 +0200
@@ -16,12 +16,11 @@
 # import standard library
 
 # import interfaces
-from pyams_i18n.interfaces import INegotiator
+from pyams_i18n.interfaces import II18n
 
 # import packages
 from chameleon.astutil import Symbol
 from chameleon.tales import StringExpr
-from pyams_utils.registry import query_utility
 from pyams_utils.tales import ContextExprMixin
 
 
@@ -35,17 +34,8 @@
         context_name = 'context',
         attr = name
     context = econtext.get(context_name)
-    result = getattr(context, attr)
-    if not isinstance(result, dict):
-        return result
     request = econtext.get('request')
-    lang = request.locale_name
-    value = result.get(lang)
-    if not value:
-        negotiator = query_utility(INegotiator)
-        if (negotiator is not None) and (negotiator.server_language != lang):
-            return result.get(negotiator.server_language)
-    return value
+    return II18n(context).query_attribute(attr, request=request)
 
 
 class I18nExpr(ContextExprMixin, StringExpr):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_i18n/index.py	Wed Jun 17 09:57:04 2015 +0200
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+from pyams_i18n.interfaces import II18n
+
+# import packages
+from hypatia.text import TextIndex
+from hypatia.text.lexicon import Lexicon
+from hypatia.util import BaseIndexMixin
+from persistent import Persistent
+from pyams_catalog.nltk import NltkFullTextProcessor
+from ZODB.broken import Broken
+
+
+_marker = object()
+
+
+class I18nTextIndexMixin(BaseIndexMixin):
+    """I18n text index mixin"""
+
+    def __init__(self, language, interface=None):
+        self.interface = interface
+        self.language = language
+
+    def discriminate(self, obj, default):
+        if self.interface is not None:
+            obj = self.interface(obj, None)
+            if obj is None:
+                return default
+
+        value = II18n(obj).get_attribute(self.discriminator, lang=self.language, default=_marker)
+        if value is _marker:
+            return default
+
+        if isinstance(value, Persistent):
+            raise ValueError('Catalog cannot index persistent object {0!r}'.format(value))
+
+        if isinstance(value, Broken):
+            raise ValueError('Catalog cannot index broken object {0!r}'.format(value))
+
+        return value
+
+
+class I18nTextIndexWithInterface(I18nTextIndexMixin, TextIndex):
+    """I18n text index"""
+
+    def __init__(self, language, discriminator, interface=None, lexicon=None, index=None, family=None):
+        I18nTextIndexMixin.__init__(self, language, interface)
+        if lexicon is None:
+            lexicon = Lexicon(NltkFullTextProcessor(language))
+        TextIndex.__init__(self, discriminator, lexicon, index, family)
--- a/src/pyams_i18n/interfaces/__init__.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/interfaces/__init__.py	Wed Jun 17 09:57:04 2015 +0200
@@ -86,7 +86,7 @@
     languages = List(title=_("Content languages"),
                      description=_("List of languages available for this content"),
                      required=True,
-                     value_type=Choice(vocabulary='PyAMS offered languages'))
+                     value_type=Choice(vocabulary='PyAMS base languages'))
 
 
 class IUserPreferredLanguage(Interface):
@@ -94,3 +94,13 @@
 
     def get_language(self):
         """Return main user preferred language"""
+
+
+class II18n(Interface):
+    """I18n attribute interface"""
+
+    def get_attribute(self, attribute, lang=None, request=None, default=None):
+        """Get attribute in given language"""
+
+    def query_attribute(self, attribute, request=None):
+        """Query attribute in given language"""
--- a/src/pyams_i18n/interfaces/schema.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/interfaces/schema.py	Wed Jun 17 09:57:04 2015 +0200
@@ -33,6 +33,10 @@
     """I18n text field marker interface"""
 
 
+class II18nHTMLField(II18nField):
+    """I18n HTML field marker interface"""
+
+
 class II18nFileField(II18nField):
     """I18n file field marker interface"""
 
--- a/src/pyams_i18n/interfaces/widget.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/interfaces/widget.py	Wed Jun 17 09:57:04 2015 +0200
@@ -33,5 +33,9 @@
     """I18n text widget interface"""
 
 
+class II18nHTMLWidget(II18nWidget):
+    """I18n HTML widget interface"""
+
+
 class II18nFileWidget(II18nWidget):
     """I18n file widget interface"""
Binary file src/pyams_i18n/resources/img/flags/aa.png has changed
Binary file src/pyams_i18n/resources/img/flags/ab.png has changed
Binary file src/pyams_i18n/resources/img/flags/ae.png has changed
Binary file src/pyams_i18n/resources/img/flags/af.png has changed
Binary file src/pyams_i18n/resources/img/flags/ak.png has changed
Binary file src/pyams_i18n/resources/img/flags/am.png has changed
Binary file src/pyams_i18n/resources/img/flags/an.png has changed
Binary file src/pyams_i18n/resources/img/flags/arn.png has changed
Binary file src/pyams_i18n/resources/img/flags/as.png has changed
Binary file src/pyams_i18n/resources/img/flags/ast.png has changed
Binary file src/pyams_i18n/resources/img/flags/av.png has changed
Binary file src/pyams_i18n/resources/img/flags/ay.png has changed
Binary file src/pyams_i18n/resources/img/flags/az.png has changed
Binary file src/pyams_i18n/resources/img/flags/ba.png has changed
Binary file src/pyams_i18n/resources/img/flags/ber.png has changed
Binary file src/pyams_i18n/resources/img/flags/bh.png has changed
Binary file src/pyams_i18n/resources/img/flags/bi.png has changed
Binary file src/pyams_i18n/resources/img/flags/bm.png has changed
Binary file src/pyams_i18n/resources/img/flags/bn.png has changed
Binary file src/pyams_i18n/resources/img/flags/bo.png has changed
Binary file src/pyams_i18n/resources/img/flags/br.png has changed
Binary file src/pyams_i18n/resources/img/flags/bs.png has changed
Binary file src/pyams_i18n/resources/img/flags/ca.png has changed
Binary file src/pyams_i18n/resources/img/flags/ce.png has changed
Binary file src/pyams_i18n/resources/img/flags/ch.png has changed
Binary file src/pyams_i18n/resources/img/flags/co.png has changed
Binary file src/pyams_i18n/resources/img/flags/cr.png has changed
Binary file src/pyams_i18n/resources/img/flags/cs.png has changed
Binary file src/pyams_i18n/resources/img/flags/cu.png has changed
Binary file src/pyams_i18n/resources/img/flags/cv.png has changed
Binary file src/pyams_i18n/resources/img/flags/cy.png has changed
Binary file src/pyams_i18n/resources/img/flags/da.png has changed
Binary file src/pyams_i18n/resources/img/flags/dv.png has changed
Binary file src/pyams_i18n/resources/img/flags/dz.png has changed
Binary file src/pyams_i18n/resources/img/flags/ee.png has changed
Binary file src/pyams_i18n/resources/img/flags/el.png has changed
Binary file src/pyams_i18n/resources/img/flags/eu.png has changed
Binary file src/pyams_i18n/resources/img/flags/fa.png has changed
Binary file src/pyams_i18n/resources/img/flags/fil.png has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_i18n/resources/img/flags/fj.png	Wed Jun 17 09:57:04 2015 +0200
@@ -0,0 +1,1 @@
+<html><head><meta http-equiv="content-type" content="text/html; charset=UTF-8"><title>Résultats Google Recherche d&#39;images correspondant à http://www.silber.de/bilder/icon/flag/fiji.png</title><style>html{height:100%}body{margin:0;font:62.5% arial,sans-serif;height:100%;overflow:hidden}a,a:visited{color:#00c}div{font-size:130%}#details{float:left;margin-top:10px}#details p{padding:0;margin:0 0 2px}img{border:none}#outer-separator{clear:both;width:100%;border-bottom:2px solid #404040;border-top:1px solid #a0a0a0;margin:10px 0 0;padding:0;font-size:1px;overflow:hidden}#separator{background:#eaeaea;height:3px}table{font-size:100%}</style></head><body><table cellpadding=0 cellspacing=0 height="100%" width="100%"><tr height="1%"><td style="top:0;width:100%"><div class=std style="background:#ebeff9;padding:6px 8px"><a href="http://images.google.fr/imghp?hl=fr"><img src=/images/isr_g.png style="padding:0;margin:0;vertical-align:middle;border:0" title="Page d&#39;accueil de Google Images" alt="Page d&#39;accueil de Google Images" width=72 height=24></a><form style="display:inline" method=GET action="/images"><input type=hidden name=um value="1"><input type=hidden name=hl value="fr"><input type=hidden name=tbo value="1"><input type=hidden name=imgsz value="i"><input type=hidden name=ndsp value="20"><input type=hidden name=tbs value="isch:1"><input type=hidden name=sa value="3">&nbsp;<input class=lst type=text name=q size=41 maxlength=2048 value="fiji.png" title="Recherche d&#39;images">&nbsp;<input type=submit name="btnG" class=lsb value="Recherche d&#39;images"></form>&nbsp;<a id=b2r href="/images?q=fiji.png&amp;start=40&amp;um=1&amp;hl=fr&amp;sa=N&amp;tbo=1&amp;imgsz=i&amp;ndsp=20&amp;tbs=isch:1">Retour aux résultats de recherche d&#39;images</a></div><table cellpadding=0 cellspacing=0 width="100%"><tr><td><a href="http://www.silber.de/bilder/icon/flag/fiji.png" id=thumbnail><img src="http://t0.gstatic.com/images?q=tbn:tW0krcFA2T2IvM:http://www.silber.de/bilder/icon/flag/fiji.png" width=16 height=11 style="float:left;margin:10px 10px 0;border:1px solid" alt="Afficher l&#39;image d&#39;origine"></a><div id=details><p style="margin-bottom:4px"><a href="http://www.silber.de/bilder/icon/flag/fiji.png" style="font-size:115%;font-weight:bold">Afficher l&#39;image d&#39;origine</a></p><p>16 x 11 - 1 ko - png - <span style="color:green">www.silber.de/bilder/<wbr>icon/flag/fiji.png</span></p><p>L&#39;image peut être soumise à des droits d&#39;auteur.</p><p>Voici l'image dans son contexte, sur la page : <a href="http://www.silber.de/anlage_banken.html">www.silber.de/<wbr>anlage_banken.html</a></p></div><td align=right valign=bottom><div style="padding-right:8px"><a href="http://www.silber.de/anlage_banken.html" style="text-decoration:none"><u>Supprimer le cadre</u>&nbsp;<img src=/images/isr_c.gif style="margin-bottom:-2px" height=15 width=15 alt=""></a></div></table><div id=outer-separator><div id=separator></div></div><tr><td><iframe allowtransparency=true frameborder=0 id=rf sandbox="allow-same-origin allow-forms allow-scripts" scrolling=auto src="http://www.silber.de/anlage_banken.html" style="width:100%;height:100%"></iframe></table></body><script>var a = document.getElementById('rf');a && a.contentWindow && a.contentWindow.focus();</script></html>
\ No newline at end of file
Binary file src/pyams_i18n/resources/img/flags/ga.png has changed
Binary file src/pyams_i18n/resources/img/flags/gbz.png has changed
Binary file src/pyams_i18n/resources/img/flags/gd.png has changed
Binary file src/pyams_i18n/resources/img/flags/gl.png has changed
Binary file src/pyams_i18n/resources/img/flags/gsw.png has changed
Binary file src/pyams_i18n/resources/img/flags/gu.png has changed
Binary file src/pyams_i18n/resources/img/flags/ha.png has changed
Binary file src/pyams_i18n/resources/img/flags/he.png has changed
Binary file src/pyams_i18n/resources/img/flags/hi.png has changed
Binary file src/pyams_i18n/resources/img/flags/hr.png has changed
Binary file src/pyams_i18n/resources/img/flags/hy.png has changed
Binary file src/pyams_i18n/resources/img/flags/id.png has changed
Binary file src/pyams_i18n/resources/img/flags/ii.png has changed
Binary file src/pyams_i18n/resources/img/flags/iu.png has changed
Binary file src/pyams_i18n/resources/img/flags/kk.png has changed
Binary file src/pyams_i18n/resources/img/flags/kl.png has changed
Binary file src/pyams_i18n/resources/img/flags/km.png has changed
Binary file src/pyams_i18n/resources/img/flags/kn.png has changed
Binary file src/pyams_i18n/resources/img/flags/kok.png has changed
Binary file src/pyams_i18n/resources/img/flags/kw.png has changed
Binary file src/pyams_i18n/resources/img/flags/ky.png has changed
Binary file src/pyams_i18n/resources/img/flags/lb.png has changed
Binary file src/pyams_i18n/resources/img/flags/lo.png has changed
Binary file src/pyams_i18n/resources/img/flags/mi.png has changed
Binary file src/pyams_i18n/resources/img/flags/mk.png has changed
Binary file src/pyams_i18n/resources/img/flags/ml.png has changed
Binary file src/pyams_i18n/resources/img/flags/mn.png has changed
Binary file src/pyams_i18n/resources/img/flags/moh.png has changed
Binary file src/pyams_i18n/resources/img/flags/mr.png has changed
Binary file src/pyams_i18n/resources/img/flags/ms.png has changed
Binary file src/pyams_i18n/resources/img/flags/my.png has changed
Binary file src/pyams_i18n/resources/img/flags/nb.png has changed
Binary file src/pyams_i18n/resources/img/flags/ne.png has changed
Binary file src/pyams_i18n/resources/img/flags/nl.png has changed
Binary file src/pyams_i18n/resources/img/flags/nn.png has changed
Binary file src/pyams_i18n/resources/img/flags/ns.png has changed
Binary file src/pyams_i18n/resources/img/flags/oc.png has changed
Binary file src/pyams_i18n/resources/img/flags/or.png has changed
Binary file src/pyams_i18n/resources/img/flags/pa.png has changed
Binary file src/pyams_i18n/resources/img/flags/ps.png has changed
Binary file src/pyams_i18n/resources/img/flags/que.png has changed
Binary file src/pyams_i18n/resources/img/flags/qut.png has changed
Binary file src/pyams_i18n/resources/img/flags/rm.png has changed
Binary file src/pyams_i18n/resources/img/flags/rw.png has changed
Binary file src/pyams_i18n/resources/img/flags/sa.png has changed
Binary file src/pyams_i18n/resources/img/flags/sah.png has changed
Binary file src/pyams_i18n/resources/img/flags/si.png has changed
Binary file src/pyams_i18n/resources/img/flags/sl.png has changed
Binary file src/pyams_i18n/resources/img/flags/sma.png has changed
Binary file src/pyams_i18n/resources/img/flags/smj.png has changed
Binary file src/pyams_i18n/resources/img/flags/smn.png has changed
Binary file src/pyams_i18n/resources/img/flags/sms.png has changed
Binary file src/pyams_i18n/resources/img/flags/sq.png has changed
Binary file src/pyams_i18n/resources/img/flags/sr.png has changed
Binary file src/pyams_i18n/resources/img/flags/sv.png has changed
Binary file src/pyams_i18n/resources/img/flags/sw.png has changed
Binary file src/pyams_i18n/resources/img/flags/syr.png has changed
Binary file src/pyams_i18n/resources/img/flags/ta.png has changed
Binary file src/pyams_i18n/resources/img/flags/te.png has changed
Binary file src/pyams_i18n/resources/img/flags/tg.png has changed
Binary file src/pyams_i18n/resources/img/flags/th.png has changed
Binary file src/pyams_i18n/resources/img/flags/tk.png has changed
Binary file src/pyams_i18n/resources/img/flags/tn.png has changed
Binary file src/pyams_i18n/resources/img/flags/tr.png has changed
Binary file src/pyams_i18n/resources/img/flags/tt.png has changed
Binary file src/pyams_i18n/resources/img/flags/ug.png has changed
Binary file src/pyams_i18n/resources/img/flags/uk.png has changed
Binary file src/pyams_i18n/resources/img/flags/ur.png has changed
Binary file src/pyams_i18n/resources/img/flags/uz.png has changed
Binary file src/pyams_i18n/resources/img/flags/vi.png has changed
Binary file src/pyams_i18n/resources/img/flags/wee.png has changed
Binary file src/pyams_i18n/resources/img/flags/wen.png has changed
Binary file src/pyams_i18n/resources/img/flags/wo.png has changed
Binary file src/pyams_i18n/resources/img/flags/xh.png has changed
Binary file src/pyams_i18n/resources/img/flags/yo.png has changed
Binary file src/pyams_i18n/resources/img/flags/zh.png has changed
Binary file src/pyams_i18n/resources/img/flags/zu.png has changed
--- a/src/pyams_i18n/schema.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/schema.py	Wed Jun 17 09:57:04 2015 +0200
@@ -17,12 +17,13 @@
 
 # import interfaces
 from pyams_i18n.interfaces.schema import II18nField, II18nTextLineField, II18nTextField, II18nFileField, II18nImageField, \
-    II18nThumbnailImageField
+    II18nThumbnailImageField, II18nHTMLField
 from zope.schema.interfaces import RequiredMissing
 
 # import packages
 from persistent.mapping import PersistentMapping
 from pyams_file.schema import FileField, ImageField, ThumbnailImageField
+from pyams_utils.schema import HTMLField
 from zope.interface import implementer
 from zope.schema import Dict, TextLine, Text
 
@@ -103,6 +104,20 @@
                                             **kwargs)
 
 
+@implementer(II18nHTMLField)
+class I18nHTMLField(I18nField):
+    """I18n HTML field"""
+
+    def __init__(self, key_type=None, value_type=None, default=None,
+                 value_constraint=None, value_min_length=0, value_max_length=None, **kwargs):
+        super(I18nHTMLField, self).__init__(value_type=HTMLField(constraint=value_constraint,
+                                                                 min_length=value_min_length,
+                                                                 max_length=value_max_length,
+                                                                 default=default,
+                                                                 required=False),
+                                            **kwargs)
+
+
 @implementer(II18nFileField)
 class I18nFileField(I18nField):
     """I18n file field"""
--- a/src/pyams_i18n/vocabulary.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/vocabulary.py	Wed Jun 17 09:57:04 2015 +0200
@@ -52,11 +52,16 @@
 
     def __init__(self, context):
         terms = []
+        translate = check_request().localizer.translate
+        negotiator = query_utility(INegotiator)
+        if negotiator is not None:
+            terms.append(SimpleTerm(negotiator.server_language,
+                                    title=translate(BASE_LANGUAGES.get(negotiator.server_language))))
         manager = get_parent(context, II18nManager)
         if manager is not None:
-            translate = check_request().localizer.translate
             for lang in manager.languages:
-                terms.append(SimpleTerm(lang, title=translate(BASE_LANGUAGES.get(lang) or _("<unknown>"))))
+                if (negotiator is None) or (lang != negotiator.server_language):
+                    terms.append(SimpleTerm(lang, title=translate(BASE_LANGUAGES.get(lang) or _("<unknown>"))))
         super(I18nContentLanguages, self).__init__(terms)
 
 getVocabularyRegistry().register('PyAMS content languages', I18nContentLanguages)
--- a/src/pyams_i18n/widget/__init__.py	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/widget/__init__.py	Wed Jun 17 09:57:04 2015 +0200
@@ -18,9 +18,10 @@
 # import interfaces
 from pyams_form.interfaces.form import IFormLayer
 from pyams_i18n.interfaces import II18nManager, INegotiator
-from pyams_i18n.interfaces.schema import II18nField, II18nTextLineField, II18nTextField, II18nFileField
-from pyams_i18n.interfaces.widget import II18nWidget, II18nTextLineWidget, II18nTextWidget, II18nFileWidget
-from z3c.form.interfaces import IDataConverter, IFieldWidget, NO_VALUE
+from pyams_i18n.interfaces.schema import II18nField, II18nTextLineField, II18nTextField, II18nFileField, II18nHTMLField
+from pyams_i18n.interfaces.widget import II18nWidget, II18nTextLineWidget, II18nTextWidget, II18nFileWidget, \
+    II18nHTMLWidget
+from z3c.form.interfaces import IDataConverter, IFieldWidget, NO_VALUE, IFormAware, IValidator, IErrorViewSnippet
 
 # import packages
 from pyams_form.widget import widgettemplate_config
@@ -32,7 +33,8 @@
 from z3c.form.converter import BaseDataConverter
 from z3c.form.util import expandPrefix
 from z3c.form.widget import Widget, FieldWidget
-from zope.interface import implementer_only
+from zope.interface import implementer_only, alsoProvides
+from zope.schema import ValidationError
 
 
 @adapter_config(context=(II18nField, II18nWidget), provides=IDataConverter)
@@ -46,6 +48,8 @@
         # I18n widget is using a dict where each key is a lang
         # and each value is matching widget value
         result = {}
+        if value is None:
+            return result
         registry = self.widget.request.registry
         for lang, val in value.items():
             converter = registry.queryMultiAdapter((self.field.value_type, self.widget.get_widget(lang)),
@@ -81,23 +85,27 @@
             langs.append(negotiator.server_language)
         manager = get_parent(self.context, II18nManager)
         if manager is not None:
-            langs.extend(sorted(filter(lambda x: x not in langs, manager.languages)))
+            langs.extend(sorted(filter(lambda x: x not in langs, manager.languages or ())))
         elif negotiator is not None:
-            langs.extend(sorted(filter(lambda x: x not in langs, negotiator.offered_languages)))
+            langs.extend(sorted(filter(lambda x: x not in langs, negotiator.offered_languages or ())))
         else:
             langs.append('en')
         return langs
 
     def update(self):
+        registry = self.request.registry
         self.widgets = {}
         for lang in self.langs:
-            widget = self.request.registry.queryMultiAdapter((self.field.value_type, self.request), IFieldWidget)
+            widget = registry.queryMultiAdapter((self.field.value_type, self.request), IFieldWidget)
             if widget is not None:
                 prefix = expandPrefix(self.form.prefix) + expandPrefix(self.form.widgets.prefix) + expandPrefix(lang)
                 name = self.field.value_type.__name__ = self.field.__name__
+                widget.mode = self.mode
                 widget.name = prefix + name
                 widget.id = widget.name.replace('.', '-')
-                widget.form = self.form
+                if IFormAware.providedBy(self):
+                    widget.form = self.form
+                    alsoProvides(widget, IFormAware)
                 widget.field = self.field.value_type
                 widget.context = self.context
                 widget.ignoreContext = self.ignoreContext
@@ -106,11 +114,30 @@
                 widget.update()
             self.widgets[lang] = widget
         super(I18nWidget, self).update()
+        for lang in self.langs:
+            widget = self.widgets[lang]
+            value = (self.value or {}).get(lang, NO_VALUE)
+            if value is not NO_VALUE:
+                try:
+                    converter = IDataConverter(widget)
+                    field_value = converter.toFieldValue(value)
+                    registry.getMultiAdapter((self.context, self.request, self.form, widget.field, widget),
+                                             IValidator).validate(field_value)
+                    widget.value = converter.toWidgetValue(field_value)
+                except (ValidationError, ValueError) as error:
+                    view = registry.getMultiAdapter((error, self.request, widget, widget.field, self.form,
+                                                     self.context), IErrorViewSnippet)
+                    view.update()
+                    widget.error = view
+                    widget.value = value
 
     def extract(self, default=NO_VALUE):
         result = {}
-        [result.setdefault(lang, self.widgets[lang].extract(default)) for lang in self.widgets.keys()]
-        return result
+        [result.setdefault(lang, self.widgets[lang].extract(default)) for lang in self.langs]
+        for value in result.values():
+            if value is not NO_VALUE:
+                return result
+        return NO_VALUE
     
     def get_widget(self, lang):
         return self.widgets.get(lang)
@@ -141,6 +168,17 @@
     return FieldWidget(field, I18nTextWidget(request))
 
 
+@implementer_only(II18nHTMLWidget)
+class I18nHTMLWidget(I18nWidget):
+    """I18n HTML widget"""
+
+
+@adapter_config(context=(II18nHTMLField, IFormLayer), provides=IFieldWidget)
+def I18nHTMLFieldWidget(field, request):
+    """I18n HTML field widget factory"""
+    return FieldWidget(field, I18nHTMLWidget(request))
+
+
 @implementer_only(II18nFileWidget)
 class I18nFileWidget(I18nWidget):
     """I18n file widget"""
--- a/src/pyams_i18n/widget/templates/i18n-input.pt	Wed May 20 12:25:29 2015 +0200
+++ b/src/pyams_i18n/widget/templates/i18n-input.pt	Wed Jun 17 09:57:04 2015 +0200
@@ -20,7 +20,7 @@
 				</li>
 			</tal:loop>
 		</ul>
-		<div class="tab-content bordered nohover">
+		<div class="tab-content i18n-content bordered nohover">
 			<tal:loop repeat="lang langs">
 				<div tal:define="active python:'active' if repeat['lang'].start() else ''"
 					 tal:attributes="class string:clearfix tab-pane ${active} fade in padding-5;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/pyams_i18n/zmi/language.py	Wed Jun 17 09:57:04 2015 +0200
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
+# All Rights Reserved.
+#
+# This software is subject to the provisions of the Zope Public License,
+# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
+# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
+# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
+# FOR A PARTICULAR PURPOSE.
+#
+from pyramid.view import view_config
+from pyams_form.form import AJAXEditForm
+from pyams_i18n.interfaces import II18nManager
+from pyams_pagelet.pagelet import pagelet_config
+from pyams_skin.layer import IPyAMSLayer
+from pyams_skin.viewlet.menu import MenuItem
+from pyams_viewlet.viewlet import viewlet_config
+from pyams_zmi.form import AdminDialogEditForm
+from pyams_zmi.interfaces.menu import IPropertiesMenu
+from pyams_zmi.layer import IAdminLayer
+
+__docformat__ = 'restructuredtext'
+
+
+# import standard library
+
+# import interfaces
+
+# import packages
+from z3c.form import field
+
+from pyams_i18n import _
+
+
+#
+# Content languages
+#
+
+@viewlet_config(name='languages.menu', context=II18nManager, layer=IAdminLayer,
+                manager=IPropertiesMenu, permission='system.view', weight=11)
+class I18nManagerLanguagesMenu(MenuItem):
+    """I18n manager languages menu"""
+
+    label = _("Languages")
+    icon_class = 'fa-flag'
+
+    url = 'languages.html'
+    modal_target = True
+
+
+@pagelet_config(name='languages.html', context=II18nManager, layer=IPyAMSLayer, permission='system.view')
+class I18nManagerLanguagesEditForm(AdminDialogEditForm):
+    """I18n manager languages edit form"""
+
+    legend = _("Content languages")
+
+    fields = field.Fields(II18nManager)
+    ajax_handler = 'languages.json'
+    edit_permission = 'system.view'
+
+
+@view_config(name='languages.json', context=II18nManager, request_type=IPyAMSLayer,
+             permission='system.view', renderer='json', xhr=True)
+class I18nManagerLanguagesAJAXEditForm(AJAXEditForm, I18nManagerLanguagesEditForm):
+    """I18n manager languages edit form, JSON renderer"""