*************** *** 28,39 **** //see if the language is already set. if ($setlanguage) { $i18n_language = $setlanguage; - } elseif ($i18n_language) { - return $i18n_language; - } else { _i18n_init(); - return $i18n_language = _i18n_get_lang(); } } /** --- 28,38 ---- //see if the language is already set. if ($setlanguage) { $i18n_language = $setlanguage; + } elseif (!isset($i18n_language)) { _i18n_init(); + $i18n_language = _i18n_get_lang(); } + return $i18n_language; } /** *************** *** 41,49 **** */ function _i18n_init(){ global $i18n_langpath; - $path = _i18n_get_original_path(); - $i18n_langpath = i18n_get_lang_prefix($path); - } /** * Language block --- 40,50 ---- */ function _i18n_init(){ global $i18n_langpath; + if (!isset($i18n_langpath)) { + $path = _i18n_get_original_path(); + $i18n_langpath = i18n_get_lang_prefix($path); + } + } /** * Language block *************** *** 94,104 **** } } elseif ($lang == $path) { // When path is only language code $_GET['q'] = i18n_frontpage($lang); } elseif ($i18n_langpath) { //search alias with and without lang and remove lang. $_GET['q'] = i18n_get_normal_path($path); } } --- 95,112 ---- } } elseif ($lang == $path) { // When path is only language code $_GET['q'] = i18n_frontpage($lang); + if ($lang == i18n_default_language()) { + i18n_get_lang_prefix($path, TRUE); + _i18n_goto($path); + } } elseif ($i18n_langpath) { //search alias with and without lang and remove lang. $_GET['q'] = i18n_get_normal_path($path); } + if (!_i18n_add_lang_prefix($lang) && i18n_get_lang_prefix($path, TRUE)) { + _i18n_goto($path); + } } *************** *** 306,312 **** '#maxlength' => 10, '#description' => t('Image size for language icons, in the form "width x height".'), ); - // Advanced options $form['advanced'] = array( '#type' => 'fieldset', --- 314,334 ---- '#maxlength' => 10, '#description' => t('Image size for language icons, in the form "width x height".'), ); + // Language prefix + $form['prefix'] = array( + '#type' => 'fieldset', + '#title' => t('Language prefix'), + '#collapsible' => TRUE, + '#collapsed' => TRUE, + '#description' => t('Note: If you wish comparability with navigation mode (without language prefix), when module i18n is disabled, disable settings.'), + ); + $form['prefix']['i18n_prefix_default'] = array( + '#type' => 'radios', + '#title' => t('Language prefix for default language'), + '#default_value' => variable_get('i18n_prefix_default', 0), + '#options' => array(t('Disabled'), t('Enabled' )), + '#description' => t("Add a language prefix to Drupal paths when the current language is the default language. Some established sites or single language sites with default language is not English may wish to disable language prefix of Drupal paths when enabling i18n module."), + ); // Advanced options $form['advanced'] = array( '#type' => 'fieldset', *************** *** 430,447 **** * Get language from browser settings, but only if it is a valid language */ function i18n_get_browser_lang() { - $languages = i18n_supported_languages(); - $exploded_server = explode(";", $_SERVER["HTTP_ACCEPT_LANGUAGE"]); - $accept=explode(',', array_shift($exploded_server)); - foreach ($accept as $lang) { - if(empty($lang)) { - continue; - } elseif (array_key_exists($lang, $languages)) { - return $lang; - } elseif (array_key_exists(substr($lang, 0, 2), $languages)) { - return substr($lang, 0, 2); } } } /** --- 452,473 ---- * Get language from browser settings, but only if it is a valid language */ function i18n_get_browser_lang() { + static $browser_lang; + if (!isset($browser_lang)) { + $languages = i18n_supported_languages(); + $exploded_server = explode(";", $_SERVER["HTTP_ACCEPT_LANGUAGE"]); + $accept = explode(',', array_shift($exploded_server)); + $browser_lang = ''; + foreach ($accept as $lang) { + if (($lang = @trim($lang)) && + (array_key_exists(($lang = strtolower($lang)), $languages) + || array_key_exists(($lang = substr($lang, 0, 2)), $languages))) { + $browser_lang = $lang; + break; + } } } + return $browser_lang; } /** *************** *** 455,466 **** $exploded_path = explode('/', $path); $maybelang = array_shift($exploded_path); $languages = i18n_languages(); - if (array_key_exists($maybelang, $languages)){ - if ($trim) { - $path = trim(substr($path, strlen($maybelang)),'/'); } - return $maybelang; } } /** --- 481,536 ---- $exploded_path = explode('/', $path); $maybelang = array_shift($exploded_path); $languages = i18n_languages(); + if (array_key_exists($maybelang, $languages)) { + $last_lang = ''; + $exploded_path_exists = count($exploded_path); + foreach ($exploded_path as $k => $alt_lang) { + if (!array_key_exists($alt_lang, $languages)) { + break; + } + $last_lang = $alt_lang; + unset($exploded_path[$k]); } + + // Normal Case + // /uk => /uk + if (!$exploded_path) { + // Redirect for frontpage with many lang prefix + // /uk/en/fr/ru => /uk + if ($exploded_path_exists) { + _i18n_goto($maybelang); + } + $path = $trim ? '' : $maybelang; + } + + // Redirect for page with many lang prefix + // 1. Translation if is node or taxonomy + // /uk/ru/en/bla_bla => /en/bla_bla => /uk/bla_bla + // 2. Or change lang + // /uk/ru/en/bla_bla => /uk/bla_bla + elseif ($last_lang) { + $new_path = join('/', $exploded_path); + $last_lang_new_path = $last_lang .'/'. $new_path; + if ($last_lang_new_path == ($new_path = drupal_get_normal_path($last_lang_new_path))) { + $new_path = drupal_get_normal_path($new_path); + } + if (module_exists('translation') && function_exists('translation_url')) { + $new_path = translation_url($new_path, $maybelang); + } + _i18n_goto($new_path); + } + + // Normal Case: + // 1. Without lang prefix: /en/bla_bla => /bla_bla + elseif ($trim) { + $path = substr($path, strlen($maybelang) + 1); + } + // 2. With lang prefix: /en/bla_bla => /en/bla_bla + // else {} + } else { + $maybelang = ''; // NO Language code. } + return $maybelang; } /** *************** *** 468,475 **** * This function will search for aliases like 'en/home', 'es/home'... */ function i18n_frontpage($lang = NULL) { - $lang = $lang ? $lang : _i18n_get_lang(); - return i18n_get_normal_path($lang.'/'.variable_get('site_frontpage','node')); } /** --- 538,552 ---- * This function will search for aliases like 'en/home', 'es/home'... */ function i18n_frontpage($lang = NULL) { + static $paths = array(); + $lang = $lang ? strtolower(@trim($lang)) : _i18n_get_lang(); + if (!isset($paths[$lang])) { + $path = _i18n_add_lang_prefix($lang) + ? $lang.'/'.variable_get('site_frontpage','node') + : variable_get('site_frontpage','node'); + $paths[$lang] = i18n_get_normal_path($path); + } + return $paths[$lang]; } /** *************** *** 506,522 **** */ function i18n_path($path, $lang) { if (!$path || $path == i18n_frontpage($lang)) { - return $lang; - } elseif($alias = drupal_lookup_path('alias', $path)) { - if($prefix = i18n_get_lang_prefix($alias)) { - // This alias will be valid only if it has the same language - return ($prefix == $lang) ? $alias : $lang.'/'.$path; - } else { // Alias without language prefix - return $lang.'/'.$alias; - } - } else { // Alias for language path will be searched later - return $lang.'/'.$path; - } } /** --- 583,597 ---- */ function i18n_path($path, $lang) { if (!$path || $path == i18n_frontpage($lang)) { + return _i18n_add_lang_prefix($lang) ? $lang : ''; + } + if(($alias = drupal_lookup_path('alias', $path)) && (!($prefix = i18n_get_lang_prefix($alias, TRUE)) || ($prefix && $prefix == $lang))) { + $path = $alias; + } + if (_i18n_add_lang_prefix($lang)) { + $path = $lang .'/'. $path; + } + return $path; } /** *************** *** 567,572 **** $path = ''; } $names = $names ? $names : i18n_languages('native'); foreach (array_keys(i18n_supported_languages()) as $lang){ $links[$lang]= theme('i18n_link', $names[$lang], i18n_path($path, $lang), $lang, $query); } --- 642,648 ---- $path = ''; } $names = $names ? $names : i18n_languages('native'); + $links = array(); foreach (array_keys(i18n_supported_languages()) as $lang){ $links[$lang]= theme('i18n_link', $names[$lang], i18n_path($path, $lang), $lang, $query); } *************** *** 706,713 **** * Rewrites path with current language and removes prefix if searching for source path */ function i18n_url_rewrite($type, $path, $original){ - if ($type == 'alias' && !strpos($path, '://') && !i18n_get_lang_prefix($path)){ - return $path ? i18n_get_lang() . '/'. $path : i18n_get_lang(); } elseif ($type == 'source') { if ($path == $original) { return i18n_get_normal_path($path); --- 782,789 ---- * Rewrites path with current language and removes prefix if searching for source path */ function i18n_url_rewrite($type, $path, $original){ + if ($type == 'alias' && !strpos($path, '://') && !i18n_get_lang_prefix($path) && _i18n_add_lang_prefix(($cur_lang = i18n_get_lang()))) { + return $path ? $cur_lang .'/'. $path : $cur_lang; } elseif ($type == 'source') { if ($path == $original) { return i18n_get_normal_path($path); *************** *** 1205,1209 **** * Cannot use $_GET["q"] cause it may have been already changed */ function _i18n_get_original_path() { - return isset($_REQUEST["q"]) ? trim($_REQUEST["q"],"/") : ''; } --- 1281,1308 ---- * Cannot use $_GET["q"] cause it may have been already changed */ function _i18n_get_original_path() { + static $path; + if (!isset($path)) { + $path = isset($_REQUEST["q"]) ? trim($_REQUEST["q"],"/") : ''; + } + return $path; + } + + /** + * Case when add language prefix for Drupal path. + * + * @param string $lang + * Language. + * + * @return bool + * TRUE when need add language prefix for language, or FALSE. + */ + function _i18n_add_lang_prefix($lang){ + static $languages = array(); + if (!isset($languages[$lang])) { + $default = i18n_default_language(); + $current = i18n_get_lang(); + $languages[$lang] = (!(!variable_get('i18n_prefix_default', 0) && $lang == $default)) || ($current != $default); + } + return $languages[$lang]; }