Bug description
The control panel doesn't work with right-to-left languages.

In the screenshot you can see the site selector has been set to Hebrew and the multi-site selector has also been set to Hebrew in this example.
But as you can see the HTML direction attribute is still set to ltr.
The dashboard layout sets these attributes with a cpDirection() function
<!doctype html>
<html lang="{{ Statamic::cpLocale() }}" dir="{{ Statamic::cpDirection() }}" class="{{ $user->preferredTheme() === 'dark' ? 'dark' : '' }}">
<head>
@include('statamic::partials.head')
</head>
The cpDirection function calls cpLocale
// statamic/cms/src/Statamic.php
public static function cpLocale(): string
{
return config('app.locale');
}
public static function cpDirection()
{
return TextDirection::of(static::cpLocale());
}
But cpLocale function always returns English because the config is not dynamic
/*
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => 'en',
As the locale is set in the config, it doesn't get updated when the site selector changes to another language.
However the Sites facade has a method to access the selected site:
public function selected()
{
return $this->get(session('statamic.cp.selected-site')) ?? $this->default();
}
I can't call that in the cpDirection function because it is not a static function, but for testing I'm going to try return the currently selected site:
// statamic/cms/src/Statamic.php
public static function cpLocale(): string
{
return session('statamic.cp.selected-site') ?? config('app.locale');
}
public static function cpDirection()
{
return TextDirection::of(static::cpLocale());
}
After making that change the control panel has the correct html attributes:

But the CodeMirror editor is still not using the correct direction, it should look like this:

Here is the config for CodeMirror:
self.codemirror = CodeMirror(this.$refs.codemirror, {
...
direction: document.querySelector('html').getAttribute('dir') ?? 'ltr',
...
});
And the direction does seem to be set with a CodeMirror-rtl class but the text direction is not correct:

That is because each line is forced into ltr mode in the stylesheet

If we remove that css then everything works correctly:

Here is the css causing a conflict which comes from the codemirror css
// statamic/cms/resources/css/vendors/codemirror.css
.CodeMirror-rtl pre { direction: ltr; }
If you take a look at the current CodeMirror css it is as follows:
.CodeMirror-rtl pre { direction: rtl; }
So I do not know why the directions are different in Statamic vs CodeMirror.
If I force the css to rtl in my own css then it seems to work correctly:
// resources/css/cp.css
.CodeMirror-rtl pre {
direction: rtl !important;
}

In the Statamic CSS it is set to ltr
.CodeMirror-rtl pre { direction: ltr; }
and compared to the CodeMirror CSS
.CodeMirror-rtl pre { direction: rtl; }
Therefore to get the control panel to work correctly it would need to return the current selected site in cpDirection and cpLocale instead of the app locale in config... I am not sure if that will have any side effects.
And the css needs to be fixed, or each user will have to force the text direction in their own css. I am not sure if that will have any side effects for users that use CodeMirror for code editing instead of markdown.
How to reproduce
Shown above
Logs
No response
Environment
Environment
Laravel Version: 10.48.22
PHP Version: 8.2.24
Composer Version: 2.7.7
Environment: local
Debug Mode: ENABLED
URL: localhost:8000
Maintenance Mode: OFF
Cache
Config: NOT CACHED
Events: NOT CACHED
Routes: CACHED
Views: CACHED
Drivers
Broadcasting: null
Cache: file
Database: sqlite
Logs: stack / single
Mail: smtp
Queue: sync
Session: file
Statamic
Addons: 5
Sites: 27 (English, Arabic, Bulgarian, and 24 more)
Stache Watcher: Disabled
Static Caching: Disabled
Version: 5.30.0 PRO
Statamic Addons
statamic/collaboration: 1.0.0
statamic/eloquent-driver: 4.15.2
statamic/ssg: 3.0.2
stillat/relationships: 2.2.1
Statamic Eloquent Driver
Asset Containers: file
Assets: file
Blueprints: file
Collection Trees: file
Collections: file
Entries: file
Forms: file
Global Sets: file
Global Variables: file
Navigation Trees: file
Navigations: file
Revisions: file
Sites: file
Taxonomies: file
Terms: file
Tokens: file
Installation
Fresh statamic/statamic site via CLI
Additional details
This has been an issue #5942 (comment) that I mentioned two years ago but was not fixed correctly at the time. My translations have kept growing and the issue is having a huge impact on our operations as I have to manually set the text direction in the editor and add the translations myself instead of letting the rest of the team help.
If you believe there may be too many side effects then I have also previously suggested an alternate solution to only flip the text direction of the form fields without effecting the overall LTR direction of the control panel. #5942 (comment)
The ideal solution for us would be to not use the site-selector at all, but rather have the direction of the form fields and markdown field set when choosing a site in the Sites selector, however just getting the RTL text direction to actually work would be amazing.

Bug description
The control panel doesn't work with
right-to-leftlanguages.In the screenshot you can see the site selector has been set to Hebrew and the multi-site selector has also been set to Hebrew in this example.
But as you can see the HTML direction attribute is still set to
ltr.The dashboard layout sets these attributes with a
cpDirection()functionThe
cpDirectionfunction callscpLocaleBut
cpLocalefunction always returns English because the config is not dynamicAs the locale is set in the config, it doesn't get updated when the site selector changes to another language.
However the
Sitesfacade has a method to access the selected site:I can't call that in the
cpDirectionfunction because it is not a static function, but for testing I'm going to try return the currently selected site:After making that change the control panel has the correct html attributes:
But the CodeMirror editor is still not using the correct direction, it should look like this:
Here is the config for CodeMirror:
self.codemirror = CodeMirror(this.$refs.codemirror, { ... direction: document.querySelector('html').getAttribute('dir') ?? 'ltr', ... });And the direction does seem to be set with a
CodeMirror-rtlclass but the text direction is not correct:That is because each line is forced into
ltrmode in the stylesheetIf we remove that css then everything works correctly:
Here is the css causing a conflict which comes from the codemirror css
If you take a look at the current CodeMirror css it is as follows:
.CodeMirror-rtl pre { direction: rtl; }
So I do not know why the directions are different in Statamic vs CodeMirror.
If I force the css to
rtlin my own css then it seems to work correctly:In the Statamic CSS it is set to
ltr.CodeMirror-rtl pre { direction: ltr; }
and compared to the CodeMirror CSS
.CodeMirror-rtl pre { direction: rtl; }
Therefore to get the control panel to work correctly it would need to return the current selected site in
cpDirectionandcpLocaleinstead of the app locale in config... I am not sure if that will have any side effects.And the css needs to be fixed, or each user will have to force the text direction in their own css. I am not sure if that will have any side effects for users that use CodeMirror for code editing instead of markdown.
How to reproduce
Shown above
Logs
No response
Environment
Installation
Fresh statamic/statamic site via CLI
Additional details
This has been an issue #5942 (comment) that I mentioned two years ago but was not fixed correctly at the time. My translations have kept growing and the issue is having a huge impact on our operations as I have to manually set the text direction in the editor and add the translations myself instead of letting the rest of the team help.
If you believe there may be too many side effects then I have also previously suggested an alternate solution to only flip the text direction of the form fields without effecting the overall LTR direction of the control panel. #5942 (comment)
The ideal solution for us would be to not use the site-selector at all, but rather have the direction of the form fields and markdown field set when choosing a site in the Sites selector, however just getting the RTL text direction to actually work would be amazing.