My site's default language is Finnish but I need to use English for admin pages. There should be next to Default language option the second one where user could choose the admin language. I tried also to change language from my user account but it didn't make any change (bug?).

Files: 
CommentFileSizeAuthor
#62 admin-user-interface-language-option-322995-62.patch12.07 KBpenyaskito
PASSED: [[SimpleTest]]: [MySQL] 40,717 pass(es). View
#60 admin-user-interface-language-option-322995-60.patch12.5 KBpenyaskito
FAILED: [[SimpleTest]]: [MySQL] Invalid PHP syntax in core/modules/language/language.admin.inc. View
#58 admin-user-interface-language-option-322995-58.patch13.25 KBwebflo
PASSED: [[SimpleTest]]: [MySQL] 40,633 pass(es). View
#58 admin-user-interface-language-option-322995-58.interdiff.txt668 byteswebflo
#57 admin-user-interface-language-option-322995-57.patch13.24 KBwebflo
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View
#54 admin-user-interface-language-option-322995-54.patch15.82 KBwebflo
PASSED: [[SimpleTest]]: [MySQL] 40,635 pass(es). View
#54 admin-user-interface-language-option-322995-54.interdiff.txt1.68 KBwebflo
#51 admin-user-interface-language-option-322995-51.patch15.61 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,640 pass(es). View
#48 46-48.txt4.09 KBSchnitzel
#48 admin-user-interface-language-option-322995-48.patch12.04 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View
#46 admin-user-interface-language-option-322995-46.patch13.58 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,642 pass(es). View
#44 admin-user-interface-language-option-322995-44.patch13.41 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,641 pass(es). View
#44 38-44.txt5.33 KBSchnitzel
#44 admin | drupal8-1.jpg112.66 KBSchnitzel
#44 Languages | drupal8-1.jpg427.81 KBSchnitzel
#42 Languages | drupal8.jpg435.62 KBSchnitzel
#42 admin | drupal8.jpg353.98 KBSchnitzel
#38 admin-user-interface-language-option-322995-38.patch11.7 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,641 pass(es). View
#38 37-38.txt5.43 KBSchnitzel
#37 admin-user-interface-language-option-322995-37.patch6.87 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View
#35 32-53.txt2.97 KBSchnitzel
#35 admin-user-interface-language-option-322995-35.patch6.87 KBSchnitzel
PASSED: [[SimpleTest]]: [MySQL] 40,631 pass(es). View
#32 admin-user-interface-language-option-322995-32.patch6.84 KBc31ck
PASSED: [[SimpleTest]]: [MySQL] 40,568 pass(es). View
#30 admin-user-interface-language-option-322995-30.patch6.97 KBc31ck
FAILED: [[SimpleTest]]: [MySQL] 40,515 pass(es), 50 fail(s), and 28 exception(s). View
#28 admin-user-interface-language-option-322995-28.patch6.9 KBc31ck
FAILED: [[SimpleTest]]: [MySQL] 40,566 pass(es), 0 fail(s), and 20 exception(s). View

Comments

silverwing’s picture

Priority: Critical » Normal

Old Issue, but it's a good question - admin in different language? Available, or move to D8?

dddave’s picture

Solution in contrib:

http://drupal.org/project/admin_language

Feature request for D8?

dddave’s picture

Version: 6.5 » 8.x-dev

Should this live in contrib? If so please set to closed(fixed).

Gábor Hojtsy’s picture

You can certainly set your user preferred language to whatever language you want and browse the site in that language. That sounds like the easiest, no extra module required :)

Gábor Hojtsy’s picture

plach’s picture

In D7 it is possible to move the user language detection method on top and having it prevale over URL language. This allows an admin user to set her preferred interface language. I ain't sure we need something more advanced in D8.

Gábor Hojtsy’s picture

Looks like http://drupal.org/project/admin_language sets one global admin language for the whole site. Is that generally accurate? Thinking about this, it sounds like this would be per-user, so that a multilingual site can be managed by people in their own language. I assume the problems solved here include that the language changes when you hit a node that you want to translate for example, from where admin links would get to keep that modified language, that is not desired. I agree it is probably easy to implement per site instead of per user though, given that if we implement per user, it becomes a problem to display the admin language selector to some people on their profile but not to others. It is hard to tell generally if someone has "some kind of admin access" or not.

Maybe we should think of this as a second session language provider that only applies to admin pages (with a block specific for that to let admins set it?). Blocks don't work well with the Seven theme though... Well, just thinking out loud here :)

plach’s picture

My current personal recipe for the scenario described in #7 is:

  • enable content language negotiation (for instance by enabling Entity Translation)
  • configure interface language detection: user, URL
  • configure content language detection: URL
  • enable the content language switcher block globally

If I wish to have the possibiliy to switch even interface language:

  • configure interface language detection: Session, user, URL
  • configure content language detection: URL
  • enable the content language switcher block globally
  • enable the interface language switcher block only for the admin roles

My main doubt is: do we need some usability improvement to make clear that all of this is actually possibile?

Another possibility might introducing a Role language provider that would allow to configure a language for each available role. But all of this looks to me fairly complex to setup for the average user.

Gábor Hojtsy’s picture

Marked #744656: No translations for admin interface and #289114: Set different presentation language for Admin only as duplicates. There is clearly *lots* of interest in this.

Gábor Hojtsy’s picture

Fascinatingly also closed down #427782: All English has gone RTL? as duplicate. Huh.

plach’s picture

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

@plach: I think your suggestions from #8 are not entirely good in that they have front-end consequences, when the requestors only want their admin language changed, not to have users fiddle with language changes persisting in their sessions.

LarsKramer’s picture

Subscribing.
It should also be possible to hide the admin language from "Language settings" on the user edit account form if the admin language is not one of the "public" languages. And if the site is a single language site where the admin language is different from the default language, it should be possible to hide "Language Settings".

LarsKramer’s picture

A new 7.x-1.x-dev version of Administration Language has just been released fixing some of what I mentioned in #13.

And it has this feature request: #1239204: Use preferred language on per-user basis instead of global setting

Gábor Hojtsy’s picture

Title: Language For Admin option » Provide a distinct administration user interface language option

Retitling to better explain the feature request. I've pinged @wulff (the admin_language module maintainer) if he would be interested in integrating some of the module functionality in core. Looking at the code, it seems to be doing numerous other things, like optionally forcing language neutral nodes and path aliases which definitely sound unrelated.

Gábor Hojtsy’s picture

BTW I think the spec for this feature at its most basic form is a language provider that only kicks in for hook_admin_paths() paths, and provides a concrete language. Then this can be enabled on the UI like any other provider. A bonus for it providing a per-user configuration option as well for admin language. Where it gets tricky is that it would change the content language as well with our current default fallback method in core, so we'd need to expose those settings somehow to let people disconnect content from interface, which is the primary goal of this feature anyway.

plach’s picture

As I was writing in #1036212: Use hook_language_types_info() instead of hook_init() in D7, I think the admin language provider is the way to go too: it could set the default admin language using the user setting and falling back to the default admin language.

Where it gets tricky is that it would change the content language as well with our current default fallback method in core, so we'd need to expose those settings somehow to let people disconnect content from interface, which is the primary goal of this feature anyway.

The provider should be defined to be assignable only to the UI language. To actually take advantage of this we should make content language negotiation enabled by default in D8: node translation, if present, could exploit it through the tnode/1 feature we were speaking about in the last months.

plach’s picture

Issue tags: +D8MI

tagging

Gábor Hojtsy’s picture

@plach: it does sound like a usability problem if we need to expose both interface and content language config separately in D8, that does not sound like good news. However, I see that trying to not inherit to content language if it was picked by the admin language one would be a bad case of special casing that we should not pursue. Hm.

Charles Belov’s picture

The issue for me is that I am below survival level for both Spanish and Chinese for a trilingual website (with English as the main language and selected content translated). It is also possible we would be adding additional languages for which I know nothing. I may need to post content simply by somebody providing me a Word doc with the translation, and I just copy and paste. I want all interface content to be in English, but the content page would be marked as Spanish or Chinese and show up in Spanish or Chinese.

An anonymous viewer of the Spanish or Chinese page would see everything on the page entirely in that language except, of course, for the other-languages entries in the language-switcher block.

However a logged-in staff content-administering viewer would want to see Drupal interface links such as "Log out," "Edit," "Add new content" and the administrator menu in the logged-in viewer's preferred administration language, not in the content language.

plach’s picture

This should be already possible in D7 core: just enable the User language detection method on top of the URL one.

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.

Charles Belov’s picture

Actually, the other languages have just hit and it's likely to affect many U.S. local government transportation websites due to action by the Federal Transportation Administration. As part of U.S. Title VI of the Civil Rights act, the San Francisco Municipal Transportation Agency website is now going to have at least a few pages each in Arabic, French, Japanese, Korean, Italian, Russian, Thai, Vietnamese and possibly Tagalog. I have to be able to copy and paste content in those languages, as well as verify they can be viewed by an anonymous visitor, but manage that content using an English-language interface.

Gábor Hojtsy’s picture

Anybody want to work on this?

c31ck’s picture

Assigned: Unassigned » c31ck

I'll work on this.

c31ck’s picture

Tagging with sprint.

c31ck’s picture

Status: Active » Needs review
Issue tags: +sprint
FileSize
6.9 KB
FAILED: [[SimpleTest]]: [MySQL] 40,566 pass(es), 0 fail(s), and 20 exception(s). View

Initial patch that adds a language provider and allows a user to choose their admin language. Users can choose their admin language if they have the access administration pages permission and if the user admin language provider is enabled.

Status: Needs review » Needs work

The last submitted patch, admin-user-interface-language-option-322995-28.patch, failed testing.

c31ck’s picture

Status: Needs work » Needs review
FileSize
6.97 KB
FAILED: [[SimpleTest]]: [MySQL] 40,515 pass(es), 50 fail(s), and 28 exception(s). View

Attempt at fixing test failures.

vasi1186’s picture

Status: Needs review » Needs work

The patch looks pretty good to me, I have a small observation:

+++ b/core/modules/user/lib/Drupal/user/AccountFormController.phpundefined
@@ -224,6 +226,18 @@ abstract class AccountFormController extends EntityFormController {
+    if (user_access('access administration pages')) {
+      language_negotiation_include();
+      $form['language']['preferred_admin_langcode'] = array(
+        '#type' => 'language_select',
+        '#title' => t('Admin language'),
+        '#languages' => LANGUAGE_CONFIGURABLE,
+        '#default_value' => $user_preferred_admin_language->langcode,
+        '#description' => t("This account's preferred language for administration pages."),
+        '#access' => language_negotiation_method_enabled(LANGUAGE_NEGOTIATION_USER_ADMIN),
+      );

The language_negotiation_include() function is implemented by the language module, which is not a required core module, so I think this will generate a fatal error on the sites that have the language module disabled.

After a talk with Gabor, I think a better idea would be to just remove the language_negotiation check from the #access, so then you do not need to include the file anymore. The user_access call should also be called with the user account parameter. Also, you can move the "user_access('access administration pages')" into the #access and then the code will be just more straightforward.

c31ck’s picture

Status: Needs work » Needs review
FileSize
6.84 KB
PASSED: [[SimpleTest]]: [MySQL] 40,568 pass(es). View

I've removed the language_negotiation check and moved the user_access into the #access. Also, $account is now passed to user_access.

vasi1186’s picture

Status: Needs review » Needs work

Looks good to me now.

But, I think we now have another issue: the user_preferred_admin_language() function generates code duplication, because the almost exactly same code and comments can be found in user_preferred_language(). One solution would be to juse use the user_preferred_language() in both cases, and add a parameter, so you will end up in having something like:

function user_preferred_language($account, $type, $default = NULL) {
...
}

Then, inside the function, depending on the $type parameter, we will have to use (preferable in the most clever and flexible way) the right attribute. A good approach would be to use the $type parameter in a way that if you will add another type of language in the future, then the code in the user_preferred_language() should not change.

Schnitzel’s picture

Assigned: c31ck » Schnitzel
Schnitzel’s picture

Status: Needs work » Needs review
Issue tags: +Needs tests
FileSize
6.87 KB
PASSED: [[SimpleTest]]: [MySQL] 40,631 pass(es). View
2.97 KB

removed the user_preferred_admin_language() function and added a new parameter for user_preferred_language()

also needs tests!

webflo’s picture

You changed the parameters for user_preferred_language(). user_preferred_language() is used in a few places in core. I also prefere NULL as default value for $type.

  • core/includes/mail.inc
  • contact module
Schnitzel’s picture

FileSize
6.87 KB
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View

checked the rest of the core, user_preferred_language() is all the time called with 1 parameter, so no issue there.

But the default parameter NULL is a good idea.

Schnitzel’s picture

FileSize
5.43 KB
11.7 KB
PASSED: [[SimpleTest]]: [MySQL] 40,641 pass(es). View

discussed with @webflo and @gabor: that language_from_user_admin() and language_from_user() should check if the preferred language is a valid language. did this now.

also added 6 new tests for testing LANGUAGE_NEGOTIATION_USER_ADMIN and LANGUAGE_NEGOTIATION_USER

Schnitzel’s picture

tags

attiks’s picture

Status: Needs review » Needs work
Issue tags: -Needs change record +Needs tests

some missing dots

+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.phpundefined
@@ -196,6 +196,107 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
+    // Set preferred langcode for user to NULL

missing dot

+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.phpundefined
@@ -196,6 +196,107 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
+    // Set preferred langcode for user to unknown language

missing dot

+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.phpundefined
@@ -196,6 +196,107 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
+    // Set preferred admin langcode for user to NULL

missing dot

+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.phpundefined
@@ -196,6 +196,107 @@ class LanguageUILanguageNegotiationTest extends WebTestBase {
+    // Set preferred admin langcode for user to unknown language

missing dot at the end

Bojhan’s picture

Can this get a screenshot?

Schnitzel’s picture

FileSize
353.98 KB
435.62 KB

screenies

Bojhan’s picture

Schnitzel explained it to me, looks like we just need to fix some of the labeling.

http://drupal.org/files/admin%20%7C%20drupal8.jpg
On the account page, we want to remove the description and clarify the label a bit. This because "Admin Language" isn't very clear, people don't know what the "Admin" is. Therefor we suggest changing it to:

"Administration pages language"

This also means that we need to change Language, to "Site Language".

http://drupal.org/files/Languages%20%7C%20drupal8.jpg
Almost all the labels here are overly descriptive, it could probably be something like:

Language from the URL(Path prefix or domain)
Language from the requestion/session paramter
Account language setting.
Language from the browser's language setting.
Account administration pages language setting.
Default site language (English)

We have to figure out whether we want setting or preference, I am not sure what the standard is.

Schnitzel’s picture

Status: Needs work » Needs review
FileSize
427.81 KB
112.66 KB
5.33 KB
13.41 KB
PASSED: [[SimpleTest]]: [MySQL] 40,641 pass(es). View

fixxed codestyle and textadaptions

attiks’s picture

Status: Needs review » Needs work

I find the description a bit odd:

+++ b/core/modules/language/language.moduleundefined
@@ -388,8 +388,8 @@ function language_language_negotiation_info() {
+    'description' => t("Account site language setting."),

alternatives:
- Site language setting of the user.
- Site language setting of the user's account.

+++ b/core/modules/language/language.moduleundefined
@@ -419,6 +419,15 @@ function language_language_negotiation_info() {
+    'description' => t("Account administration pages language setting."),

- "Language setting of the user for the administration pages"
- "Administration pages language of the user"

+++ b/core/modules/language/language.negotiation.incundefined
@@ -162,6 +167,27 @@ function language_from_user($languages) {
+  // User preference (only for logged users).

only for authenticated users

+++ b/core/modules/user/lib/Drupal/user/AccountFormController.phpundefined
@@ -218,12 +220,20 @@ abstract class AccountFormController extends EntityFormController {
+      '#title' => t('Site Language'),

Site language (without a capital L)

Schnitzel’s picture

Status: Needs work » Needs review
FileSize
13.58 KB
PASSED: [[SimpleTest]]: [MySQL] 40,642 pass(es). View

thanks @atticks for the review. Also discussed the change and we both agree that Account is a bit confusing, but overall we say:

- I send a mail to an user
- An user makes changes in is account

So account makes more sense.

so fixxed the capital and "authenticated users"

webflo’s picture

Status: Needs review » Needs work
+++ b/core/modules/language/language.moduleundefined
@@ -367,7 +367,7 @@ function language_language_negotiation_info() {
-    'description' => t('Determine the language from the URL (Path prefix or domain).'),
+    'description' => t('Language from the URL (Path prefix or domain).'),

@@ -380,7 +380,7 @@ function language_language_negotiation_info() {
-    'description' => t('Determine the language from a request/session parameter.'),
+    'description' => t('Language from a request/session parameter.'),

@@ -388,8 +388,8 @@ function language_language_negotiation_info() {
-    'name' => t('User'),
-    'description' => t("Follow the user's language preference."),
+    'name' => t('Account'),
+    'description' => t("Account site language setting."),

@@ -398,7 +398,7 @@ function language_language_negotiation_info() {
-    'description' => t("Determine the language from the browser's language settings."),
+    'description' => t("Language from the browser's language settings."),

Lets rename this negotiation methods in follow-up issue.

+++ b/core/modules/language/language.negotiation.incundefined
@@ -150,10 +155,10 @@ function language_from_browser($languages) {
+  if ($user->uid && !empty($user->preferred_langcode) && array_key_exists($user->preferred_langcode, $languages)) {

@@ -162,6 +167,27 @@ function language_from_user($languages) {
+  if ($user->uid && !empty($user->preferred_admin_langcode) && array_key_exists($user->preferred_admin_langcode, $languages) && path_is_admin(current_path())) {

Why not just use isset($langauges[$user->preferred_language])?

+++ b/core/modules/user/user.moduleundefined
@@ -2962,14 +2962,24 @@ function theme_user_signature($variables) {
+  if (empty($type)) {

isset($type) is more accurate.

Schnitzel’s picture

Status: Needs work » Needs review
FileSize
12.04 KB
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View
4.09 KB

thanks for review, removed the textchanges and using isset()

Schnitzel’s picture

webflo’s picture

Status: Needs review » Needs work

I found one last issue.

+++ b/core/modules/user/user.installundefined
@@ -224,6 +224,13 @@ function user_schema() {
+        'not null' => TRUE,

@@ -475,5 +482,18 @@ function user_update_8003() {
+    'not null' => FALSE,

The db schema is not identical. The 'default' key is missing too.

Schnitzel’s picture

Status: Needs work » Needs review
FileSize
15.61 KB
PASSED: [[SimpleTest]]: [MySQL] 40,640 pass(es). View

thanks! fixed with using the same schema for update and install

webflo’s picture

Status: Needs review » Reviewed & tested by the community

Looks good now.

attiks’s picture

Status: Reviewed & tested by the community » Needs work

sorry missed it before

+++ b/core/modules/language/language.admin.incundefined
@@ -325,34 +325,34 @@ function language_admin_add_custom_form_validate($form, &$form_state) {
+  $language = (object) array(
+    'langcode' => $langcode,
+    'name' => $form_state['values']['name'],
+    'direction' => $form_state['values']['direction'],
+  );

better switch to using new Language()

+++ b/core/modules/language/language.admin.incundefined
@@ -325,34 +325,34 @@ function language_admin_add_custom_form_validate($form, &$form_state) {
+  $language = (object) array(
+    'langcode' => $langcode,
+  );

dito

webflo’s picture

Status: Needs work » Needs review
FileSize
1.68 KB
15.82 KB
PASSED: [[SimpleTest]]: [MySQL] 40,635 pass(es). View

Fixed the bugs mentioned by attiks.

Schnitzel’s picture

looks good, RTBC when green

Schnitzel’s picture

Status: Needs review » Reviewed & tested by the community
webflo’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
13.24 KB
PASSED: [[SimpleTest]]: [MySQL] 40,637 pass(es). View

Rebased against 8.x HEAD is much smaller now. Its only one submit handler (language_admin_add_form_submit) for predefined and custom languages.

webflo’s picture

FileSize
668 bytes
13.25 KB
PASSED: [[SimpleTest]]: [MySQL] 40,633 pass(es). View

And added the more descriptive strings for 46.

Schnitzel’s picture

Status: Needs review » Reviewed & tested by the community

the new patch is better now, so RTBC!

penyaskito’s picture

Assigned: Schnitzel » penyaskito
FileSize
12.5 KB
FAILED: [[SimpleTest]]: [MySQL] Invalid PHP syntax in core/modules/language/language.admin.inc. View

Rerolled.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, admin-user-interface-language-option-322995-60.patch, failed testing.

penyaskito’s picture

FileSize
12.07 KB
PASSED: [[SimpleTest]]: [MySQL] 40,717 pass(es). View

Duplicated use?

diff --git a/core/modules/language/language.admin.inc b/core/modules/language/language.admin.inc
index 2fadec7..b388986 100644
--- a/core/modules/language/language.admin.inc
+++ b/core/modules/language/language.admin.inc
@@ -7,7 +7,6 @@
 
 use Drupal\Core\Language\Language;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
-use Drupal\Core\Language\Language;
 
 /**
  * User interface for the language overview screen.
penyaskito’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, admin-user-interface-language-option-322995-62.patch, failed testing.

penyaskito’s picture

webchick’s picture

Status: Needs work » Needs review
Gábor Hojtsy’s picture

Status: Needs review » Reviewed & tested by the community

Thanks for the rerolls.

Dries’s picture

Status: Reviewed & tested by the community » Fixed
Issue tags: -Needs tests

This looks good. Committed to 8.x. Thanks.

Gábor Hojtsy’s picture

Added a site builders' change notice for this at http://drupal.org/node/1776768 - CHANGELOG.txt patch forthcoming from rvilar.

Gábor Hojtsy’s picture

Issue tags: -sprint

Changelog action happening in #1777870: Catch up changelog.txt with recent languages changes, removing off sprint. Thanks all!

Status: Fixed » Closed (fixed)

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

Gábor Hojtsy’s picture

Gábor Hojtsy’s picture

Issue summary: View changes

minor grammar changes

penyaskito’s picture

Assigned: penyaskito » Unassigned
Issue summary: View changes