Uploaded image for project: 'Tapestry'
  1. Tapestry
  2. TAPESTRY-996

Better locale detection for fully localized applications


    • Type: Improvement
    • Status: Resolved
    • Priority: Major
    • Resolution: Fixed
    • Affects Version/s: 4.0.2
    • Fix Version/s: 4.1.2
    • Component/s: Web
    • Labels:


      Very often, localized applications are not just language-specific but country-specific. Besides displaying pages in a particular language, currencies and dates has to be correctly formatted too. As is well known, these are dependant on the country code (ISO 3166). Unfortunately, some browsers, like Opera and MSIE, do not send the country code in the "Accept-Language" HTTP header. This problem can be resolved by providing a substitution to the incomplete locale string (ex: 'en_GB' instead of 'en').

      Tapestry already has the facility for this modification. After the modification, the list "en_GB, de_DE, fr_FR, fr_CA" in the accepted-locales configuration property would be interpreted like this:
      Assuming the browser is sending...
      'de', the closest match would be 'de_DE' (no country present, assume Germany)
      'de_LU', the closest match would be 'de_DE' (no exact match found)
      'fr', the closest match would be 'fr_FR' (no country present, assume France)
      'fr_CA', the closest match would be exactly 'fr_CA'
      'sv_SE', the closest match would be 'en_GB' (as in the current implementaion)

      In the current implementation, if there isn't an exact match for a particular locale, the closest match would be the first locale in the list ('en_GB').

      The modification that makes the above possible should be made to the private method filterRequestedLocale(String localeName) of the org.apache.tapestry.services.impl.RequestLocaleManagerImpl class.


      • Converts the request locale name into a Locale instance; applies filters (based on
      • acceptedLocales) if enabled.
        private Locale filterRequestedLocale(String localeName) {
        if (_acceptedLocaleNamesSet.isEmpty()) return getLocale(localeName);

      // If there's an exact match return it:
      if (_acceptedLocaleNamesSet.contains(localeName)) return getLocale(localeName);

      // Now look for the first closest match:
      for (Iterator it= _acceptedLocaleNamesSet.iterator(); it.hasNext(); )

      { String validLoc = (String) it.next(); if (validLoc.startsWith(localeName)) return getLocale(validLoc); }

      // Return the first locale string in the list
      return _defaultLocale;


      • Ability to make country-specific localizations very easy.
      • The proposed modification is backward-compatible. One doesn't have to change the list of accepted languages in any way. For language-specific applications it's completely OK to just list languages, like "en, sp, de, fr".
      • Locales for incoming requests will be converted to truely closest match. For example:
        if the list of accepted languages is "en, es_ES", then an argentinian user ('es_AR') would most likely be intrested in viewing pages in Spanish ('es_ES') than in english ('en').




            • Assignee:
              jkuhnert Jesse Kuhnert
              firas Firas Adiler
            • Votes:
              0 Vote for this issue
              1 Start watching this issue


              • Created: