No Code Attached Yet bug
avatar codealfa
codealfa
13 Apr 2023

Steps to reproduce the issue

Set "Language Selection for new Visitors => Site Language" in the System - Language Filter plugin on a multilanguage site. If the global Document object is created before the PlgSystemLanguageFilter::parseRule function runs, then the Document object doesn't get updated with the detected language, and the lang attribute on the <html> tag always shows the default language, adversely affecting SEO.

You can reproduce this by creating the global Document object early in the page's life cycle, for example, just adding Factory::getDocument() to the onAfterInitialize function in the Language Filter plugin.

Expected result

When you use the Language Switcher Module to select another language, the lang attribute in the HTML tag should be updated to reflect the chosen language. For e.g., for French, <html lang="fr-fr" dir="ltr">, for Spanish, <html lang="es-es" dir="ltr">, etc.

Actual result

Using the Language Switcher changes the language on the site, but the lang and dir attributes in the HTML source will always show the site's default language when the Document object is created early, e.g., <html lang="en-gb" dir="ltr">, when the page is accessed at https://www.example.com/fr/.

System information (as much as possible)

Ubuntu 22.04
Chrome 112
Joomla 4.2.9
PHP 8.1.17

Additional comments

As the user adds extensions to his site, this will likely break, as any extension can create the Document object at any time.

I can get this to work by updating the global Document when the language is parsed. I updated this section of the code in the PlgSystemLanguageFilter::parseRule function:

       if ($language->getTag() !== $lang_code) {
            $language_new = Language::getInstance($lang_code, (bool) $this->app->get('debug_lang'));

            foreach ($language->getPaths() as $extension => $files) {
                if (strpos($extension, 'plg_system') !== false) {
                    $extension_name = substr($extension, 11);

                    $language_new->load($extension, JPATH_ADMINISTRATOR)
                    || $language_new->load($extension, JPATH_PLUGINS . '/system/' . $extension_name);

                    continue;
                }

                $language_new->load($extension);
            }

            Factory::$language = $language_new;
            $this->app->loadLanguage($language_new);

            //I add the following lines
            $this->app->loadDocument();
            $document = $this->app->getDocument();

            $document->setLanguage($language_new->getTag());
            $document->setDirection($language_new->isRtl() ? 'rtl' : 'ltr');

            $this->app->loadDocument($document);
        }

However, there may be a better fix. This just addresses the current situation I encountered.

Votes

# of Users Experiencing Issue
3/3
Average Importance Score
5.00

avatar codealfa codealfa - open - 13 Apr 2023
avatar codealfa codealfa - change - 13 Apr 2023
Labels Removed: ?
avatar joomla-cms-bot joomla-cms-bot - change - 13 Apr 2023
Labels Added: No Code Attached Yet
avatar joomla-cms-bot joomla-cms-bot - labeled - 13 Apr 2023
avatar Zamarza
Zamarza - comment - 14 Apr 2023

Hi,

it is a very important bug that Samuel solves.
My website is multilangual. I got the problem. I could not use the cache for my pages.
With that correction, it works fine now.
I hope the bug will be corrected in the next release. For me it appears to be a high level bug.
Thanks for your help.


This comment was created with the J!Tracker Application at issues.joomla.org/tracker/joomla-cms/40380.

avatar Hackwar Hackwar - change - 24 Aug 2023
Labels Added: bug
avatar Hackwar Hackwar - labeled - 24 Aug 2023

Add a Comment

Login with GitHub to post a comment