Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Language string fallback problem when ini files are in different language folders #17272

Closed
b2z opened this issue Jul 26, 2017 · 12 comments
Closed

Comments

@b2z
Copy link
Member

b2z commented Jul 26, 2017

Steps to reproduce the issue

In custom extension en-GB file is located in language folder under extension folder like /components/com_component/language. Localisation languages are located the following way:

  • ru-RU file under /components/com_component/language
  • fr-FR file under /language

Imagine that we have language string COM_COMPONENT_TITLE_CONTROL_PANEL="Component: Control Panel" in en-GB file and translations in ru-RU and fr-FR files.
Now if we remove this string from ru-RU file we have a fallback to en-GB and it is displayed as Component: Control Panel.
If we remove this string from fr-FR file then we do not have a fallback and it is displayed as COM_COMPONENT_TITLE_CONTROL_PANEL.

Questions

Is it expected behavior and custom extensions should always distribute en-GB in JPATH_SITE(ADMIN)/language folder? Or it is a bug and should be fixed?

@laoneo
Copy link
Member

laoneo commented Jul 28, 2017

As far as I know there should always be a en-GB file. At least I ship for every of my extension such one.

@infograf768
Copy link
Member

infograf768 commented Jul 29, 2017

Do I understand well the matter by saying that you get the en-GB fallback when ru-RU is loaded but not when fr-FR is loaded (both files being present + the en-GB one ONLY in the extension language folder)?
Or that fr-FR is only present in the core language folders?

@infograf768
Copy link
Member

infograf768 commented Jul 30, 2017

I have tested here and I confirm the issue.
If the fr-FR ini file is placed in core language folders and one string is missing, then the en-GB file from the extension language folder is not loaded. Both have to be OR in the core language folder or in the extension language folder.
Something has changed in core as this was working before

@nikosdion
Could you have a look? That is an important bug.

@infograf768 infograf768 changed the title Language string fallback problem for extension language folder REGRESSION: Language string fallback broken Jul 30, 2017
@infograf768 infograf768 changed the title REGRESSION: Language string fallback broken Language string fallback problem Jul 30, 2017
@infograf768 infograf768 changed the title Language string fallback problem Language string fallback problem when ini files are in different language folders Jul 30, 2017
@infograf768
Copy link
Member

Code used for lang fallback is here if I remember well:
https://github.com/joomla/joomla-cms/blob/staging/libraries/src/Joomla/CMS/Language/Language.php#L719-L724

@nikosdion
Copy link
Contributor

I am not sure why you pinged me? All I have ever pointed out is that you can and should load both the translation and the en-GB file :D Anyway, I can help you navigate this issue.

Per the code I'm reading in the Language package the fallback is being detected in the same $basePath. In other words, if your $basePath is /components/com_component/language then Joomla! correctly shows an untranslated string if the en-GB file is not there. So, it boils down to how your component tells Joomla! to load language files, i.e. which $basePath to use.

That seems to come from Joomla\CMS\Component\ComponentHelper circa line 361. As we can see, Joomla! tries to load the language from the system-wide directory. If that fails (and only if it fails), it tries to load from the component directory.

The problem with this approach is that if you load the local language from the system wide directory BUT your default (en-GB) file exists only in the component directory then your en-GB file will never be loaded because of Boolean short circuit evaluation. Your en-GB file should always be in the system-wide directory for Joomla! to pick it up.

There's another caveat: loading the default language only takes place when Debug Language is set to No. If it's set to Yes then Joomla! will not load the default language. So if you have Debug Language set to Yes because you're debugging language issues, well, of course you'll see untranslated strings. This is what it's supposed to do.

I am not sure which of the two cases above is what happened to you, but I assume it's the first because it's not immediately evident. However, as far as I am aware this has always been the case of how Joomla! worked. Disclaimer: I always put my en-GB and localised files in the system-wide directories so I can't provide first hand experience. Sorry :(

If you want to force load all language files from both the system wide and the component directory you can change the ComponentHelper line I pointed out with two separate lines:

$lang->load($option, JPATH_BASE, null, false, true);
$lang->load($option, JPATH_COMPONENT, null, false, true);

The downsides are:

  • The component-specific language files override the system-wide files (which is probably the intended effect but you MUST document it)
  • If files do not exist in the component-specific files you have a slight performance impact while Joomla! is looking for the two files which don't exist. Considering that you only have a single component on the page that shouldn't be much (sub millisecond)

@Bakual
Copy link
Contributor

Bakual commented Jul 30, 2017

The component-specific language files override the system-wide files (which is probably the intended effect but you MUST document it)

The system ones have to override the component one (which is current behaviour). Eg a language pack has to override the files shipped with an extension.
So the lines would have to be the other way around and it would work I guess.

@b2z
Copy link
Member Author

b2z commented Jul 30, 2017

The problem with this approach is that if you load the local language from the system wide directory BUT your default (en-GB) file exists only in the component directory then your en-GB file will never be loaded because of Boolean short circuit evaluation. Your en-GB file should always be in the system-wide directory for Joomla! to pick it up.

@nikosdion thank you for explanation. Now it is clear and seems that it is not a bug.

@Bakual
Copy link
Contributor

Bakual commented Jul 30, 2017

@b2z actually, it is a bug. There should be no reason to install language files into the system language folder.
The extension specific folder was added I think with 1.6 or even 1.5 and that bug probably exists since then 😄

@nikosdion
Copy link
Contributor

I didn't know what was the intended behavior since none is documented anywhere I could look. If we want the system to override extension translations then, yes, the order of lines should be;

$lang->load($option, JPATH_COMPONENT, null, false, true);
$lang->load($option, JPATH_BASE, null, false, true);

Would you like me to make a quick PR for this?

@Bakual
Copy link
Contributor

Bakual commented Jul 31, 2017

If you have time to spare, please yes.

@nikosdion
Copy link
Contributor

Well, I have some time while dinner is cooking :) Please see PR gh-17372

@zero-24
Copy link
Contributor

zero-24 commented Jul 31, 2017

Closing here than. Thanks.

@zero-24 zero-24 closed this as completed Jul 31, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants