Return-Path: Delivered-To: apmail-xml-cocoon-cvs-archive@xml.apache.org Received: (qmail 57664 invoked by uid 500); 15 Jun 2001 15:00:32 -0000 Mailing-List: contact cocoon-cvs-help@xml.apache.org; run by ezmlm Precedence: bulk Reply-To: cocoon-dev@xml.apache.org list-help: list-unsubscribe: list-post: Delivered-To: mailing list cocoon-cvs@xml.apache.org Received: (qmail 57419 invoked by uid 500); 15 Jun 2001 15:00:27 -0000 Delivered-To: apmail-xml-cocoon2-cvs@apache.org Date: 15 Jun 2001 15:00:25 -0000 Message-ID: <20010615150025.57342.qmail@apache.org> From: dims@apache.org To: xml-cocoon2-cvs@apache.org Subject: cvs commit: xml-cocoon2/xdocs i18n.xml dims 01/06/15 08:00:24 Modified: src/org/apache/cocoon/transformation Tag: cocoon_20_branch I18nTransformer2.java webapp/i18n Tag: cocoon_20_branch simple.xml simple.xsl simple.xsp webapp/i18n/translations Tag: cocoon_20_branch simple_dict.xml xdocs Tag: cocoon_20_branch i18n.xml Log: Patches for i18nTransformer from Konstantin Revision Changes Path No revision No revision 1.9.2.1 +375 -75 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.9 retrieving revision 1.9.2.1 diff -u -r1.9 -r1.9.2.1 --- I18nTransformer2.java 2001/06/01 16:14:57 1.9 +++ I18nTransformer2.java 2001/06/15 15:00:06 1.9.2.1 @@ -37,8 +37,15 @@ import java.util.StringTokenizer; import java.util.ArrayList; import java.util.Locale; +import java.util.Date; +import java.text.Format; import java.text.MessageFormat; +import java.text.DateFormat; +import java.text.SimpleDateFormat; +import java.text.NumberFormat; +import java.text.DecimalFormat; +import java.text.ParseException; import java.net.URL; import java.net.MalformedURLException; @@ -132,23 +139,43 @@ public final static String I18N_DATE_ELEMENT = "date"; public final static String I18N_NUMBER_ELEMENT = "number"; + // number and date formatting attributes + public final static String I18N_SRC_PATTERN_ATTRIBUTE = "src-pattern"; + public final static String I18N_PATTERN_ATTRIBUTE = "pattern"; + public final static String I18N_VALUE_ATTRIBUTE = "value"; + /** + * sub-type attribute is used with i18:number to indicate + * a sub-type: currency or percent. + */ + public final static String I18N_SUB_TYPE_ATTRIBUTE = "sub-type"; + /** + * type attribute is used with i18:param to indicate + * the parameter type: date or number. + * If type is number then a sub-type + * can be used. + */ + public final static String I18N_TYPE_ATTRIBUTE = "type"; + // 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_TRANSLATE_TEXT = 5; - private final static int STATE_TRANSLATE_KEY = 6; - private final static int STATE_TRANSLATE_TEXT_KEY = 7; + private final static int STATE_INSIDE_TRANSLATE_TEXT = 4; + private final static int STATE_TRANSLATE_KEY = 5; + private final static int STATE_TRANSLATE_TEXT_KEY = 6; + private final static int STATE_INSIDE_DATE = 7; + private final static int STATE_INSIDE_NUMBER = 8; /** * Current state of the transformer. + * The value is STATE_OUTSIDE by default. */ private int current_state = STATE_OUTSIDE; /** - * Previous state. Used to translate text inside params and translate elements. + * Previous state. + * Used to translate text inside params and translate elements. */ private int prev_state = STATE_OUTSIDE; @@ -205,13 +232,33 @@ * Also, different encodings can be specified: ru_RU_koi8 */ private Locale locale; + + /** + * Date element attributes and their values. + */ + private HashMap formattingParams; + + public static Locale parseLocale(String locale) { + StringTokenizer st = new StringTokenizer(locale, "_"); + String lang = null; + String country = null; + String variant = null; + if (!st.hasMoreTokens()) { + return Locale.ENGLISH; + } + else { + lang = st.nextToken(); + } - public void setLang(String lang) { - this.lang = lang; + country = st.hasMoreTokens() ? st.nextToken() : ""; + variant = st.hasMoreTokens() ? st.nextToken() : ""; + + return new Locale(lang, country, variant); } public void setLocale(Locale locale) { this.locale = locale; + this.lang = locale.getLanguage(); } /** @@ -228,26 +275,8 @@ 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); + setLocale(parseLocale(lang)); formatter.setLocale(locale); // FIXME (KP) @@ -307,51 +336,126 @@ 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); + try { + 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); } - 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); + 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; } - 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); + 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); + } + setFormattingParams(attr); + current_state = STATE_INSIDE_PARAM; } - current_state = STATE_INSIDE_PARAM; + else if (I18N_DATE_ELEMENT.equals(name)) { + if (current_state != STATE_OUTSIDE) { + throw new SAXException(this.getClass().getName() + + ": i18n:date elements are not allowed " + + "inside of other i18n elements."); + } + + setFormattingParams(attr); + current_state = STATE_INSIDE_DATE; + } + else if (I18N_NUMBER_ELEMENT.equals(name)) { + if (current_state != STATE_OUTSIDE) { + throw new SAXException(this.getClass().getName() + + ": i18n:number elements are not allowed " + + "inside of other i18n elements."); + } + + setFormattingParams(attr); + current_state = STATE_INSIDE_NUMBER; + } + } catch (Exception e) { + // we need it to avoid further errors if an exception occurs + current_state = STATE_OUTSIDE; + throw new SAXException(this.getClass().getName() + + ": error in format", e); } } + /** + * Get src-pattern, pattern and value attribute values and store in a Map + */ + private void setFormattingParams(Attributes attr) throws SAXException { + formattingParams = new HashMap(3); + + String attr_value = attr.getValue(I18N_SRC_PATTERN_ATTRIBUTE); + if (attr_value != null) { + formattingParams.put(I18N_SRC_PATTERN_ATTRIBUTE, attr_value); + } + + attr_value = attr.getValue(I18N_PATTERN_ATTRIBUTE); + if (attr_value != null) { + formattingParams.put(I18N_PATTERN_ATTRIBUTE, attr_value); + } + + attr_value = attr.getValue(I18N_VALUE_ATTRIBUTE); + if (attr_value != null) { + formattingParams.put(I18N_VALUE_ATTRIBUTE, attr_value); + } + + attr_value = attr.getValue(I18N_TYPE_ATTRIBUTE); + if (attr_value != null) { + formattingParams.put(I18N_TYPE_ATTRIBUTE, attr_value); + } + + attr_value = attr.getValue(I18N_SUB_TYPE_ATTRIBUTE); + if (attr_value != null) { + formattingParams.put(I18N_SUB_TYPE_ATTRIBUTE, attr_value); + } + } + private void endI18NElement(String name) throws SAXException { this.getLogger().debug("End i18n element: " + name); - switch (current_state) { - case STATE_INSIDE_TEXT: { - endTextElement(); - break; - } - case STATE_INSIDE_TRANSLATE: { - endTranslateElement(); - break; - } - case STATE_INSIDE_PARAM: { - endParamElement(); - break; - } + try { + switch (current_state) { + case STATE_INSIDE_TEXT: { + endTextElement(); + break; + } + case STATE_INSIDE_TRANSLATE: { + endTranslateElement(); + break; + } + case STATE_INSIDE_PARAM: { + endParamElement(); + break; + } + case STATE_INSIDE_DATE: { + endDateElement(); + break; + } + case STATE_INSIDE_NUMBER: { + endNumberElement(); + break; + } + } + } catch (Exception e) { + // we need it to avoid further errors if an exception occurs + current_state = STATE_OUTSIDE; + throw new SAXException(this.getClass().getName() + + ": error in format", e); } } @@ -362,9 +466,9 @@ // 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; -// } + if (s == null) { + return null; + } String result = (s + "!").trim(); return result.substring(0, result.length() - 1); } @@ -375,7 +479,6 @@ String text2translate = new String(ch, start, len); text2translate = stripWhitespace(text2translate); if (text2translate == null || text2translate.length() == 0) { -// this.getLogger().warn(this.getClass().getName() + ": null i18n text found"); return; } @@ -390,7 +493,7 @@ } current_key = null; } - else if (len > 0) { + else { translated_text = (String)(dictionary.get(text2translate)); } @@ -398,19 +501,44 @@ } case STATE_INSIDE_TRANSLATE: { // Store text for param substitution (do not translate) - if (len > 0 && substitute_text == null) { + if (substitute_text == null) { substitute_text = text2translate; } break; } case STATE_INSIDE_PARAM: { // Store translation for param substitution - if (len > 0 && param_value == null) { + if (param_value == null) { param_value = text2translate; } break; } - + case STATE_INSIDE_DATE: { + if (formattingParams != null) { + if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null) { + formattingParams.put(I18N_VALUE_ATTRIBUTE, text2translate); + } + else { + // how to use the text inside of date element? + } + } + break; + } + case STATE_INSIDE_NUMBER: { + if (formattingParams != null) { + if (formattingParams.get(I18N_PATTERN_ATTRIBUTE) == null) { + formattingParams.put(I18N_PATTERN_ATTRIBUTE, text2translate); + } + else { + // how to use the text inside of number element? + } + } + break; + } + default: { + throw new SAXException(this.getClass().getName() + + "Something's really wrong!!!"); + } } } @@ -471,9 +599,8 @@ 0, translated_text.length()); } else { - // Translation not found. - super.contentHandler.characters("".toCharArray(), - 0, 0); + // else - translation not found + this.getLogger().debug("--- Translation not found! ---"); } break; } @@ -491,8 +618,28 @@ prev_state = STATE_OUTSIDE; } - private void endParamElement() { + private void endParamElement() throws SAXException { this.getLogger().debug("Substitution param: " + param_value); + if (formattingParams != null) { + String paramType = (String)formattingParams.get(I18N_TYPE_ATTRIBUTE); + if (paramType != null) { + this.getLogger().debug("Param type: " + paramType); + if (formattingParams.get(I18N_VALUE_ATTRIBUTE) == null + && param_value != null) { + this.getLogger().debug("Put param value: " + param_value); + formattingParams.put(I18N_VALUE_ATTRIBUTE, param_value); + } + if ("date".equals(paramType)) { + this.getLogger().debug("Formatting date param: " + formattingParams); + param_value = formatDate(formattingParams); + } + else if ("number".equals(paramType)) { + this.getLogger().debug("Formatting number param: " + formattingParams); + param_value = formatNumber(formattingParams); + } + } + } + this.getLogger().debug("Added substitution param: " + param_value); indexedParams.add(param_value); param_value = null; current_state = STATE_INSIDE_TRANSLATE; @@ -520,8 +667,124 @@ current_state = STATE_OUTSIDE; } + private void endDateElement() throws SAXException { + String result = formatDate(formattingParams); + super.contentHandler.characters(result.toCharArray(), 0, result.length()); + current_state = STATE_OUTSIDE; + } + + private String formatDate(Map params) throws SAXException { + if (params == null) { + throw new SAXException(this.getClass().getName() + + ": i18n:date - error in element attributes."); + } + // from pattern + String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE); + // to pattern + String pattern = (String)params.get(I18N_PATTERN_ATTRIBUTE); + // the date value + String value = (String)params.get(I18N_VALUE_ATTRIBUTE); + + // parsed date object + Date dateValue = null; + + // src format + SimpleDateFormat from_fmt = (SimpleDateFormat)DateFormat.getInstance(); + if (srcPattern != null) { + from_fmt.applyPattern(srcPattern); + } + + // result pattern is localized + SimpleDateFormat to_fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance( + DateFormat.DEFAULT, DateFormat.DEFAULT, locale); + if (pattern != null) { + to_fmt.applyPattern(pattern); + } + + // get current date and time by default + if (value == null) { + dateValue = new Date(); + } + else { + try { + dateValue = from_fmt.parse(value); + } catch (ParseException pe) { + throw new SAXException(this.getClass().getName() + + "i18n:date - parsing error.", pe); + } + } + + // we have all necessary data here: do formatting. + String result = to_fmt.format(dateValue); + this.getLogger().debug("i18n:date result: " + result); + return result; + } + + private void endNumberElement() throws SAXException { + String result = formatNumber(formattingParams); + super.contentHandler.characters(result.toCharArray(), 0, result.length()); + current_state = STATE_OUTSIDE; + } + + private String formatNumber(Map params) throws SAXException { + if (params == null) { + throw new SAXException(this.getClass().getName() + + ": i18n:number - error in element attributes."); + } + // from pattern + String srcPattern = (String)params.get(I18N_SRC_PATTERN_ATTRIBUTE); + // to pattern + String pattern = (String)params.get(I18N_PATTERN_ATTRIBUTE); + // the number value + String value = (String)params.get(I18N_VALUE_ATTRIBUTE); + // sub-type + String subType = (String)params.get(I18N_SUB_TYPE_ATTRIBUTE); + + // parsed number + Number numberValue = null; + + // src format + DecimalFormat from_fmt = (DecimalFormat)NumberFormat.getInstance(); + if (srcPattern != null) { + from_fmt.applyPattern(srcPattern); + } + + // result pattern is localized + DecimalFormat to_fmt = null; + if (subType == null) { + to_fmt = (DecimalFormat)NumberFormat.getInstance(locale); + } + else if (subType.equals("currency")) { + to_fmt = (DecimalFormat)NumberFormat.getCurrencyInstance(locale); + } + else if (subType.equals("percent")) { + to_fmt = (DecimalFormat)NumberFormat.getPercentInstance(locale); + } + if (pattern != null) { + to_fmt.applyPattern(pattern); + } + + // get current date and time by default + if (value == null) { + numberValue = new Long(0); + } + else { + try { + numberValue = from_fmt.parse(value); + } catch (ParseException pe) { + throw new SAXException(this.getClass().getName() + + "i18n:number - parsing error.", pe); + } + } + + // we have all necessary data here: do formatting. + String result = to_fmt.format(numberValue); + this.getLogger().debug("i18n:number result: " + result); + return result; + } + /** - *Gets translations from xml file to dictionary. + * Gets translations from xml file to dictionary. */ class I18nContentHandler extends DefaultHandler { boolean in_entry = false; @@ -622,4 +885,41 @@ if(parser != null) this.manager.release((Component) parser); } } + + /** + * + */ + static public void main(String[] args) { + + Locale locale = null; + + Locale[] locales = Locale.getAvailableLocales(); + for (int i = 0; i < locales.length; i++) { + locale = locales[i]; + SimpleDateFormat fmt = (SimpleDateFormat)DateFormat.getDateTimeInstance( + DateFormat.DEFAULT, DateFormat.DEFAULT, locale + ); + + String localized = fmt.format(new Date()); + + NumberFormat n_fmt = NumberFormat.getCurrencyInstance(locale); + String money = n_fmt.format(1210.5); + + System.out.println("Locale [" + + locale.getLanguage() + ", " + + locale.getCountry() + ", " + + locale.getVariant() + "] : " + + locale.getDisplayName() + + " \t Date: " + localized + + " \t Money: " + money); + } + } + } + + + + + + + No revision No revision 1.3.2.1 +43 -5 xml-cocoon2/webapp/i18n/simple.xml Index: simple.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/simple.xml,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- simple.xml 2001/05/23 12:32:20 1.3 +++ simple.xml 2001/06/15 15:00:11 1.3.2.1 @@ -1,15 +1,18 @@ - <i18n:text>Hello, internationalization!</i18n:text> + <i18n:text>Hello, internationalization!</i18n:text> + + + Documentation link: - http://xml.apache.org/cocoon/cocoon2/i18n.html + http://xml.apache.org/cocoon2/i18n.html Cocoon 2 Web Site - - + + <i18n:text>language</i18n:text> @@ -55,6 +58,32 @@ + + + + ?lang=en_US + English (US) + + + + + ?lang=en_GB + English (GB) + + + + + ?lang=ru_RU + Russian (Russia) + + + + + ?lang=de_AT_EURO + German (Austria, Euro) + + + article_text1 @@ -77,9 +106,18 @@ one two baby - ~ + ~ + + + Number : {0} | Currency: {1} | Percent: {2}, processed on: {3} + + 27.24 + 1.2 + + + 1.2.2.1 +15 -6 xml-cocoon2/webapp/i18n/simple.xsl Index: simple.xsl =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/simple.xsl,v retrieving revision 1.2 retrieving revision 1.2.2.1 diff -u -r1.2 -r1.2.2.1 --- simple.xsl 2001/05/18 14:05:20 1.2 +++ simple.xsl 2001/06/15 15:00:13 1.2.2.1 @@ -7,16 +7,25 @@ - -

+ +

-

- -

- + +
+ + + + + +
+ + + +

+ 1.4.2.1 +148 -109 xml-cocoon2/webapp/i18n/simple.xsp Index: simple.xsp =================================================================== RCS file: /home/cvs/xml-cocoon2/webapp/i18n/simple.xsp,v retrieving revision 1.4 retrieving revision 1.4.2.1 diff -u -r1.4 -r1.4.2.1 --- simple.xsp 2001/06/01 16:14:59 1.4 +++ simple.xsp 2001/06/15 15:00:14 1.4.2.1 @@ -1,18 +1,15 @@ - - - java.text.SimpleDateFormat - java.util.Locale - - - + + java.text.SimpleDateFormat + java.util.Locale + + private static int count = 0; - - - - + + + synchronized (this) { count++; } @@ -20,110 +17,152 @@ Locale loc = null; String lang = ; if (lang != null) { - // request.setAttribute("lang", lang); - loc = new Locale(lang, lang.toUpperCase()); + loc = org.apache.cocoon.transformation.I18nTransformer2.parseLocale(lang); } - - // here also must be a check if this locale is available - // otherwise, date format will be incorrect. - if (loc == null) { - loc = Locale.ENGLISH; - } - - SimpleDateFormat df = new SimpleDateFormat("EEE, MMM dd, yyyy H:mm:ss", loc); + + SimpleDateFormat df = new SimpleDateFormat("EEEE, MMMM dd, yyyy H:mm:ss", loc); - - <i18n:text>Hello, internationalization!</i18n:text> - - - Documentation link: - - http://xml.apache.org/cocoon/cocoon2/i18n.html - Cocoon 2 Web Site - - - - - count_title - count - df.format(new Date()) - - - - - <i18n:text>language</i18n:text> - - - - ?lang=lang_id1 - - <i18n:text>language1</i18n:text> - - - - + + <i18n:text>Hello, internationalization!</i18n:text> + + + Documentation link: - ?lang=lang_id2 - - <i18n:text>language2</i18n:text> - - - - - - ?lang=lang_id3 - - <i18n:text>language3</i18n:text> - + http://xml.apache.org/cocoon2/i18n.html + Cocoon 2 Web Site - - - - ?lang=lang_id4 - - <i18n:text>language4</i18n:text> - - - - - - ?lang=lang_id5 - - <i18n:text>language5</i18n:text> - - - - - - - article_text1 - - - article_text2 - - + + - Hello, {0}! Glad to see you! - + count_title + + count + + + df.format(new Date()) + - - - + + + + + <i18n:text>language</i18n:text> + + + + + ?lang=lang_id1 + + <i18n:text>language1</i18n:text> + + + + + + ?lang=lang_id2 + + <i18n:text>language2</i18n:text> + + + + + + ?lang=lang_id3 + + <i18n:text>language3</i18n:text> + + + + + + ?lang=lang_id4 + + <i18n:text>language4</i18n:text> + + + + + + ?lang=lang_id5 + + <i18n:text>language5</i18n:text> + + + + + + + + ?lang=en_US + English (US) + + + + + ?lang=en_GB + English (GB) + + + + + ?lang=ru_RU + Russian (Russia) + + + + + ?lang=de_AT_EURO + German (Austria, Euro) + + + + + + article_text1 + + + article_text2 + + + + Hello, {0}! Glad to see you! + + + + + + + + + One = {0}, two = {1}, {2}! {3} This line is not translated {3} - "ONE".toLowerCase() - two - baby - ~ - - - - - - copyright - - - - + + + "ONE".toLowerCase() + + + + two + + baby + ~ + + + + + Number : {0} | Currency: {1} | Percent: {2}, processed on: {3} + + 27.24 + 1.2 + + + + + + + copyright + + + - No revision No revision 1.3.2.2 +267 -267 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.3.2.1 retrieving revision 1.3.2.2 diff -u -r1.3.2.1 -r1.3.2.2 --- simple_dict.xml 2001/06/09 12:20:47 1.3.2.1 +++ simple_dict.xml 2001/06/15 15:00:18 1.3.2.2 @@ -1,267 +1,267 @@ - - - - - - - count_title - This page was accessed {0} times. Last at: {1}. - На эту страницу заходили {0} раз(а). В последний раз {1}. - Auf diese Seite kamen {0} Des males vorbei. In das letzte {1}. - Ta strona była pobierana {0} razy. Ostatnio {1} - Esta página fue tenida acceso {0} veces. Pasado en: {1}. - ²Ûë ¿çÁ ³Ûó»É»É »Ý {0} ³Ý·³Ù. ì»ñçÇÝÁ {1}. - - - a_key - This is a key value. - Это значение по ключу. - Diese Bedeutung nach dem Schlüssel. - To jest klucz. - Esto es un valor clave. - ê³ µ³Ý³ÉÇÇ ³éÅ»ùÝ ¿£ - - - lang_id1 - ru - en - en - en - en - en - - - lang_id2 - de - de - ru - ru - ru - ru - - - lang_id3 - pl - pl - pl - de - de - de - - - lang_id4 - es - es - es - es - pl - pl - - - lang_id5 - hy - hy - hy - hy - hy - es - - - - language - English - Русский - Deutsch - Polski - Español - гۻñ»Ý - - - language1 - Russian - Английский - Englische - Angielski - Inglés - ²Ý·É»ñ»Ý - - - language2 - German - Немецкий - Russe - Rosyjski - Ruso - èáõë»ñ»Ý - - - language3 - Polish - Польский - Polnisch - Niemiecki - Alemán - ¶»ñٳݻñ»Ý - - - language4 - Spanish - Испанский - Spanisch - Hiszpañski - Polaco - Ȼѻñ»Ý - - - language5 - Armenian - Армянский - Armenier - Armeñski - Armenio - Æëå³Ý»ñ»Ý - - - Hello, internationalization! - Hello, internationalization! - Привет, многоязычность! - Hallo, die Internationalisierung! - Witam, oto przykład wielojęzycznej strony! - ¡¡Hola!, internacionalización! - ´³ñ¢°, ÇÝï»ñݳóÛáݳÉáõÃÛáõÝ£ - - - Documentation link: - See i18n documentation for details: - Для дополнительной информации по i18n смотри: - Sieh i18n Dokumentation für Details: - Widzą i18n dokumentacja dla szczegółów: - Visto la documentación i18n para detalles: - سÝñ³Ù³ë µ³ó³ïñáõÃÛ³Ý Ñ³Ù³ñ ݳÇñª - - - first - First - Первый - Ersten - Pierwszy - Primero - ²é³çÇÝ - - - second - Second - Второй - Zwiete - Drugi - Segundo - ºñÏñáñ¹ - - - third - Third - Третий - Dritten - Trzeci - Tercio - ºññáñ¹ - - - forth - Forth - Четвертый - Vierten - Czwarty - En adelante - ¼áñáñ¹ - - - article - Article - Статья - Artikel - Artykuł - Artículo - Ðá¹í³Í - - - article_text1 - This is a i18n paragraph. - Это интернационализированный абзац. - Es i18n den Absatz. - To jest paragraf w i18n. - Esto es un párrafo i18n. - ê³ ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿£ - - - article_text2 - This is another i18n paragraph and is also a cool one. - Это тоже интернационализированный абзац и такой же классный. - Es auch i18n den Absatz und solcher cool. - To jest następny paragraf w i18n i jest takze fajny. - Esto es otro párrafo i18n y es también uno 'cool'. - ê³ ÙÇ áõñÇß ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿, ¢ ÝáõÛÝ å»ë ó»Ýïñ£ - - - copyright - Copyright © 2001 Konstantin Piroumian. No rights are reserved. - Авторские права © 2001 Константин Пирумян. Ничто не защищено. - Die Urheberrechte © 2001 Konstantin Piroumian. Nichts ist geschützt. - Copyright © 2001 Konstantin Piroumian i Krzysztof Zieliński. Żadne prawa nie są zastrzeżone:) - Copyright © 2001 Konstantin Piroumian. Ningunos derechos son reservados. - Copyright © 2001 Konstantin Piroumian. àãÇÝã ãÇ å³Ñå³Ýí³Í£ - - - Hello, {0}! Glad to see you! - Hello, {0}! Glad to see you! - Привет, {0}! Рад тебя видеть! - Hallo, {0}! Ist dich froh, zu sehen! - Witam, {0}! Miło Cię widzieć! - ¡¡Hola!, {0}! ¡Alegre de verle! - ´³ñ¢¯ {0}: àõñ³Ë »Ù ù»½ ï»ëݻɣ - - - Kot - Tomcat - Кот - Der Kater - Tomcat - Gato - γïáõ - - - none - None - Никто - Niemand - Nic - Ninguno - àã áù - - - one - one - раз - einen - raz - un - Ù»Ï - - - two - two - два - zwei - dwa - dos - »ñÏáõë - - + + + + + + + count_title + This page was accessed {0} times. Last at: {1}. + На эту страницу заходили {0} раз(а). В последний раз {1}. + Diese Seite wurde {0}mal aufgerufen. Letzter Aufruf: {1}. + Ta strona była pobierana {0} razy. Ostatnio {1} + Esta página fue tenida acceso {0} veces. Pasado en: {1}. + ²Ûë ¿çÁ ³Ûó»É»É »Ý {0} ³Ý·³Ù. ì»ñçÇÝÁ {1}. + + + a_key + This is a key value. + Это значение по ключу. + Dies ist der Wert eines Schlüssels. + To jest klucz. + Esto es un valor clave. + ê³ µ³Ý³ÉÇÇ ³éÅ»ùÝ ¿£ + + + lang_id1 + ru + en + en + en + en + en + + + lang_id2 + de + de + ru + ru + ru + ru + + + lang_id3 + pl + pl + pl + de + de + de + + + lang_id4 + es + es + es + es + pl + pl + + + lang_id5 + hy + hy + hy + hy + hy + es + + + + language + English + Русский + Deutsch + Polski + Español + гۻñ»Ý + + + language1 + Russian + Английский + Englische + Angielski + Inglés + ²Ý·É»ñ»Ý + + + language2 + German + Немецкий + Russe + Rosyjski + Ruso + èáõë»ñ»Ý + + + language3 + Polish + Польский + Polnisch + Niemiecki + Alemán + ¶»ñٳݻñ»Ý + + + language4 + Spanish + Испанский + Spanisch + Hiszpañski + Polaco + Ȼѻñ»Ý + + + language5 + Armenian + Армянский + Armenier + Armeñski + Armenio + Æëå³Ý»ñ»Ý + + + Hello, internationalization! + Hello, internationalization! + Привет, многоязычность! + Herzlich willkommen, Internationalisierung! + Witam, oto przykład wielojęzycznej strony! + ¡¡Hola!, internacionalización! + ´³ñ¢°, ÇÝï»ñݳóÛáݳÉáõÃÛáõÝ£ + + + Documentation link: + See i18n documentation for details: + Для дополнительной информации по i18n смотри: + Näheres unter der i18n Dokumentation: + Widzą i18n dokumentacja dla szczegółów: + Visto la documentación i18n para detalles: + سÝñ³Ù³ë µ³ó³ïñáõÃÛ³Ý Ñ³Ù³ñ ݳÇñª + + + first + First + Первый + Erstens + Pierwszy + Primero + ²é³çÇÝ + + + second + Second + Второй + Zweitens + Drugi + Segundo + ºñÏñáñ¹ + + + third + Third + Третий + Drittens + Trzeci + Tercio + ºññáñ¹ + + + forth + Forth + Четвертый + Viertens + Czwarty + En adelante + ¼áñáñ¹ + + + article + Article + Статья + Artikel + Artykuł + Artículo + Ðá¹í³Í + + + article_text1 + This is a i18n paragraph. + Это интернационализированный абзац. + Dies ist ein Absatz nach i18n. + To jest paragraf w i18n. + Esto es un párrafo i18n. + ê³ ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿£ + + + article_text2 + This is another i18n paragraph and is also a cool one. + Это тоже интернационализированный абзац и такой же классный. + Dies ist ein weiterer Absatz nach i18n und auch noch ein ziemlich cooler dazu. + To jest następny paragraf w i18n i jest takze fajny. + Esto es otro párrafo i18n y es también uno 'cool'. + ê³ ÙÇ áõñÇß ÇÝï»ñݳóÛáÝ³É å³ñ³·ñ³ý ¿, ¢ ÝáõÛÝ å»ë ó»Ýïñ£ + + + copyright + Copyright © 2001 Konstantin Piroumian. No rights are reserved. + Авторские права © 2001 Константин Пирумян. Ничто не защищено. + Copyright © 2001 Konstantin Piroumian. Deutsche Übersetzung von Jörg Prante. + Copyright © 2001 Konstantin Piroumian i Krzysztof Zieliński. Żadne prawa nie są zastrzeżone:) + Copyright © 2001 Konstantin Piroumian. Ningunos derechos son reservados. + Copyright © 2001 Konstantin Piroumian. àãÇÝã ãÇ å³Ñå³Ýí³Í£ + + + Hello, {0}! Glad to see you! + Hello, {0}! Glad to see you! + Привет, {0}! Рад тебя видеть! + Hallo {0}! Schön, dich zu sehen! + Witam, {0}! Miło Cię widzieć! + ¡¡Hola!, {0}! ¡Alegre de verle! + ´³ñ¢¯ {0}: àõñ³Ë »Ù ù»½ ï»ëݻɣ + + + Kot + Tomcat + Кот + Tomcat + Tomcat + Gato + γïáõ + + + none + None + Никто + nichts + Nic + Ninguno + àã áù + + + one + one + раз + eins + raz + un + Ù»Ï + + + two + two + два + zwei + dwa + dos + »ñÏáõë + + No revision No revision 1.3.2.1 +48 -32 xml-cocoon2/xdocs/i18n.xml Index: i18n.xml =================================================================== RCS file: /home/cvs/xml-cocoon2/xdocs/i18n.xml,v retrieving revision 1.3 retrieving revision 1.3.2.1 diff -u -r1.3 -r1.3.2.1 --- i18n.xml 2001/06/01 16:15:03 1.3 +++ i18n.xml 2001/06/15 15:00:22 1.3.2.1 @@ -7,7 +7,7 @@ - This document describes an aproach for internationalization of XML + This document describes an approach for internationalization of XML documents within Cocoon 2. It introduces some tags to markup text that should be translated and a format for dictionaries. The first proposal was made by Infozone Group (http://www.infozone-group.org). @@ -30,7 +30,7 @@ xmlns:i18n="http://apache.org/cocoon/i18n/2.0"

- First implementation was developed by Lassi Immonen. In this implementation the syntax was changed according to the Infozone Group's i18n proposal (with a little difference) and new features were implemented. + First implementation was developed by Lassi Immonen. In this implementation syntax was changed according to the Infozone Group's i18n proposal (with a little difference) and some new features were implemented.

@@ -42,6 +42,10 @@
  • Attribute translation
  • Param substitution
  • Substitution param translation
  • +
  • Date internationalization (New!)
  • +
  • Number internationalization (New!)
  • +
  • Locale support (New!)
  • +
  • A dictionary update and language addition automation stylesheet (New!)
  • A simple example of i18n: @@ -52,12 +56,11 @@ ]]>

    Text inside the ]]> will be used as a key to find the - translation in the dictionary. All attributes that are listed in the ]]> attribute also will - be translated and their values will be used as dicionary keys. + translation in the dictionary. All attributes that are listed in the ]]> attribute also will be translated and their values will be used as dicionary keys.

    - This i18n approach is not designed to implement i18n of dates, currencies, etc. - Maybe this features will be supported in future versions. + This i18n approach was re-designed to implement i18n of dates, currencies, etc. + Although supported possibilities are quite enough for complicated formatting, but in some cases you will need to use XSP to achieve more flexibility.
    @@ -81,7 +84,7 @@ Default value]]> - Maybe it would be better to have a possibility to use i18n:key in any element and not only in i18n:text. + Maybe it would be better to have a possibility to use i18n:key in any element and not only in i18n:text? E.g.: @@ -106,21 +109,21 @@ text here ]]> -

    +

    Now we want to translate this into German. First, the processor will look into the dictionary, we specified, for the string:

    -

    - Some {0} was inserted {1}. -

    -

    +

    + Some {0} was inserted {1}. +

    +

    It finds the string and translates it to German: -

    -

    +

    +

    Etwas {0} wurde {1} eingesetzt. -

    -

    +

    +

    Now the processor will replace the parameters. {0} will be replaced with "text" and {1} with "here". This results in:

    @@ -159,6 +162,33 @@ Parameter replacement is not available for attributes at this time.

    + +

    To format dates and time according to the current locale use ]]>. The 'src-pattern' attribute will be used to parse the 'value', then the date will be formatted according to the current locale using the format specified by 'pattern' attribute. +

    +

    + If no pattern was specified then the date will be formatted with the DateFormat.DEFAULT format (both date and time). If no value for the date is specified then the current date will be used. E.g.: will result in the current date and time, formatted with default localized pattern. +

    +

    To format numbers in locale sensitive manner use ]]>. This will be useful for Arabic, Indian, etc. number formatting. Additionally, currencies and percent formatting can be used. E.g.: +

    +
      +
    • ]]> will result in localized presentation of the value - $1,703.74 for US locale.
    • +
    • ]]> will result in localized percent value - %120 for most of the locales.
    • +
    +

    + Also, date and number formatting can be used with substitution params. Additional type attribute must be used with params to indicate the param type (date or number). Default type is string. +

    + + You have to pay {0} for {1} pounds or {2} of your profit. Valid from {3} + 102.5 + + + +]]> +

    + Result will be like this: You have to pay $102.5 for 2.5 pounds or 10% of your profit. Valid from 13-Jun-01 +

    +

    Dictionaries contain the translations for the text to be translated. @@ -263,26 +293,12 @@ - -

    - Some more features must be added for more flexibility and convenience: -

    +
      +
    • Multiple dictionary support
    • Dictionary import and include capabilities (like in XSLT)
    • Command line dictionary-from-source generation
    • Dictionary caching
    • -
    • Date translation: - - ]]> - - 'src-pattern' will be used to parse the 'value', then the date will be formatted according to the current lang (Locale) using the 'pattern' format. -
    • -
    • Number localized formatting - - ]]> - - this will be useful for Arabic, Indian, etc. number formatting. -
    ---------------------------------------------------------------------- In case of troubles, e-mail: webmaster@xml.apache.org To unsubscribe, e-mail: cocoon-cvs-unsubscribe@xml.apache.org For additional commands, e-mail: cocoon-cvs-help@xml.apache.org