> > ----- Original Message ----- > From: "Leandro Rodrigo Saad Cruz" <[EMAIL PROTECTED]> > To: "Turbine Users List" <[EMAIL PROTECTED]> > Sent: Tuesday, March 19, 2002 3:52 PM > Subject: Re: Localization > > > > You can use the Localization accessor with any locale you would like. > > Maybe you can change TLocalizationService.java or LocalizationTool.java > > to allow some order or user preference regarding localized objects. > > I created a class called LocaleHelper that has the business logic used > > to pick up a locale acording to values in user session and http headers. > > If you wnat I can send it to you.
Ok.. that's what I've done. I need to grab *localized objects and maybe choose between **localized templates * to accomplish this I wrote LocalizationHelper, this class is used in behalf of *new* LocalizationTool and encapsulates the logic that chooses locales. ** I wrote a new Screen that tries to find different templates accordign to some locale info. For example : locale=pt_BR, then SomeTemplate-pt_BR.vm is looked up, then SomeTemplate.vm OBS : you will have to change the package of this files and possibly some code (chanbe ACCEPTED_LOACES for example) to make it work. Want any help ?? To see it working visit http://www.intercontinental.ind.br:8180/inter/servlet/main this site is supposed to be viewed in English and Portuguese -- Leandro Rodrigo Saad Cruz IT - Inter Business Tecnologia e Servicos (IB) http://www.ibnetwork.com.br
package br.com.ibnetwork.intercontinental.modules.screens; //APP import br.com.ibnetwork.intercontinental.services.localization.LocalizationHelper; //T2 import org.apache.turbine.util.RunData; import org.apache.turbine.util.Log; import org.apache.turbine.modules.screens.VelocityScreen; import org.apache.turbine.services.template.TurbineTemplate; import org.apache.turbine.services.velocity.TurbineVelocity; import org.apache.velocity.context.Context; import org.apache.velocity.app.Velocity; import org.apache.ecs.ConcreteElement; //JAVA import java.util.Locale; import java.io.File; /** * This module is responsible for searching a template file accordign to LocalizationHelper.getLocale() * <br> * This way we can stil use links like $link.setPage("SomeTemplate.vm") and this module will handle the template engine the right template. For Example : * <br> * <b>USER_LOCALE = pt_BR</b> * <br> * search for : SomeTemplate-pt_BR.vm, then SomeTemplate.vm .... * * @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a> */ public class IntercontinentalVelocityScreen extends VelocityScreen { /** * Este metodo sera executado apos os metodos dos screens que estendem esta classe<br> * Sua funcao eh tentar localizar um template com o mesmo nome do presente em RunData, mas com conteudo sensivel ao locale correto. * O locale pesquisado pode variar de acordo com as regras em LocalizationHelper. * Este módulo apenas faz uma tentativa de mudar o template, caso o template-locale não exista, o template original será executado */ public void setTemplateLocalizationExtension(RunData data) { Locale locale = LocalizationHelper.getLocale(data); Log.debug("debug","IntercontinentalScreen - Searching for new template for locale["+locale+"]"); if(locale != null) { try { //caso algum locale esteja disponivel nos tentaremos achar outros template String templateName = TurbineTemplate.getScreenTemplateName(data.getTemplateInfo().getScreenTemplate()); Log.debug("debug","IntercontinentalScreen - original template["+templateName+"]"); data.setScreenTemplate(composeLocaleInfoAndTemplateName(templateName,locale)); } catch(Exception e) { Log.debug("Erro",e); //em caso de erro, o template original sera pesquisado } } } /** * This method is called by the Screenloader to construct the * Screen. * * @param data Turbine information. * @return A ConcreteElement. * @exception Exception, a generic exception. */ public ConcreteElement doBuild( RunData data ) throws Exception { Log.debug("debug","IntercontinentalScreen - Executing doBuild(data)"); ConcreteElement out = null; try { doBuildTemplate(data); setTemplateLocalizationExtension(data); out = buildTemplate(data); } finally { doPostBuildTemplate(data); } return out; } private String composeLocaleInfoAndTemplateName(String templateName,Locale locale) { int pathSeparatorPosition = templateName.lastIndexOf("/"); if(pathSeparatorPosition >= 0) { String minusPath = templateName.substring(pathSeparatorPosition + 1); String path = templateName.substring(0,pathSeparatorPosition+1); Log.debug("debug","IntercontinentalScreen - path["+path+"] name["+minusPath+"]"); int dotPosition = minusPath.lastIndexOf("."); StringBuffer sb = new StringBuffer(); sb.append(path) .append(minusPath.substring(0,dotPosition)) .append("-") .append(locale) .append(minusPath.substring(dotPosition)); String newTemplateName = sb.toString(); if(Velocity.templateExists("/screens"+newTemplateName)) { Log.info("debug","IntercontinentalScreen - localizedTemplateName found ["+newTemplateName+"] "); return newTemplateName; } } Log.info("debug","IntercontinentalScreen - localizedTemplateName found ["+templateName+"] "); return templateName; } }
package br.com.ibnetwork.intercontinental.services.localization; //T2 import org.apache.turbine.util.Log; import org.apache.turbine.util.RunData; import org.apache.turbine.services.localization.Localization; //JAVA import java.util.Locale; import java.util.StringTokenizer; /** * This class is a helper tool to be used when you have to decide which Locale to choose. * This implementation follows this criteria : <br> * i - first it checks to see if there is locale in the user session <br> * ii - then it tries to build a locale from HTTP headers <br> * iii - then it uses the default locale in TR.conf <br> * * @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a> */ public class LocalizationHelper { /** * Key used to put a Locale Object * into the session and used as a form field name * OBS : if you want this to work between user logins you will have to patch Turbine.java to not exclude this key/val from Session */ public static final String USER_LOCALE = "user.locale"; /** * Key used to define the locale separator char */ public static final String SEPARATOR = "_"; /** * All locales that we are prepard to handle PORTUGUES and ENGLISH * <br> * OBS : Remenber, if you want do add the locales to this array you will have to add new templates to your system too */ public static Locale[] ACCEPTED_LOCALES = { new Locale("pt","BR"), Locale.US,Locale.ENGLISH }; /** * Performs Locale selection */ public static Locale getLocale(RunData data) { //Session Locale locale = (Locale) ((RunData)data).getSession().getValue(USER_LOCALE); //HEADERS HTTP if(locale == null) { locale = Localization.getLocale( ((RunData) data).getRequest() ); boolean accepted = false; for(int i=0 ; i < ACCEPTED_LOCALES.length ; i++) { Log.debug("debug","LocalizationHelper: searching locale["+ACCEPTED_LOCALES[i]+"] in ACCEPTED list"); if(locale.equals(ACCEPTED_LOCALES[i])) { accepted = true; break; } } locale = (accepted == false ? null : locale); } //TR.conf if(locale == null) { locale = Localization.getBundle(Localization.getDefaultBundleName()).getLocale(); } return locale; } /** * helper method used to build a locale from HTTP HEADERS * @return a new locale obj or null when an error occur */ public static Locale buildLocaleFromParameter(String param) { if(param != null) { Locale locale; StringTokenizer st = new StringTokenizer(param,SEPARATOR); int total = st.countTokens(); String tokens[] = new String[total]; while (st.hasMoreTokens()) { String token = st.nextToken(); Log.debug("debug","TOKEN ["+token+"]"); tokens[--total] = token; } if(tokens.length == 2) { return new Locale(tokens[1],tokens[0]); } if(tokens.length == 3) { return new Locale(tokens[2],tokens[1],tokens[0]); } } return null; } }
package br.com.ibnetwork.intercontinental.services.localization; //APP //T2 import org.apache.turbine.services.localization.Localization; import org.apache.turbine.services.pull.ApplicationTool; import org.apache.turbine.om.security.User; import org.apache.turbine.util.Log; import org.apache.turbine.util.RunData; //JAVA import java.util.Locale; import java.util.MissingResourceException; import java.util.ResourceBundle; /** * Localization Tool usado nos templates para disponibilizar conteúdo localizado com ajuda de * {@link br.com.ibnetwork.intercontinental.services.localization.LocalizationHelper} * * @author <a href="mailto:[EMAIL PROTECTED]">Leandro Rodrigo Saad Cruz</a> */ public class LocalizationTool implements ApplicationTool { /** * The language and country information parsed from the request's * <code>Accept-Language</code> header. Reset on each request. */ protected Locale locale; /** * The bundle for this request. */ private ResourceBundle bundle; /** * The name of the bundle for this tool to use. */ private String bundleName; /** * Creates a new instance. Used by <code>PullService</code>. */ public LocalizationTool() { locale = null; bundle = null; bundleName = null; } /** * <p>Performs text lookups for localization.</p> * * <p>Assuming there is a instance of this class with a HTTP * request set in your template's context named <code>l10n</code>, * the VTL <code>$l10n.HELLO</code> would render to * <code>hello</code> for English requests and <code>hola</code> * in Spanish (depending on the value of the HTTP request's * <code>Accept-Language</code> header).</p> * * @param key The identifier for the localized text to retrieve. * @return The localized text. */ public String get(String key) { try { //Log.debug("service","Localization tool :Bundle["+bundleName+"]=["+bundle+"] used for key["+key+"] and locale["+locale+"]"); return bundle.getString(key); } catch (MissingResourceException noKey) { Log.warn("service","Missing Resource",noKey); return null; } } /** * The return value of this method is used to set the name of the * bundle used by this tool. Useful as a hook for using a * different bundle than specifed in your * <code>LocalizationService</code> configuration. * * @param data The inputs passed from {@link #init(Object)}. * (ignored by this implementation). */ protected String getBundleName(Object data) { return Localization.getDefaultBundleName(); } /** * Tool initialization * <BR> * GLOBAL * <blockquote> * Locale comes from TR.conf * </blockquote> * <BR> * REQUEST * <blockquote> * Check if user.locale is in Session, otherwise build a locale from HTTP HEADERS * </blockquote> * */ public final void init(Object data) { if(data == null) { Log.debug("service","Localization tool initializing with scope GLOBAL"); //bundle default em TR.conf since no request data is available bundle = Localization.getBundle(Localization.getDefaultBundleName()); } if(data instanceof User) { Log.debug("service","Localization tool initializing with scope SESSION"); // Pull necessary information out of Session. } if (data instanceof RunData) { Log.debug("service","Localization tool initializing with scope REQUEST"); // Pull necessary information out of RunData while we have a reference to it. locale = LocalizationHelper.getLocale((RunData)data); bundleName = getBundleName(data); //bundle acoording to request information bundle = Localization.getBundle(bundleName, locale); Log.debug("service","Localization tool initialized with bundleName["+bundleName+"] locale["+locale+"]"); } } /** * No-op. */ public void refresh() { Log.debug("service","Localization tool refreshing..."); } /** * helper method to be used inside templates */ public String getUserLocale() { return LocalizationHelper.USER_LOCALE; } }
-- To unsubscribe, e-mail: <mailto:[EMAIL PROTECTED]> For additional commands, e-mail: <mailto:[EMAIL PROTECTED]>