diff options
Diffstat (limited to 'modules/locale/locale.module')
-rw-r--r-- | modules/locale/locale.module | 186 |
1 files changed, 154 insertions, 32 deletions
diff --git a/modules/locale/locale.module b/modules/locale/locale.module index f6968c093..e73eaf87b 100644 --- a/modules/locale/locale.module +++ b/modules/locale/locale.module @@ -12,6 +12,32 @@ * Gettext portable object files are supported. */ +/** + * The language is determined using a URL language indicator: + * path prefix or domain according to the configuration. + */ +define('LOCALE_LANGUAGE_NEGOTIATION_URL', 'locale-url'); + +/** + * The language is set based on the browser language settings. + */ +define('LOCALE_LANGUAGE_NEGOTIATION_BROWSER', 'locale-browser'); + +/** + * The language is determined using the current content language. + */ +define('LOCALE_LANGUAGE_NEGOTIATION_CONTENT', 'locale-content'); + +/** + * The language is set based on the user language settings. + */ +define('LOCALE_LANGUAGE_NEGOTIATION_USER', 'locale-user'); + +/** + * The language is set based on the request/session parameters. + */ +define('LOCALE_LANGUAGE_NEGOTIATION_SESSION', 'locale-session'); + // --------------------------------------------------------------------------------- // Hook implementations @@ -38,12 +64,10 @@ function locale_help($path, $arg) { case 'admin/config/regional/language/add': return '<p>' . t('Add all languages to be supported by your site. If your desired language is not available in the <em>Language name</em> drop-down, click <em>Custom language</em> and provide a language code and other details manually. When providing a language code manually, be sure to enter a standardized language code, since this code may be used by browsers to determine an appropriate display language.') . '</p>'; case 'admin/config/regional/language/configure': - $output = '<p>' . t("Language negotiation settings determine the site's presentation language. Available options include:") . '</p>'; - $output .= '<ul><li>' . t('<strong>None.</strong> The default language is used for site presentation, though users may (optionally) select a preferred language on the <em>My Account</em> page. (User language preferences will be used for site e-mails, if available.)') . '</li>'; - $output .= '<li>' . t('<strong>Path prefix only.</strong> The presentation language is determined by examining the path for a language code or other custom string that matches the path prefix (if any) specified for each language. If a suitable prefix is not identified, the default language is used. <em>Example: "example.com/de/contact" sets presentation language to German based on the use of "de" within the path.</em>') . '</li>'; - $output .= '<li>' . t("<strong>Path prefix with language fallback.</strong> The presentation language is determined by examining the path for a language code or other custom string that matches the path prefix (if any) specified for each language. If a suitable prefix is not identified, the display language is determined by the user's language preferences from the <em>My Account</em> page, or by the browser's language settings. If a presentation language cannot be determined, the default language is used.") . '</li>'; - $output .= '<li>' . t('<strong>Domain name only.</strong> The presentation language is determined by examining the domain used to access the site, and comparing it to the language domain (if any) specified for each language. If a match is not identified, the default language is used. <em>Example: "http://de.example.com/contact" sets presentation language to German based on the use of "http://de.example.com" in the domain.</em>') . '</li></ul>'; - $output .= '<p>' . t('The path prefix or domain name for a language may be set by editing the <a href="@languages">available languages</a>. In the absence of an appropriate match, the site is displayed in the <a href="@languages">default language</a>.', array('@languages' => url('admin/config/regional/language'))) . '</p>'; + $output = '<p>' . t("Language negotiation settings determine the site's content and presentation languages. For both <em>language types</em> there is a list of <em>language detection methods</em> which can be used to configure the desired language negotiation logic. Each detection method can be <em>dragged</em> to gain a higher priority, but it must be <em>enabled</em> to affect the language negotiation process. If a language detection method is applied then all the lower ones are <em>ignored</em>, otherwise the following one will be taken into account. Some lanaguage detection methods provide a configuration page to further specify their behavior. The <em>default</em> detection method is always applied, so anything below it is always ignored. <strong>Modifying this setting may break all incoming URLs and should be used with caution in a production environment.</strong>") . '</p>'; + $output .= '<p>' . t('Available options include:') .'</p>'; + $output .= '<ul><li>' . t('<strong>URL.</strong> The language is determined by examining the URL for a language code, a custom string, or a domain, that matches the ones (if any) specified for each language. The path prefix or domain name for a language may be set by editing the <a href="@languages">available languages</a>. In the absence of an appropriate match, the site is displayed in the <a href="@languages">default language</a>. A configuration is available to choose whether use the path prefix or the domain. <em>Example: "example.com/de/contact" sets language to German based on the use of "de" within the path. "http://de.example.com/contact" sets presentation language to German based on the use of "http://de.example.com" in the domain.</em>', array('@languages' => url('admin/config/regional/language'))) . '</li>'; + $output .= '<li>' . t('<strong>Session.</strong> The language is determined from a request/session parameter. A configuration is available to choose the URL parameter name to be used. <em>Example: "example.com?language=de" sets language to German based on the use of "de" within the "language" parameter.</em>') . '</li></ul>'; return $output; case 'admin/config/regional/translate': $output = '<p>' . t('This page provides an overview of available translatable strings. Drupal displays translatable strings in text groups; modules may define additional text groups containing other translatable strings. Because text groups provide a method of grouping related strings, they are often used to focus translation efforts on specific areas of the Drupal interface.') . '</p>'; @@ -103,6 +127,22 @@ function locale_menu() { 'file path' => 'includes', 'type' => MENU_LOCAL_TASK, ); + $items['admin/config/regional/language/configure/url'] = array( + 'title' => 'URL language provider configuration', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('locale_language_providers_url_form'), + 'access arguments' => array('administer languages'), + 'file' => 'locale.inc', + 'file path' => 'includes', + ); + $items['admin/config/regional/language/configure/session'] = array( + 'title' => 'Session language provider configuration', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('locale_language_providers_session_form'), + 'access arguments' => array('administer languages'), + 'file' => 'locale.inc', + 'file path' => 'includes', + ); $items['admin/config/regional/language/edit/%'] = array( 'title' => 'Edit language', 'page callback' => 'drupal_get_form', @@ -249,13 +289,13 @@ function locale_language_selector_form(&$form, &$form_state, $user) { ); // Get language negotiation settings. - $mode = variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE); + $mode = language_negotiation_get(LANGUAGE_TYPE_INTERFACE) != LANGUAGE_NEGOTIATION_DEFAULT; $form['locale']['language'] = array( '#type' => (count($names) <= 5 ? 'radios' : 'select'), '#title' => t('Language'), '#default_value' => $user_preferred_language->language, '#options' => $names, - '#description' => ($mode == LANGUAGE_NEGOTIATION_PATH) ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."), + '#description' => $mode ? t("This account's default language for e-mails, and preferred language for site presentation.") : t("This account's default language for e-mails."), ); } @@ -330,12 +370,97 @@ function locale_theme() { 'locale_languages_overview_form' => array( 'arguments' => array('form' => array()), ), + 'locale_languages_configure_form' => array( + 'arguments' => array('form' => array()), + ), 'locale_translation_filters' => array( 'arguments' => array('form' => array()), ), ); } +/** + * Implement hook_language_types_info(). + */ +function locale_language_types_info() { + return array( + LANGUAGE_TYPE_CONTENT => array( + 'name' => t('Content'), + 'description' => t('If a piece of content is available in multiple languages, the one matching the <em>content</em> language will be used.'), + ), + LANGUAGE_TYPE_INTERFACE => array( + 'name' => t('Interface'), + 'description' => t('The interface labels will be displayed in the <em>interface</em> language.'), + ), + LANGUAGE_TYPE_URL => array( + 'fixed' => array(LOCALE_LANGUAGE_NEGOTIATION_URL), + ), + ); +} + +/** + * Implement hook_language_negotiation_info(). + */ +function locale_language_negotiation_info() { + $file = 'includes/locale.inc'; + $providers = array(); + + $providers[LOCALE_LANGUAGE_NEGOTIATION_URL] = array( + 'types' => array(LANGUAGE_TYPE_CONTENT, LANGUAGE_TYPE_INTERFACE, LANGUAGE_TYPE_URL), + 'callbacks' => array( + 'language' => 'locale_language_from_url', + 'switcher' => 'locale_language_switcher_url', + 'url_rewrite' => 'locale_language_url_rewrite_url', + ), + 'file' => $file, + 'weight' => -8, + 'name' => t('URL'), + 'description' => t('The language is determined from the URL (Path prefix or domain).'), + 'config' => 'admin/config/regional/language/configure/url', + ); + + $providers[LOCALE_LANGUAGE_NEGOTIATION_SESSION] = array( + 'callbacks' => array( + 'language' => 'locale_language_from_session', + 'switcher' => 'locale_language_switcher_session', + 'url_rewrite' => 'locale_language_url_rewrite_session', + ), + 'file' => $file, + 'weight' => -6, + 'name' => t('Session'), + 'description' => t('The language is determined from a request/session parameter.'), + 'config' => 'admin/config/regional/language/configure/session', + ); + + $providers[LOCALE_LANGUAGE_NEGOTIATION_USER] = array( + 'callbacks' => array('language' => 'locale_language_from_user'), + 'file' => $file, + 'weight' => -4, + 'name' => t('User'), + 'description' => t('The language is determined from the language preference set in the user account.'), + ); + + $providers[LOCALE_LANGUAGE_NEGOTIATION_BROWSER] = array( + 'callbacks' => array('language' => 'locale_language_from_browser'), + 'name' => $file, + 'weight' => -2, + 'cache' => CACHE_DISABLED, + 'name' => t('Browser'), + 'description' => t('The language is determined from the browser\'s language settings.'), + ); + + $providers[LOCALE_LANGUAGE_NEGOTIATION_CONTENT] = array( + 'types' => array(LANGUAGE_TYPE_INTERFACE), + 'callbacks' => array('language' => 'locale_language_from_content'), + 'file' => $file, + 'weight' => 8, + 'name' => t('Content'), + 'description' => t('The interface language is the same as the negotiated content language.'), + ); + + return $providers; +} + // --------------------------------------------------------------------------------- // Locale core functionality @@ -625,39 +750,36 @@ function locale_css_alter(&$css) { * Implement hook_block_info(). */ function locale_block_info() { - $block['language-switcher']['info'] = t('Language switcher'); - // Not worth caching. - $block['language-switcher']['cache'] = DRUPAL_NO_CACHE; + include_once DRUPAL_ROOT . '/includes/language.inc'; + $block = array(); + $info = language_types_info(); + foreach (language_types_configurable() as $type) { + $block[$type] = array( + 'info' => t('Language switcher (@type)', array('@type' => $info[$type]['name'])), + // Not worth caching. + 'cache' => DRUPAL_NO_CACHE, + ); + } return $block; } /** * Implement hook_block_view(). * - * Displays a language switcher. Translation links may be provided by other modules. - * Only show if we have at least two languages and language dependent - * web addresses, so we can actually link to other language versions. + * Displays a language switcher. Only show if we have at least two languages. */ -function locale_block_view($delta = '') { - if (variable_get('language_count', 1) > 1 && variable_get('language_negotiation', LANGUAGE_NEGOTIATION_NONE) != LANGUAGE_NEGOTIATION_NONE) { +function locale_block_view($type) { + if (variable_get('language_count', 1) > 1) { $path = drupal_is_front_page() ? '<front>' : $_GET['q']; - $languages = language_list('enabled'); - $links = array(); - foreach ($languages[1] as $language) { - $links[$language->language] = array( - 'href' => $path, - 'title' => $language->native, - 'language' => $language, - 'attributes' => array('class' => array('language-link')), - ); + $links = language_negotiation_get_switch_links($type, $path); + + if (isset($links->links) && count($links->links > 1)) { + $class = "language-switcher-{$links->provider}"; + $variables = array('links' => $links->links, 'attributes' => array('class' => array($class))); + $block['content'] = theme('links', $variables); + $block['subject'] = t('Languages'); + return $block; } - - // Allow modules to provide translations for specific links. - drupal_alter('translation_link', $links, $path); - - $block['subject'] = t('Languages'); - $block['content'] = theme('links', array('links' => $links, 'attributes' => array())); - return $block; } } |