Problem: in Drupal 7 if you enable language support, add a couple of languages and add content in them, you cannot actually enable a language switcher or use language dependent URLs until you go and configure it manually. You can enable the language switcher block but it will not show up. The language selection (negotiation) settings are empty at the start, so the default language is used at all times.

Proposal: default the language negotiation settings to URL path prefix, so that the most commonly used (and out-of-the-box workable) solution is the default, which makes working with languages easy right away. Only those who are not fine with this setting will need to go and configure language settings. We'd lead ith sensible defaults for the 80%.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

Bojhan’s picture

Wait, does this mean on install someone needs to specify multilingual or not?

Gábor Hojtsy’s picture

Well, it would mean that either (a) we add the default foreign language without a path prefix or (b) your new foreign single language site will have a path prefix until you kill this setting. I think (a) is more likely :)

Gábor Hojtsy’s picture

Issue tags: +Usability, +D8MI
Gábor Hojtsy’s picture

Project: Localization update » Drupal core
Version: 7.x-1.x-dev » 8.x-dev
Component: Code » language system

Fix project/component.

Gábor Hojtsy’s picture

Yes, we should add the default foreign language without a prefix when installed in a foreign language. Then having the path prefix based negotiation has no effect until you add another language, when there needs to be some differentiator, which is going to be the path. Then without extra configuration, the added language would work right away (ie. language switcher block, etc). This removes an extra step and a sizable area to understand from language configuration, making language setup way easier, so it is going to be a huge plus IMHO. To reiterate, the tasks are:

1. When Drupal is installed make sure there is only one language added. If its the default English, make sure it has no prefix set. When it is some foreign language, make sure it has no prefix either. If it is a foreign language, we should not have English there at all.
2. Configure language negotiation with the URL based method and path prefixes.

Gábor Hojtsy’s picture

This is probably much easier to implement once #1301460: Decouple domain/path language negotiation storage from language config storage lands (which is hopefully soon).

Gábor Hojtsy’s picture

That landed, so now this should be pretty simple to do. :) Any takers?

fastangel’s picture

Assigned: Unassigned » fastangel

I work in this issue.

Regards.

fastangel’s picture

Hi,

I am working how implements this feature. I have a small question. In the default profile the module locale is not active. Then the prefix and negotation isn't active. Does it make sense then put prefix in the install?

Regards.

Gábor Hojtsy’s picture

@fastangel: well, this issue is about the installation of locale.module that handles the negotiation configuration. So when locale_install() is called, it would set up a default negotiation config that is not empty. In Drupal 7 the default config is empty, so you can keep adding languages but never be able to switch to them, since there is no URL or other setup that can be used to access them. If we default to URL path prefix negotiation when locale module is installed (and the initial language is saved with an empty prefix), the initial behavior is still identical to how Drupal 7 worked, that is the default language is used and no changes are made to the URLs, but when you add a second, third, etc. language, those would work right away since they get their prefixes.

So the idea here is to have smarter defaults for the user and make the system work better out of the box without compromising the initial simplicity of the system and the URLs backward compatibility when locale is installed.

Did this explanation help?

fastangel’s picture

Ok. I think you understand better. When active module locale in function install I must turn negotiation with url (Option URL in admin/config/regional/language/configure). Taking intoaccount the restrictions discussed (

1. When Drupal is installed make sure there is only one language added. If its the default English, make sure it has no prefix set. When it is some foreign language, make sure it has no prefix either. If it is a foreign language, we should not have English there at all.
2. Configure language negotiation with the URL based method and path prefixes.

).
In short, the restrictions is that prefix is empty in all languages.

Is the right thing to say?

Regards

Gábor Hojtsy’s picture

When locale is installed, it already ensures the prefixes are set up as discussed, see locale_install().

fastangel’s picture

Status: Active » Needs review
FileSize
901 bytes

Attach patch. I put the code in locale_enabled because locale_install already not exists (In one of your most recent patches are removed).

Regards.

Status: Needs review » Needs work

The last submitted patch, locale-1280538-1.patch, failed testing.

Gábor Hojtsy’s picture

@fastangel: do you expect a module to change settings when you disable and then enable it?

Gábor Hojtsy’s picture

I'll answer my own question then. No, you don't want to have your settings change when you disable and then enable a module. The code in locale_enable() merely updated locale module's settings to the new realities of a language list that might have changes inbetween locale module not being enabled and language module being enabled.

So let's do this in a locale_install() instead. Then we should look at which tests fail and update the tests for the new assumptions for language negotiation preconfiguration IMHO.

fastangel’s picture

Sorry for my late response :( . I am working on it.

Regards.

Gábor Hojtsy’s picture

@fastangel: any updates?

fastangel’s picture

Status: Needs work » Needs review
FileSize
971 bytes

@Gábor: Attached new patch with implement in locale_install. If there is any test to pass I start to work on it. Sorry about the time but I have been a few days away. Already back with renewed vigor. :D

Status: Needs review » Needs work

The last submitted patch, locale-1280538-2.patch, failed testing.

fastangel’s picture

I work in the pass the test.

fastangel’s picture

Status: Needs work » Needs review
FileSize
2.21 KB

Hi,

I attached a new patch. I have a one question. For test Translation functionality I don't know how to fix it.

Regards.

Status: Needs review » Needs work

The last submitted patch, locale-1280538-3.patch, failed testing.

Gábor Hojtsy’s picture

@fastangel: url() should never get the language code prefix like in your change. I'll ask @plach to help you out since that seems like the most time effective :) He is the architect behind the language negotiation system :)

plach’s picture

Status: Needs work » Needs review
FileSize
1.41 KB

This should be ok, tests yet to be fixed.

We should not need to care about prefixes since they are ignored on monolingual sites and multilingual ones with all prefixed languages work just fine.

Status: Needs review » Needs work

The last submitted patch, locale-1280538-25.patch, failed testing.

Gábor Hojtsy’s picture

@plach: I don't really understand this code comment:

+  // Since we cannot rely on language negotiation hooks here, **as any module
+  // implementing them cannot be enabled yet**, language_negotiation_set() cannot
+  // be used.

Emphasis mine. Also, I assume the test fails are due to how the tests assumed a pristine negotiation environment, and they should not assume that anymore, right?

plach’s picture

Well, language_negotiation_set() relies on hook_language_negotiation_info() definitions: the URL detection method is defined in locale.module which is not enabled yet, hence we must replicate its logic manually.

Also, I assume the test fails are due to how the tests assumed a pristine negotiation environment, and they should not assume that anymore, right?

Didn't look at those yet, just tested the patch manually and it seemed to work well. I guess some tests currently don't expect a prefixed URL.

Gábor Hojtsy’s picture

So the comment would be more like this?

+  // We cannot rely on language negotiation hooks here, because locale module is not 
+  // enabled yet. Therefore language_negotiation_set() cannot be used.
plach’s picture

Yes :)

Gábor Hojtsy’s picture

Status: Needs work » Needs review
FileSize
2.97 KB

Here is a slightly updated patch. It fixes the comment that I noted and also a test in locale.test. I was debugging the UI language test when I figured out that the approach taken might not be good. Your code seems to set up all language types to have URL negotiation only, right? That kills the fallback negotiation setup that is default for "hidden" types, no? That is what I'm seeing with the testUrlLanguageFallback() test in locale.test I assume. Is that not the case?

plach’s picture

Your code seems to set up all language types to have URL negotiation only, right? That kills the fallback negotiation setup that is default for "hidden" types, no?

No, it should update only configurable language types, i.e. currently only UI language. When entity translation lands we might want to switch on content language too, and that code would be future-proof.

Status: Needs review » Needs work

The last submitted patch, locale-1280538-31.patch, failed testing.

Gábor Hojtsy’s picture

Status: Needs work » Needs review
FileSize
6.88 KB

Ok, then we need to pass a language in $options for url() that would generate a language independent URL, so that we can get a URL that is useful for detection testing without an URL component to it. Added that fix in the patch.

Also looked into the path test failure and tracked it down to http://api.drupal.org/api/drupal/core--modules--locale--locale.module/fu... calls locale_language_url_rewrite_url() properly but then that function has a static cache of languages that was not cleared, so it was not yet aware of French being present and available. Fixed that too.

Finally, in the translation module tests, Italian is originally used as a disabled language to use for assigning to content. Then it is enabled so it shows up in the language switcher blocks. But the simpletest-side caches are not cleared there either, so the path being looked for is not properly constructed, which made the tests fail for the previously disabled language. If we clear the static caches proper after enabling Italian, then these pass too.

(While debugging I also found a $language in url() that is in fact a language code. It in fact uses $language first for an object then re-assigns to a langcode. That should have been a $langcode, so modified that too.)

Attached patch should now pass all tests. Reviews please!

Gábor Hojtsy’s picture

Assigned: fastangel » Unassigned
plach’s picture

Status: Needs review » Reviewed & tested by the community

Looks good!

Dries’s picture

Committed to 8.x. Thanks.

Dries’s picture

Status: Reviewed & tested by the community » Fixed
Gábor Hojtsy’s picture

Added a changelog entry at http://drupal.org/node/1413776 to document this for site builders and test authors.

Gábor Hojtsy’s picture

Issue tags: +language-base

Tagging for base language system.

Gábor Hojtsy’s picture

Issue tags: +negotiation

Tagging for language negotiation too.

Automatically closed -- issue fixed for 2 weeks with no activity.

Anonymous’s picture

Issue summary: View changes

Concise summary of the goals.