dims 01/06/01 09:15:05 Modified: . build.xml src/org/apache/cocoon/acting LangSelect.java src/org/apache/cocoon/transformation I18nTransformer2.java webapp/i18n simple.xsp sitemap.xmap webapp/i18n/translations simple_dict.xml xdocs i18n.xml Log: Patch(es) for I18nTransformer from Konstantin Piroumian ([EMAIL PROTECTED]) Revision Changes Path 1.6 +1 -0 xml-cocoon2/build.xml Index: build.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/build.xml,v retrieving revision 1.5 retrieving revision 1.6 diff -u -r1.5 -r1.6 --- build.xml 2001/06/01 11:44:20 1.5 +++ build.xml 2001/06/01 16:14:52 1.6 @@ -169,6 +169,7 @@ <property name="site" value="../xml-site/targets/${name}"/> + <filter token="Name" value="${Name}"/> <filter token="name" value="${fullname}"/> <filter token="year" value="${year}"/> <filter token="version" value="${version}"/> 1.3 +115 -15 xml-cocoon2/src/org/apache/cocoon/acting/LangSelect.java Index: LangSelect.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/acting/LangSelect.java,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- LangSelect.java 2001/05/22 14:31:05 1.2 +++ LangSelect.java 2001/06/01 16:14:55 1.3 @@ -15,10 +15,14 @@ import java.util.Locale; import java.util.Map; import org.apache.avalon.framework.parameters.Parameters; +import org.apache.avalon.framework.configuration.Configurable; +import org.apache.avalon.framework.configuration.Configuration; +import org.apache.avalon.framework.configuration.ConfigurationException; import org.apache.cocoon.Constants; import org.apache.cocoon.acting.Action; import org.apache.cocoon.environment.Cookie; import org.apache.cocoon.environment.Request; +import org.apache.cocoon.environment.Response; import org.apache.cocoon.environment.Session; import org.apache.cocoon.environment.SourceResolver; @@ -46,14 +50,71 @@ * * * Creation date: (3.11.2000 14:32:19) + * Modification date: (29.05.2001 0:30:01) + * @author: <a href="mailto:[EMAIL PROTECTED]">Konstantin Piroumian</a> * @author: <a href="mailto:[EMAIL PROTECTED]">Lassi Immonen</a> */ -public class LangSelect extends java.lang.Object implements Action { +public class LangSelect extends java.lang.Object implements Action, Configurable { + + /** + * The default language: en (English). + */ private final static String DEFAULT_LANG = "en"; + /** + * The name that will be used as a request param or a cookie name. + */ + private final static String PARAM_LANG = "lang"; + + /** + * Should we store the lang in request. + * Default is off. + */ + private boolean storeInRequest = false; + /** + * Should we store the lang in session, if one is available. + * Default is off. + */ + private boolean storeInSession = false; /** + * Should we create a session to store the lang if it's not created yet. + * Not used if use-session is false. + * Default is off. + */ + private boolean createSession = false; + + /** + * Should we add a cookie with the lang. + */ + private boolean storeInCookie = false; + + /** + * Configure this action. + */ + public void configure(Configuration conf) + throws ConfigurationException { + if (conf != null) { + + Configuration child = conf.getChild("store-in-request"); + this.storeInRequest = child.getValueAsBoolean(false); + + child = conf.getChild("create-session"); + this.createSession = child.getValueAsBoolean(false); +// getLogger().debug("Create session is " + this.createSession + " for " + this); + + child = conf.getChild("store-in-session"); + this.storeInSession = child.getValueAsBoolean(false); +// getLogger().debug("Store in session is " + this.storeInSession + " for " + this); + + child = conf.getChild("store-in-cookie"); + this.storeInCookie = child.getValueAsBoolean(false); +// getLogger().debug("Use cookie is " + this.storeInCookie + " for " + this); + } + } + + /** * Selects language if it is not set already in objectModel * Puts lang parameter to session and to objectModel * if it is not already there. @@ -63,30 +124,27 @@ String lang; - if (objectModel.containsKey("lang")) { - lang = (String)(objectModel.get("lang")); + if (objectModel.containsKey(PARAM_LANG)) { + lang = (String)(objectModel.get(PARAM_LANG)); } else { lang = getLang(objectModel, par); - objectModel.put("lang", lang); + objectModel.put(PARAM_LANG, lang); } + // Creating session to store the language code Request request = (Request)(objectModel.get(Constants.REQUEST_OBJECT)); + request.getSession(createSession); - Session session = request.getSession(); - if (session != null) { - if (session.getAttribute("lang") == null) { - session.setAttribute("lang", lang); - } + if (storeInSession || storeInCookie) { + storeLang(objectModel, lang); } Map m = new HashMap(1); - m.put("lang", lang); + m.put(PARAM_LANG, lang); return m; } - - /** * Returns two character language code by checking environment in following order * <ol> @@ -119,12 +177,12 @@ String lang = null; - lang = request.getParameter("lang"); + lang = request.getParameter(PARAM_LANG); if (lang == null) { Session session = request.getSession(false); if (session != null) { - Object session_lang = session.getAttribute("lang"); + Object session_lang = session.getAttribute(PARAM_LANG); if (session_lang != null) { lang = session_lang.toString(); } @@ -137,7 +195,7 @@ if (cookies != null) { for ( int i = 0; i < cookies.length; i++) { Cookie cookie = cookies[i]; - if (cookie.getName().equals("lang")) { + if (cookie.getName().equals(PARAM_LANG)) { lang = cookie.getValue(); } } @@ -171,5 +229,47 @@ } } return lang; + } + + /** + * Stores language code in the session or a cookie + * @param objectModel java.util.Map + * @param lang String The language code to store + */ + public void storeLang(Map objectModel, String lang) throws Exception { + + if (lang == null) { + lang = DEFAULT_LANG; + } + + Request request = + (Request)(objectModel.get(Constants.REQUEST_OBJECT)); + + if (storeInRequest) { + request.setAttribute(PARAM_LANG, lang); + } + + if (storeInSession) { + // We do not create session here to keep this method static. + // Session must be created outside if needed. + Session session = request.getSession(false); + // Try to store in a session. + if (session != null) { + synchronized (session) { + session.setAttribute(PARAM_LANG, lang); + } + } + else { + throw new Exception("LangSelect: session is not available."); + } + } + + if (storeInCookie) { + Response response = + (Response)(objectModel.get(Constants.RESPONSE_OBJECT)); + + Cookie langCookie = response.createCookie(PARAM_LANG, lang); + response.addCookie(langCookie); + } } } 1.9 +129 -46 xml-cocoon2/src/org/apache/cocoon/transformation/I18nTransformer2.java Index: I18nTransformer2.java =================================================================== RCS file: /home/cvs/xml-cocoon2/src/org/apache/cocoon/transformation/I18nTransformer2.java,v retrieving revision 1.8 retrieving revision 1.9 diff -u -r1.8 -r1.9 --- I18nTransformer2.java 2001/05/31 17:39:00 1.8 +++ I18nTransformer2.java 2001/06/01 16:14:57 1.9 @@ -30,16 +30,13 @@ import org.xml.sax.helpers.AttributesImpl; import org.xml.sax.helpers.DefaultHandler; -import java.io.InputStream; -import java.io.BufferedInputStream; import java.io.IOException; -import java.io.Reader; -import java.io.BufferedReader; + import java.util.Map; import java.util.HashMap; -//import java.util.Hashtable; import java.util.StringTokenizer; import java.util.ArrayList; +import java.util.Locale; import java.text.MessageFormat; @@ -91,54 +88,60 @@ * </translations><br> * </p> * <p> - * - *TODO -Add i18n:key support.<br> - * -Caching dictionaries in memory.<br> - * -Implementing Infozone group I18nProcessors param substitutions - * where you can enter params in the translated text. - * * + * @todo Caching dictionaries in memory.<br> + * @todo Date and Number i18n.<br> + * @todo Multiple dictionary support. <br> +* * @author <a href="mailto:[EMAIL PROTECTED]">Konstantin Piroumian</a> * @author <a href="mailto:[EMAIL PROTECTED]">Lassi Immonen</a> */ -public class I18nTransformer2 extends AbstractTransformer implements Composable, Poolable { +public class I18nTransformer2 extends AbstractTransformer +implements Composable, Poolable { protected ComponentManager manager; + /** + * The parsed dictionary data. + */ public Map dictionary; - //apache.org/cocoon/i18n/2.0"; + /** + * The namespace for i18n is "http://apache.org/cocoon/i18n/2.0" + */ public final static String I18N_NAMESPACE_URI = "http://apache.org/cocoon/i18n/2.0"; - public final static String I18N_ELEMENT = "i18n"; // // Dictionary elements and attributes // public final static String I18N_DICTIONARY_ELEMENT = "dictionary"; public final static String I18N_ENTRY_ELEMENT = "entry"; -// public final static String I18N_ELEMENT_KEY_ATTRIBUTE = "key"; public final static String I18N_KEY_ELEMENT = "key"; public final static String I18N_TRANSLATION_ELEMENT = "translation"; + // + // Text elements and attributes + // public final static String I18N_LANG = "lang"; public final static String I18N_KEY_ATTRIBUTE = "key"; public final static String I18N_ATTR_ATTRIBUTE = "attr"; public final static String I18N_TEXT_ELEMENT = "text"; public final static String I18N_TRANSLATE_ELEMENT = "translate"; public final static String I18N_PARAM_ELEMENT = "param"; + public final static String I18N_DATE_ELEMENT = "date"; + public final static String I18N_NUMBER_ELEMENT = "number"; // States of the transformer private final static int STATE_OUTSIDE = 0; private final static int STATE_INSIDE_TEXT = 1; private final static int STATE_INSIDE_PARAM = 2; private final static int STATE_INSIDE_TRANSLATE = 3; - private final static int STATE_INSIDE_PARAM_TEXT = 4; +// private final static int STATE_INSIDE_PARAM_TEXT = 4; private final static int STATE_INSIDE_TRANSLATE_TEXT = 5; private final static int STATE_TRANSLATE_KEY = 6; private final static int STATE_TRANSLATE_TEXT_KEY = 7; - // If true - then text part of the element will be translated. /** * Current state of the transformer. */ @@ -151,64 +154,111 @@ /** * The i18n:key attribute is stored for the current element. + * If no translation found for the key then the character + * data of element is used as default value. */ - protected String current_key = null; + private String current_key = null; /** * Translated text inside the i18n:text element. */ - protected String translated_text = null; + private String translated_text = null; /** - * If no translation found for the key then the character - * data is used as default value. - */ -// protected String default_value = null; - - /** * Translated text, ready for param substitution. */ - protected String substitute_text = null; + private String substitute_text = null; /** * Current parameter value (translated or not) */ - protected String param_value = null; + private String param_value = null; /** - * @todo - * i18n:params are stored in a HashMap for named substitutions. + * @todo Named parameter substitution. + * i18n:params are stored in a HashMap for named substitutions, <br> + * name attribute is used as a key.<br> + * <i>MessageFormat class does not support named params. + * Some kind of mapping (name to index) must be used.</i> */ - protected HashMap namedParams = null; + private HashMap namedParams = null; /** * i18n:params are stored for index substitutions. */ - protected ArrayList indexedParams = new ArrayList(); + private ArrayList indexedParams = new ArrayList(); + /** + * Message formatter for param substitution. + */ + private MessageFormat formatter = new MessageFormat(""); /** * Current language id. + */ + private String lang; + + /** + * @todo Locale full support. + * Do we really need it? We can use a combination of + * language code and country code (en_US) instead. <br> + * Also, different encodings can be specified: ru_RU_koi8 */ - protected String lang; + private Locale locale; + public void setLang(String lang) { + this.lang = lang; + } + + public void setLocale(Locale locale) { + this.locale = locale; + } + /** * Uses <code>org.apache.cocoon.acting.LangSelect.getLang()</code> * to get language user has selected. First it checks is lang set in * objectModel. */ - public void setup(SourceResolver resolver, Map objectModel, String source, Parameters parameters) throws ProcessingException, SAXException, IOException { - lang = (String)(objectModel.get("lang")); + // Set current language and locale + String lang = (String)(objectModel.get("lang")); if (lang == null) { lang = LangSelect.getLang(objectModel, parameters); } + setLang(lang); + + Locale locale = null; + int ind = lang.indexOf("_"); + if (ind != -1) { + int lind = lang.lastIndexOf("_"); + if (ind == lind) { + locale = new Locale(lang.substring(0, ind - 1), + lang.substring(ind + 1)); + } + else { + locale = new Locale(lang.substring(0, ind - 1), + lang.substring(ind + 1, lind - 1), + lang.substring(lind + 1)); + } + } + else { + locale = new Locale(lang, ""); + } + setLocale(locale); + formatter.setLocale(locale); + // FIXME (KP) + // We need another way of specifying dictionaries, e.g. + // <parameter name="dictionary.en" src="dict.xml" /> + // <parameter name="dictionary.de" src="dict_de.xml" /> + // etc. String translations_file = parameters.getParameter("src", null); + // FIXME (KP) + // Add multiple dictionary support! initialiseDictionary(resolver.resolve(translations_file)); } @@ -217,7 +267,6 @@ this.manager = manager; } - public void startElement(String uri, String name, String raw, Attributes attr) throws SAXException { @@ -255,16 +304,34 @@ // My own content handlers - private void startI18NElement(String name, Attributes attr) { + private void startI18NElement(String name, Attributes attr) + throws SAXException { + this.getLogger().debug("Start i18n element: " + name); if (I18N_TEXT_ELEMENT.equals(name)) { + if (current_state != STATE_OUTSIDE + && current_state != STATE_INSIDE_PARAM + && current_state != STATE_INSIDE_TRANSLATE) { + throw new SAXException(this.getClass().getName() + + ": nested i18n:text elements are not allowed. Current state: " + current_state); + } prev_state = current_state; current_state = STATE_INSIDE_TEXT; current_key = attr.getValue(I18N_NAMESPACE_URI, I18N_KEY_ATTRIBUTE); } else if (I18N_TRANSLATE_ELEMENT.equals(name)) { + if (current_state != STATE_OUTSIDE) { +// throw new SAXException(this.getClass().getName() +// + ": i18n:translate element must be used " +// + "outside of other i18n elements. Current state: " + current_state); + } current_state = STATE_INSIDE_TRANSLATE; } else if (I18N_PARAM_ELEMENT.equals(name)) { + if (current_state != STATE_INSIDE_TRANSLATE) { + throw new SAXException(this.getClass().getName() + + ": i18n:param element can be used only inside " + + "i18n:translate element. Current state: " + current_state); + } current_state = STATE_INSIDE_PARAM; } } @@ -289,7 +356,15 @@ } + /* + */ private String stripWhitespace(String s) { + // FIXME (KP) Must be a better way to determine whitespace-only nodes. + // trim() function does not remove spaces if string does not contain + // anything else. +// if (s == null) { +// return null; +// } String result = (s + "!").trim(); return result.substring(0, result.length() - 1); } @@ -299,7 +374,8 @@ String text2translate = new String(ch, start, len); text2translate = stripWhitespace(text2translate); - if (text2translate.length() == 0) { + if (text2translate == null || text2translate.length() == 0) { +// this.getLogger().warn(this.getClass().getName() + ": null i18n text found"); return; } @@ -370,13 +446,13 @@ temp_attr.setValue(attr_index, result); } else { - getLogger().warn("translation not found for attribute " + attr_name - + " in element: " + name); + getLogger().warn("translation not found for attribute " + + attr_name + " in element: " + name); } } else { - getLogger().warn("i18n attribute " + attr_name - + " not found in element: " + name); + getLogger().warn("i18n attribute '" + attr_name + + "' not found in element: " + name); } } return temp_attr; @@ -390,8 +466,15 @@ switch (prev_state) { case STATE_OUTSIDE: { // simply translate text (key translation already performed) - super.contentHandler.characters(translated_text.toCharArray(), - 0, translated_text.length()); + if (translated_text != null) { + super.contentHandler.characters(translated_text.toCharArray(), + 0, translated_text.length()); + } + else { + // Translation not found. + super.contentHandler.characters("".toCharArray(), + 0, 0); + } break; } case STATE_INSIDE_TRANSLATE: { @@ -424,7 +507,7 @@ String result; if (indexedParams.size() > 0 && substitute_text.length() > 0) { this.getLogger().debug("Text for susbtitution: " + substitute_text); - result = MessageFormat.format(substitute_text, indexedParams.toArray()); + result = formatter.format(substitute_text, indexedParams.toArray()); this.getLogger().debug("Result of susbtitution: " + result); } else { @@ -516,7 +599,7 @@ try { parser = (Parser)(manager.lookup(Roles.PARSER)); - InputSource input = inputSource.getInputSource(); + InputSource input = new InputSource(inputSource.getInputStream()); // How this could be cached? this.dictionary = new HashMap(); @@ -536,7 +619,7 @@ getLogger().error("Error in initialiseDictionary", e); throw new SAXException("ComponentException in initialiseDictionary"); } finally { - if(parser != null) this.manager.release(parser); + if(parser != null) this.manager.release((Component) parser); } } } 1.4 +2 -2 xml-cocoon2/webapp/i18n/simple.xsp Index: simple.xsp =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/simple.xsp,v retrieving revision 1.3 retrieving revision 1.4 diff -u -r1.3 -r1.4 --- simple.xsp 2001/05/23 12:32:20 1.3 +++ simple.xsp 2001/06/01 16:14:59 1.4 @@ -18,9 +18,9 @@ } Locale loc = null; - String lang = <xsp-request:get-parameter name="lang"/>; + String lang = <xsp-request:get-attribute name="lang"/>; if (lang != null) { - request.setAttribute("lang", lang); + // request.setAttribute("lang", lang); loc = new Locale(lang, lang.toUpperCase()); } 1.5 +17 -4 xml-cocoon2/webapp/i18n/sitemap.xmap Index: sitemap.xmap =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/sitemap.xmap,v retrieving revision 1.4 retrieving revision 1.5 diff -u -r1.4 -r1.5 --- sitemap.xmap 2001/05/22 16:21:16 1.4 +++ sitemap.xmap 2001/06/01 16:14:59 1.5 @@ -19,23 +19,36 @@ <map:matchers default="wildcard"> <map:matcher name="wildcard" src="org.apache.cocoon.matching.WildcardURIMatcherFactory"/> </map:matchers> + <map:actions> + <map:action name="lang-select" src="org.apache.cocoon.acting.LangSelect"> + <store-in-session>true</store-in-session> + <create-session>true</create-session> + <store-in-cookie>true</store-in-cookie> + <store-in-request>true</store-in-request> + </map:action> + </map:actions> + </map:components> <!-- =========================== Pipelines ================================= --> <map:pipelines> <map:pipeline> <map:match pattern="**.xml"> - <map:generate src="{1}.xml"/> + <map:act type="lang-select"> + <map:generate src="{../1}.xml"/> <map:transform type="i18n"> - <map:parameter name="src" value="translations/{1}_dict.xml"/> + <map:parameter name="src" value="translations/{../1}_dict.xml"/> </map:transform> + </map:act> <map:transform src="simple.xsl"/> <map:serialize/> </map:match> <map:match pattern="**.xsp"> - <map:generate type="serverpages" src="{1}.xsp"/> + <map:act type="lang-select"> + <map:generate type="serverpages" src="{../1}.xsp"/> <map:transform type="i18n"> - <map:parameter name="src" value="translations/{1}_dict.xml"/> + <map:parameter name="src" value="translations/{../1}_dict.xml"/> </map:transform> + </map:act> <map:transform src="simple.xsl"/> <map:serialize/> </map:match> 1.3 +268 -268 xml-cocoon2/webapp/i18n/translations/simple_dict.xml Index: simple_dict.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/translations/simple_dict.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- simple_dict.xml 2001/05/18 14:05:36 1.2 +++ simple_dict.xml 2001/06/01 16:15:01 1.3 @@ -1,268 +1,268 @@ -<?xml version="1.0" encoding="UTF-8"?> -<translations> -<!-- - Languages: - en - English - ru - Russian - de - German - pl - Polish (thanks to Krzysztof Zieliński) - es - Spanish - hy - Armenian. ---> - - <!-- Language links --> - <entry> - <key>count_title</key> - <translation lang="en">This page was accessed {0} times. Last at: {1}.</translation> - <translation lang="ru">На эту страницу заходили {0} раз(а). В последний раз {1}.</translation> - <translation lang="de">Auf diese Seite kamen {0} Des males vorbei. In das letzte {1}.</translation> - <translation lang="pl">Ta strona była pobierana {0} razy. Ostatnio {1}</translation> - <translation lang="es">Esta página fue tenida acceso {0} veces. Pasado en: {1}.</translation> - <translation lang="hy">²Ûë ¿çÁ ³Ûó»É»É »Ý {0} ³Ý·³Ù. ì»ñçÇÝÁ {1}.</translation> - </entry> - <entry> - <key>a_key</key> - <translation lang="en">This is a key value.</translation> - <translation lang="ru">Это значение по ключу.</translation> - <translation lang="de">Diese Bedeutung nach dem Schlüssel.</translation> - <translation lang="pl">To jest klucz.</translation> - <translation lang="es">Esto es un valor clave.</translation> - <translation lang="hy">ê³ µ³Ý³ÉÇÇ ³éÅ»ùÝ ¿£</translation> - </entry> - <entry> - <key>lang_id1</key> - <translation lang="en">ru</translation> - <translation lang="ru">en</translation> - <translation lang="de">en</translation> - <translation lang="pl">en</translation> - <translation lang="es">en</translation> - <translation lang="hy">en</translation> - </entry> - <entry> - <key>lang_id2</key> - <translation lang="en">de</translation> - <translation lang="ru">de</translation> - <translation lang="de">ru</translation> - <translation lang="pl">ru</translation> - <translation lang="es">ru</translation> - <translation lang="hy">ru</translation> - </entry> - <entry> - <key>lang_id3</key> - <translation lang="en">pl</translation> - <translation lang="ru">pl</translation> - <translation lang="de">pl</translation> - <translation lang="pl">de</translation> - <translation lang="es">de</translation> - <translation lang="hy">de</translation> - </entry> - <entry> - <key>lang_id4</key> - <translation lang="en">es</translation> - <translation lang="ru">es</translation> - <translation lang="de">es</translation> - <translation lang="pl">es</translation> - <translation lang="es">pl</translation> - <translation lang="hy">pl</translation> - </entry> - <entry> - <key>lang_id5</key> - <translation lang="en">hy</translation> - <translation lang="ru">hy</translation> - <translation lang="de">hy</translation> - <translation lang="pl">hy</translation> - <translation lang="es">hy</translation> - <translation lang="hy">es</translation> - </entry> - <!-- current language --> - <entry> - <key>language</key> - <translation lang="en">English</translation> - <translation lang="ru">Русский</translation> - <translation lang="de">Deutsch</translation> - <translation lang="pl">Polski</translation> - <translation lang="es">Español</translation> - <translation lang="hy">гۻñ»Ý</translation> - </entry> - <entry> - <key>language1</key> - <translation lang="en">Russian</translation> - <translation lang="ru">Английский</translation> - <translation lang="de">Englische</translation> - <translation lang="pl">Angielski</translation> - <translation lang="es">Inglés</translation> - <translation lang="hy">²Ý·É»ñ»Ý</translation> - </entry> - <entry> - <key>language2</key> - <translation lang="en">German</translation> - <translation lang="ru">Немецкий</translation> - <translation lang="de">Russe</translation> - <translation lang="pl">Rosyjski</translation> - <translation lang="es">Ruso</translation> - <translation lang="hy">èáõë»ñ»Ý</translation> - </entry> - <entry> - <key>language3</key> - <translation lang="en">Polish</translation> - <translation lang="ru">Польский</translation> - <translation lang="de">Polnisch</translation> - <translation lang="pl">Niemiecki</translation> - <translation lang="es">Alemán</translation> - <translation lang="hy">¶»ñٳݻñ»Ý</translation> - </entry> - <entry> - <key>language4</key> - <translation lang="en">Spanish</translation> - <translation lang="ru">Испанский</translation> - <translation lang="de">Spanisch</translation> - <translation lang="pl">Hiszpañski</translation> - <translation lang="es">Polaco</translation> - <translation lang="hy">Ȼѻñ»Ý</translation> - </entry> - <entry> - <key>language5</key> - <translation lang="en">Armenian</translation> - <translation lang="ru">Армянский</translation> - <translation lang="de">Armenier</translation> - <translation lang="pl">Armeñski</translation> - <translation lang="es">Armenio</translation> - <translation lang="hy">Æëå³Ý»ñ»Ý</translation> - </entry> - <entry> - <key>Hello, internationalization!</key> - <translation lang="en">Hello, internationalization!</translation> - <translation lang="ru">Привет, многоязычность!</translation> - <translation lang="de">Hallo, die Internationalisierung!</translation> - <translation lang="pl">Witam, oto przykład wielojęzycznej strony!</translation> - <translation lang="es">¡¡Hola!, internacionalización!</translation> - <translation lang="hy">´³ñ¢°, ÇÝï»ñݳóÛáݳÉáõÃÛáõÝ£</translation> - </entry> - <entry> - <key>Documentation link:</key> - <translation lang="en">See i18n documentation for details:</translation> - <translation lang="ru">Для дополнительной информации по i18n смотри:</translation> - <translation lang="de">Sieh i18n Dokumentation für Details:</translation> - <translation lang="pl">Widzą i18n dokumentacja dla szczegółów:</translation> - <translation lang="es">Visto la documentación i18n para detalles:</translation> - <translation lang="hy">سÝñ³Ù³ë µ³ó³ïñáõÃÛ³Ý Ñ³Ù³ñ ݳÇñª</translation> - </entry> - <entry> - <key>first</key> - <translation lang="en">First</translation> - <translation lang="ru">Первый</translation> - <translation lang="de">Ersten</translation> - <translation lang="pl">Pierwszy</translation> - <translation lang="es">Primero</translation> - <translation lang="hy">²é³çÇÝ</translation> - </entry> - <entry> - <key>second</key> - <translation lang="en">Second</translation> - <translation lang="ru">Второй</translation> - <translation lang="de">Zwiete</translation> - <translation lang="pl">Drugi</translation> - <translation lang="es">Segundo</translation> - <translation lang="hy">ºñÏñáñ¹</translation> - </entry> - <entry> - <key>third</key> - <translation lang="en">Third</translation> - <translation lang="ru">Третий</translation> - <translation lang="de">Dritten</translation> - <translation lang="pl">Trzeci</translation> - <translation lang="es">Tercio</translation> - <translation lang="hy">ºññáñ¹</translation> - </entry> - <entry> - <key>forth</key> - <translation lang="en">Forth</translation> - <translation lang="ru">Четвертый</translation> - <translation lang="de">Vierten</translation> - <translation lang="pl">Czwarty</translation> - <translation lang="es">En adelante</translation> - <translation lang="hy">¼áñáñ¹</translation> - </entry> - <entry> - <key>article</key> - <translation lang="en">Article</translation> - <translation lang="ru">Статья</translation> - <translation lang="de">Artikel</translation> - <translation lang="pl">Artykuł</translation> - <translation lang="es">Artículo</translation> - <translation lang="hy">Ðá¹í³Í</translation> - </entry> - <entry> - <key>article_text1</key> - <translation lang="en">This is a i18n paragraph.</translation> - <translation lang="ru">Это интернационализированный абзац.</translation> - <translation lang="de">Es i18n den Absatz.</translation> - <translation lang="pl">To jest paragraf w i18n.</translation> - <translation lang="es">Esto es un párrafo i18n.</translation> - <translation lang="hy">ê³ ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿£</translation> - </entry> - <entry> - <key>article_text2</key> - <translation lang="en">This is another i18n paragraph and is also a cool one.</translation> - <translation lang="ru">Это тоже интернационализированный абзац и такой же классный.</translation> - <translation lang="de">Es auch i18n den Absatz und solcher cool.</translation> - <translation lang="pl">To jest następny paragraf w i18n i jest takze fajny.</translation> - <translation lang="es">Esto es otro párrafo i18n y es también uno 'cool'.</translation> - <translation lang="hy">ê³ ÙÇ áõñÇß ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿, ¢ ÝáõÛÝ å»ë ó»Ýïñ£</translation> - </entry> - <entry> - <key>copyright</key> - <translation lang="en">Copyright © 2001 Konstantin Piroumian. No rights are reserved.</translation> - <translation lang="ru">Авторские права © 2001 Константин Пирумян. Ничто не защищено.</translation> - <translation lang="de">Die Urheberrechte © 2001 Konstantin Piroumian. Nichts ist geschützt.</translation> - <translation lang="pl">Copyright © 2001 Konstantin Piroumian i Krzysztof Zieliński. Żadne prawa nie są zastrzeżone:)</translation> - <translation lang="es">Copyright © 2001 Konstantin Piroumian. Ningunos derechos son reservados.</translation> - <translation lang="hy">Copyright © 2001 Konstantin Piroumian. àãÇÝã ãÇ å³Ñå³Ýí³Í£</translation> - </entry> - <entry> - <key>Hello, {0}! Glad to see you!</key> - <translation lang="en">Hello, {0}! Glad to see you!</translation> - <translation lang="ru">Привет, {0}! Рад тебя видеть!</translation> - <translation lang="de">Hallo, {0}! Ist dich froh, zu sehen!</translation> - <translation lang="pl">Witam, {0}! Miło Cię widzieć!</translation> - <translation lang="es">¡¡Hola!, {0}! ¡Alegre de verle!</translation> - <translation lang="hy">´³ñ¢¯ {0}: àõñ³Ë »Ù ù»½ ï»ëݻɣ</translation> - </entry> - <entry> - <key>Kot</key> - <translation lang="en">Tomcat</translation> - <translation lang="ru">Кот</translation> - <translation lang="de">Der Kater</translation> - <translation lang="pl">Tomcat</translation> - <translation lang="es">Gato</translation> - <translation lang="hy">γïáõ</translation> - </entry> - <entry> - <key>none</key> - <translation lang="en">None</translation> - <translation lang="ru">Никто</translation> - <translation lang="de">Niemand</translation> - <translation lang="pl">Nic</translation> - <translation lang="es">Ninguno</translation> - <translation lang="hy">àã áù</translation> - </entry> - <entry> - <key>one</key> - <translation lang="en">one</translation> - <translation lang="ru">раз</translation> - <translation lang="de">einen</translation> - <translation lang="pl">raz</translation> - <translation lang="es">un</translation> - <translation lang="hy">Ù»Ï</translation> - </entry> - <entry> - <key>two</key> - <translation lang="en">two</translation> - <translation lang="ru">два</translation> - <translation lang="de">zwei</translation> - <translation lang="pl">dwa</translation> - <translation lang="es">dos</translation> - <translation lang="hy">»ñÏáõë</translation> - </entry> -</translations> - +<?xml version="1.0" encoding="UTF-8"?> +<translations> +<!-- + Languages: + en - English + ru - Russian + de - German + pl - Polish (thanks to Krzysztof Zieliński) + es - Spanish + hy - Armenian. +--> + + <!-- Language links --> + <entry> + <key>count_title</key> + <translation lang="en">This page was accessed {0} times. Last at: {1}.</translation> + <translation lang="ru">На эту страницу заходили {0} раз(а). В последний раз {1}.</translation> + <translation lang="de">Auf diese Seite kamen {0} Des males vorbei. In das letzte {1}.</translation> + <translation lang="pl">Ta strona była pobierana {0} razy. Ostatnio {1}</translation> + <translation lang="es">Esta página fue tenida acceso {0} veces. Pasado en: {1}.</translation> + <translation lang="hy">²Ûë ¿çÁ ³Ûó»É»É »Ý {0} ³Ý·³Ù. ì»ñçÇÝÁ {1}.</translation> + </entry> + <entry> + <key>a_key</key> + <translation lang="en">This is a key value.</translation> + <translation lang="ru">Это значение по ключу.</translation> + <translation lang="de">Diese Bedeutung nach dem Schlüssel.</translation> + <translation lang="pl">To jest klucz.</translation> + <translation lang="es">Esto es un valor clave.</translation> + <translation lang="hy">ê³ µ³Ý³ÉÇÇ ³éÅ»ùÝ ¿£</translation> + </entry> + <entry> + <key>lang_id1</key> + <translation lang="en">ru</translation> + <translation lang="ru">en</translation> + <translation lang="de">en</translation> + <translation lang="pl">en</translation> + <translation lang="es">en</translation> + <translation lang="hy">en</translation> + </entry> + <entry> + <key>lang_id2</key> + <translation lang="en">de</translation> + <translation lang="ru">de</translation> + <translation lang="de">ru</translation> + <translation lang="pl">ru</translation> + <translation lang="es">ru</translation> + <translation lang="hy">ru</translation> + </entry> + <entry> + <key>lang_id3</key> + <translation lang="en">pl</translation> + <translation lang="ru">pl</translation> + <translation lang="de">pl</translation> + <translation lang="pl">de</translation> + <translation lang="es">de</translation> + <translation lang="hy">de</translation> + </entry> + <entry> + <key>lang_id4</key> + <translation lang="en">es</translation> + <translation lang="ru">es</translation> + <translation lang="de">es</translation> + <translation lang="pl">es</translation> + <translation lang="es">pl</translation> + <translation lang="hy">pl</translation> + </entry> + <entry> + <key>lang_id5</key> + <translation lang="en">hy</translation> + <translation lang="ru">hy</translation> + <translation lang="de">hy</translation> + <translation lang="pl">hy</translation> + <translation lang="es">hy</translation> + <translation lang="hy">es</translation> + </entry> + <!-- current language --> + <entry> + <key>language</key> + <translation lang="en">English</translation> + <translation lang="ru">Русский</translation> + <translation lang="de">Deutsch</translation> + <translation lang="pl">Polski</translation> + <translation lang="es">Español</translation> + <translation lang="hy">гۻñ»Ý</translation> + </entry> + <entry> + <key>language1</key> + <translation lang="en">Russian</translation> + <translation lang="ru">Английский</translation> + <translation lang="de">Englische</translation> + <translation lang="pl">Angielski</translation> + <translation lang="es">Inglés</translation> + <translation lang="hy">²Ý·É»ñ»Ý</translation> + </entry> + <entry> + <key>language2</key> + <translation lang="en">German</translation> + <translation lang="ru">Немецкий</translation> + <translation lang="de">Russe</translation> + <translation lang="pl">Rosyjski</translation> + <translation lang="es">Ruso</translation> + <translation lang="hy">èáõë»ñ»Ý</translation> + </entry> + <entry> + <key>language3</key> + <translation lang="en">Polish</translation> + <translation lang="ru">Польский</translation> + <translation lang="de">Polnisch</translation> + <translation lang="pl">Niemiecki</translation> + <translation lang="es">Alemán</translation> + <translation lang="hy">¶»ñٳݻñ»Ý</translation> + </entry> + <entry> + <key>language4</key> + <translation lang="en">Spanish</translation> + <translation lang="ru">Испанский</translation> + <translation lang="de">Spanisch</translation> + <translation lang="pl">Hiszpañski</translation> + <translation lang="es">Polaco</translation> + <translation lang="hy">Ȼѻñ»Ý</translation> + </entry> + <entry> + <key>language5</key> + <translation lang="en">Armenian</translation> + <translation lang="ru">Армянский</translation> + <translation lang="de">Armenier</translation> + <translation lang="pl">Armeñski</translation> + <translation lang="es">Armenio</translation> + <translation lang="hy">Æëå³Ý»ñ»Ý</translation> + </entry> + <entry> + <key>Hello, internationalization!</key> + <translation lang="en">Hello, internationalization!</translation> + <translation lang="ru">Привет, многоязычность!</translation> + <translation lang="de">Hallo, die Internationalisierung!</translation> + <translation lang="pl">Witam, oto przykład wielojęzycznej strony!</translation> + <translation lang="es">¡¡Hola!, internacionalización!</translation> + <translation lang="hy">´³ñ¢°, ÇÝï»ñݳóÛáݳÉáõÃÛáõÝ£</translation> + </entry> + <entry> + <key>Documentation link:</key> + <translation lang="en">See i18n documentation for details:</translation> + <translation lang="ru">Для дополнительной информации по i18n смотри:</translation> + <translation lang="de">Sieh i18n Dokumentation für Details:</translation> + <translation lang="pl">Zobacz wiкcej szczegуіуw w dokumentacji I18n:</translation> + <translation lang="es">Visto la documentación i18n para detalles:</translation> + <translation lang="hy">³Ýñ³Ù³ë µ³ó³ïñáõÃÛ³Ý Ñ³Ù³ñ ݳÇñª</translation> + </entry> + <entry> + <key>first</key> + <translation lang="en">First</translation> + <translation lang="ru">Первый</translation> + <translation lang="de">Ersten</translation> + <translation lang="pl">Pierwszy</translation> + <translation lang="es">Primero</translation> + <translation lang="hy">²é³çÇÝ</translation> + </entry> + <entry> + <key>second</key> + <translation lang="en">Second</translation> + <translation lang="ru">Второй</translation> + <translation lang="de">Zwiete</translation> + <translation lang="pl">Drugi</translation> + <translation lang="es">Segundo</translation> + <translation lang="hy">ºñÏñáñ¹</translation> + </entry> + <entry> + <key>third</key> + <translation lang="en">Third</translation> + <translation lang="ru">Третий</translation> + <translation lang="de">Dritten</translation> + <translation lang="pl">Trzeci</translation> + <translation lang="es">Tercio</translation> + <translation lang="hy">ºññáñ¹</translation> + </entry> + <entry> + <key>forth</key> + <translation lang="en">Forth</translation> + <translation lang="ru">Четвертый</translation> + <translation lang="de">Vierten</translation> + <translation lang="pl">Czwarty</translation> + <translation lang="es">En adelante</translation> + <translation lang="hy">¼áñáñ¹</translation> + </entry> + <entry> + <key>article</key> + <translation lang="en">Article</translation> + <translation lang="ru">Статья</translation> + <translation lang="de">Artikel</translation> + <translation lang="pl">Artykuł</translation> + <translation lang="es">Artículo</translation> + <translation lang="hy">Ðá¹í³Í</translation> + </entry> + <entry> + <key>article_text1</key> + <translation lang="en">This is a i18n paragraph.</translation> + <translation lang="ru">Это интернационализированный абзац.</translation> + <translation lang="de">Es i18n den Absatz.</translation> + <translation lang="pl">To jest paragraf w i18n.</translation> + <translation lang="es">Esto es un párrafo i18n.</translation> + <translation lang="hy">ê³ ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿£</translation> + </entry> + <entry> + <key>article_text2</key> + <translation lang="en">This is another i18n paragraph and is also a cool one.</translation> + <translation lang="ru">Это тоже интернационализированный абзац и такой же классный.</translation> + <translation lang="de">Es auch i18n den Absatz und solcher cool.</translation> + <translation lang="pl">To jest następny paragraf w i18n i jest takze fajny.</translation> + <translation lang="es">Esto es otro párrafo i18n y es también uno 'cool'.</translation> + <translation lang="hy">ê³ ÙÇ áõñÇß ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿, ¢ ÝáõÛÝ å»ë ó»Ýïñ£</translation> + </entry> + <entry> + <key>copyright</key> + <translation lang="en">Copyright © 2001 Konstantin Piroumian. No rights are reserved.</translation> + <translation lang="ru">Авторские права © 2001 Константин Пирумян. Ничто не защищено.</translation> + <translation lang="de">Die Urheberrechte © 2001 Konstantin Piroumian. Nichts ist geschützt.</translation> + <translation lang="pl">Copyright © 2001 Konstantin Piroumian i Krzysztof Zieliński. Żadne prawa nie są zastrzeżone:)</translation> + <translation lang="es">Copyright © 2001 Konstantin Piroumian. Ningunos derechos son reservados.</translation> + <translation lang="hy">Copyright © 2001 Konstantin Piroumian. àãÇÝã ãÇ å³Ñå³Ýí³Í£</translation> + </entry> + <entry> + <key>Hello, {0}! Glad to see you!</key> + <translation lang="en">Hello, {0}! Glad to see you!</translation> + <translation lang="ru">Привет, {0}! Рад тебя видеть!</translation> + <translation lang="de">Hallo, {0}! Ist dich froh, zu sehen!</translation> + <translation lang="pl">Witam, {0}! Miło Cię widzieć!</translation> + <translation lang="es">¡¡Hola!, {0}! ¡Alegre de verle!</translation> + <translation lang="hy">´³ñ¢¯ {0}: àõñ³Ë »Ù ù»½ ï»ëݻɣ</translation> + </entry> + <entry> + <key>Kot</key> + <translation lang="en">Tomcat</translation> + <translation lang="ru">Кот</translation> + <translation lang="de">Der Kater</translation> + <translation lang="pl">Tomcat</translation> + <translation lang="es">Gato</translation> + <translation lang="hy">γïáõ</translation> + </entry> + <entry> + <key>none</key> + <translation lang="en">None</translation> + <translation lang="ru">Никто</translation> + <translation lang="de">Niemand</translation> + <translation lang="pl">Nic</translation> + <translation lang="es">Ninguno</translation> + <translation lang="hy">àã áù</translation> + </entry> + <entry> + <key>one</key> + <translation lang="en">one</translation> + <translation lang="ru">раз</translation> + <translation lang="de">einen</translation> + <translation lang="pl">raz</translation> + <translation lang="es">un</translation> + <translation lang="hy">Ù»Ï</translation> + </entry> + <entry> + <key>two</key> + <translation lang="en">two</translation> + <translation lang="ru">два</translation> + <translation lang="de">zwei</translation> + <translation lang="pl">dwa</translation> + <translation lang="es">dos</translation> + <translation lang="hy">»ñÏáõë</translation> + </entry> +</translations> + 1.3 +15 -6 xml-cocoon2/xdocs/i18n.xml Index: i18n.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/xdocs/i18n.xml,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- i18n.xml 2001/05/23 12:32:22 1.2 +++ i18n.xml 2001/06/01 16:15:03 1.3 @@ -92,7 +92,7 @@ ]]></code> </note> </s2> - <s2 title="Translation with param susbtitution"> + <s2 title="Translation with param substitution"> <p> To translate the text with param substitution the <code><![CDATA[<i18n:translate>]]></code> tag must be used. We can specify some <code><![CDATA[<i18n:param>]]></code>-tags which contain @@ -176,7 +176,7 @@ </translations>]]></source> <p> For each text, we want to translate, we must provide a key, where - the key is either text as we've wrote it in the document or the value + the key is either text as we have written it in the document or the value of the 'i18n:key' attribute. The key must be written exactly like in the document, including spaces, linefeeds, etc. </p> @@ -271,15 +271,24 @@ <li>Dictionary import and include capabilities (like in XSLT)</li> <li>Command line dictionary-from-source generation</li> <li>Dictionary caching</li> + <li>Date translation: + <code><![CDATA[ +<i18n:date src-pattern="dd/MM/yyyy" pattern="dd:MMM:yyyy" value="01/01/2001"/> + ]]></code> + - <code>'src-pattern'</code> will be used to parse the <code>'value'</code>, then the date will be formatted according to the current lang (Locale) using the <code>'pattern'</code> format. + </li> + <li>Number localized formatting + <code><![CDATA[ +<i18n:decimal pattern="0.##" value="2.0" /> + ]]></code> + - this will be useful for Arabic, Indian, etc. number formatting. + </li> </ul> - <p> - Some other features will be considered for implementation, like: date, currency, floating point numer formats i18n. - </p> </s2> <s2 title="Contacts"> <p> Feel free to contact for any comments and improvement ideas either directly <link href="mailto:[EMAIL PROTECTED]">Konstantin Piroumian</link> - or through the <link href="mail-lists.html">Cocoon Mail List</link>. + or through the <link href="/cocoon/mail-lists.html">Cocoon Mail List</link>. </p> </s2> </s1> ---------------------------------------------------------------------- In case of troubles, e-mail: [EMAIL PROTECTED] To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]