Index: modules/locale/locale.module =================================================================== RCS file: /cvs/drupal/drupal/modules/locale/locale.module,v retrieving revision 1.293 diff -u -p -r1.293 locale.module --- modules/locale/locale.module 12 May 2010 08:26:14 -0000 1.293 +++ modules/locale/locale.module 2 Jul 2010 08:29:44 -0000 @@ -962,7 +962,11 @@ function locale_block_view($type) { function locale_url_outbound_alter(&$path, &$options, $original_path) { // Only modify internal URLs. if (!$options['external']) { - static $callbacks; + static $drupal_static_fast; + if (!isset($drupal_static_fast)) { + $drupal_static_fast['callbacks'] = &drupal_static(__FUNCTION__); + } + $callbacks = &$drupal_static_fast['callbacks']; if (!isset($callbacks)) { $callbacks = array(); @@ -990,6 +994,11 @@ function locale_url_outbound_alter(&$pat foreach ($callbacks as $callback) { $callback($path, $options); } + + // No language dependent path allowed in this mode. + if (empty($callbacks)) { + unset($options['language']); + } } } Index: modules/path/path.test =================================================================== RCS file: /cvs/drupal/drupal/modules/path/path.test,v retrieving revision 1.35 diff -u -p -r1.35 path.test --- modules/path/path.test 26 Mar 2010 12:37:30 -0000 1.35 +++ modules/path/path.test 2 Jul 2010 08:29:45 -0000 @@ -246,18 +246,12 @@ class PathLanguageTestCase extends Drupa $this->drupalLogin($web_user); // Enable French language. - $edit = array(); - $edit['langcode'] = 'fr'; - + $edit = array('langcode' => 'fr'); $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); - // Set language negotiation to "Path prefix with fallback". - include_once DRUPAL_ROOT . '/includes/locale.inc'; - variable_set('language_negotiation_' . LANGUAGE_TYPE_CONTENT, locale_language_negotiation_info()); - variable_set('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX); - - // Force inclusion of language.inc. - drupal_language_initialize(); + // Enable URL language detection and selection. + $edit = array('language[enabled][locale-url]' => 1); + $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings')); } /** @@ -303,6 +297,7 @@ class PathLanguageTestCase extends Drupa // Confirm that the alias is returned by url(). drupal_static_reset('language_list'); + drupal_static_reset('locale_url_outbound_alter'); $languages = language_list(); $url = url('node/' . $french_node->nid, array('language' => $languages[$french_node->language])); $this->assertTrue(strpos($url, $edit['path[alias]']), t('URL contains the path alias.')); @@ -334,13 +329,9 @@ class PathLanguageUITestCase extends Dru $this->drupalPost('admin/config/regional/language/add', $edit, t('Add language')); - // Set language negotiation to "Path prefix with fallback". - include_once DRUPAL_ROOT . '/includes/locale.inc'; - variable_set('language_negotiation_' . LANGUAGE_TYPE_CONTENT, locale_language_negotiation_info()); - variable_set('locale_language_negotiation_url_part', LOCALE_LANGUAGE_NEGOTIATION_URL_PREFIX); - - // Force inclusion of language.inc. - drupal_language_initialize(); + // Enable URL language detection and selection. + $edit = array('language[enabled][locale-url]' => 1); + $this->drupalPost('admin/config/regional/language/configure', $edit, t('Save settings')); } /** Index: modules/translation/translation.module =================================================================== RCS file: /cvs/drupal/drupal/modules/translation/translation.module,v retrieving revision 1.80 diff -u -p -r1.80 translation.module --- modules/translation/translation.module 6 Jun 2010 00:24:16 -0000 1.80 +++ modules/translation/translation.module 2 Jul 2010 08:47:23 -0000 @@ -177,23 +177,51 @@ function translation_form_alter(&$form, /** * Implements hook_node_view(). * - * Display translation links with native language names, if this node - * is part of a translation set. + * Display translation links with native language names, if this node is part of + * a translation set. If no language provider is enabled "fall back" to the + * simple links built through the result of translation_node_get_translations(). */ function translation_node_view($node, $view_mode) { - if (isset($node->tnid) && $translations = translation_node_get_translations($node->tnid)) { - $path = 'node/' . $node->nid; - $links = language_negotiation_get_switch_links(LANGUAGE_TYPE_INTERFACE, $path); - if (is_object($links)) { - $links = $links->links; - // Do not show link to the same node. - unset($links[$node->language]); - $node->content['links']['translation'] = array( - '#theme' => 'links__translation_node', - '#links' => $links, - '#attributes' => array('class' => array('links', 'inline')), - ); + // If the site has no translations or is not multilingual we have no content + // translation links to display. + if (isset($node->tnid) && drupal_multilingual() && $translations = translation_node_get_translations($node->tnid)) { + $languages = language_list('enabled'); + $languages = $languages[1]; + + // There might be a language provider enabled defining custom language + // switch links which need to be taken into account while generating the + // content translation links. As custom language switch links are available + // only for configurable language types and interface language is the only + // configurable language type in core and we use it as default. Contributed + // modules can change this behavior by setting the system variable below. + $type = variable_get('translation_language_type', LANGUAGE_TYPE_INTERFACE); + $custom_links = language_negotiation_get_switch_links($type, "node/$node->nid"); + $links = is_object($custom_links) ? $custom_links->links : array(); + + foreach ($translations as $langcode => $translation) { + // Do not show link to the same node or to translations in disabled + // languages. + if (isset($languages[$langcode]) && $langcode != $node->language) { + $language = $languages[$langcode]; + if (!isset($links[$langcode])) { + $links[$langcode] = array( + 'href' => "node/{$translation->nid}", + 'title' => $language->native, + 'language' => $language, + ); + } + $links[$langcode]['attributes'] = array('title' => $translation->title, 'class' => 'translation-link'); + } + else { + unset($links[$langcode]); + } } + + $node->content['links']['translation'] = array( + '#theme' => 'links__translation_node', + '#links' => $links, + '#attributes' => array('class' => array('links', 'inline')), + ); } } Index: modules/translation/translation.test =================================================================== RCS file: /cvs/drupal/drupal/modules/translation/translation.test,v retrieving revision 1.26 diff -u -p -r1.26 translation.test --- modules/translation/translation.test 6 Jun 2010 00:24:16 -0000 1.26 +++ modules/translation/translation.test 2 Jul 2010 09:42:30 -0000 @@ -14,12 +14,7 @@ class TranslationTestCase extends Drupal function setUp() { parent::setUp('locale', 'translation'); - } - - /** - * Create a basic page with translation, modify the basic page outdating translation, and update translation. - */ - function testContentTranslation() { + // Setup users. $admin_user = $this->drupalCreateUser(array('administer languages', 'administer content types', 'access administration pages')); $translator = $this->drupalCreateUser(array('create page content', 'edit own page content', 'translate content')); @@ -39,7 +34,13 @@ class TranslationTestCase extends Drupal $this->drupalLogout(); $this->drupalLogin($translator); + } + /** + * Create a basic page with translation, modify the basic page outdating + * translation, and update translation. + */ + function atestContentTranslation() { // Create Basic page in English. $node_title = $this->randomName(); $node_body = $this->randomName(); @@ -49,7 +50,7 @@ class TranslationTestCase extends Drupal $node_translation_title = $this->randomName(); $node_translation_body = $this->randomName(); $node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es'); - + // Attempt to submit a duplicate translation by visiting the node/add page // with identical query string. $languages = language_list(); @@ -84,6 +85,31 @@ class TranslationTestCase extends Drupal $this->drupalPost('node/' . $node_translation->nid . '/edit', $edit, t('Save')); $this->assertRaw(t('Basic page %title has been updated.', array('%title' => $node_translation_title)), t('Translated node updated.')); } + + /** + * Check that content translation links behave properly. + */ + function testContentTranslationLinks() { + // Create Basic page in English. + $node_title = $this->randomName(); + $node_body = $this->randomName(); + $node = $this->createPage($node_title, $node_body, 'en'); + + // Submit translation in Spanish. + $node_translation_title = $this->randomName(); + $node_translation_body = $this->randomName(); + $node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es'); + + // div[@id="node-'. $nid .'"] + $languages = language_list(); + $this->drupalGet("node/$node->nid"); + $url = url("node/$node_translation->nid"); + $this->assertFieldByXPath('//a[@href="'. $url .'"]', $languages['es']->native, t('Spanish translation link found.')); + + $this->drupalGet("node/$node_translation->nid"); + $url = url("node/$node->nid"); + $this->assertFieldByXPath('//a[@href="'. $url .'"]', $languages['en']->native, t('English translation link found.')); + } /** * Install a the specified language if it has not been already. Otherwise make sure that