Modify “Interface locale” dropdown in administration

Modify “Interface locale” dropdown in administration

It is really cool when you can see large list of languages in the footer of Magento administration. You might think that all those languages you can see are available by default, but that is not the case. What to do when you need only two? English and Spanish for example? What seamed to be a simple task, turned up to be quite challenging.

Mage_Core_Model_Locale_Config has protected property $_allowedLocales containing array of locales that will be used to show language dropdown.

I have failed to rewrite that class, but that would be bad idea anyway, mostly because I don’t have time to spend half day testing if that has any sideefects that I’m not aware of, so here’s what I came up in the end.

Digging through Mage::getConfig() wasn’t really helpful either… 🙁

Worst thing is that if I define allowed locales in local.xml, they only get merged with existing languages.

Moving class in local directory helps, but it is not acceptable. I didn’t even tried to rewrite Mage_Core_Block_Html_Select since it would be really messy.

Fortunately we can do something else 🙂

Let’s observe core_block_abstract_to_html_before event!

Here is my config.xml

< ?xml version="1.0"?>
<config>
<modules>
<inchoo_developer>
<version>0.1.0</version>
</inchoo_developer>
</modules>
<global>
<models>
<developer>
<class>Inchoo_Developer_Model</class>
</developer>
</models>
<events>
<core_block_abstract_to_html_before>
<observers>
<hook_to_block_abstract_to_html_before_1>
<class>developer/observer</class>
<!-- Mage_Adminhtml_Block_Html_Select -->
<method>modifyLanguageDropdownOptions</method>
</hook_to_block_abstract_to_html_before_1>
</observers>
</core_block_abstract_to_html_before>
</events>
</global>
</config>

Now we are hooked to core_lock_abstract_to_html_before event and we can modify options for our specific block in Observer.php:

< ?php
class Inchoo_Developer_Model_Observer
{
public function modifyLanguageDropdownOptions($observer = null)
{
if(get_class($observer->getEvent()->getBlock())== "Mage_Adminhtml_Block_Html_Select")
{
 
// This should be made to be read from configuration, but for this article purposes, it is fine, I guess...
 
$allowedLocales = array (0 => array ('value' => 'en_US',
'label' => 'English (United States) / English (United States)'),
1 => array ('value' => 'hr_HR',
'label' => 'Hrvatski (Hrvatska) / Croatian (Croatia)')
);
 
$observer->getEvent()->getBlock()->setOptions($allowedLocales);
}
return $this;
}
}

Now it should work.
Of course, please make sure that you test / modify it before using it on production sites.

Cheers!

P.S. Keep in mind that this is just one way of doing things and I’m not saying it is the only one.

You made it all the way down here so you must have enjoyed this post! You may also like:

Calling out all Magento developers who want to improve their testing skills – visit MageTestFest! Maja Kardum
Maja Kardum, | 0

Calling out all Magento developers who want to improve their testing skills – visit MageTestFest!

Meet with Inchoo at Magento Imagine 2014! Maja Kardum
Maja Kardum, | 0

Meet with Inchoo at Magento Imagine 2014!

Create Magento Dropdown Login in a few minutes Petar Sambolek
Petar Sambolek, | 17

Create Magento Dropdown Login in a few minutes

18 comments

  1. Well, I would say it depends on the site. Why not add some timing code around your if block. Then aggregate the time spent doing the if check across every block being loaded in a single page view. Every single block that is rendered will fire that event. And by attaching it as a global observer instead of an adminhtml observer, you are now firing your event for every frontend block as well. I would say the total time spent checking block types is not insignificant.

  2. @Thomas

    Ok, I forgot they do things weird when laying out admin pages and don’t use layout XML as much as they should. Looking at the code the most ‘fool proof’ way would be to extend the Mage_Adminhtml_Block_Page_Footer class and override the getLanguageselect method. There, instead of directly adding the result of Mage::app()->getLocale()->getTranslatedOptionLocales() to the select element, you filter it in whatever manner you like.

  3. @Thomas

    I meant change the layout XML to direct Magento to use a different block to render the list of languages in the admin area. Create a block that extends the original block and move your modifications to that area. Then Magento uses your new, extended, block to render the HTML for the language list.

  4. And at the end of the day there is “Of course, please make sure that you test / modify it before using it on production sites.” sentence in this article for a reason.

  5. @Lee S – I’m not sure if I’m completely right, but it seems to me that I would need to add whole new observer class to restrict event callback only for admin which is little more heavier on resources compared to 1 “if”. I don’t have too much time atm, but by simply adding event to admin section, I can’t make it work now, but I’ll try later. Let me know if you managed to do it if you have time to play with it. Changing what block is rendering would also require way more time etc. so it seems to me that’s not a good idea as well.

    @suvi I’m not putting anything in local/Mage PERIOD.

  6. I looked into this as well, but the much faster and easier way is to make your Local/Config.php
    just copy
    /app/code/core/Mage/Core/Model/Locale/Config.php
    to
    /app/code/local/Mage/Core/Model/Locale/Config.php

    and modify.

    Cheers
    Suvi

  7. Tapping into the GLOBAL core_block_abstract_to_html_before event for this is a bad idea. That means you have an event callback being fired for every single block being rendered on your site, frontend and backend. I understand you are not doing anything for 99.9% of the block, but you are still running the if statement for every block rendered. At the very least you should only attach to the backend event. Even better would be modify the layout and change what block is rendering that element and make your modifications there.

  8. @Yon Zubizarreta

    Don’t get me wrong, but that really doesn’t work.
    I’m not saying your sintax is wrong. I’m just saying that you might consider running that piece of code.
    Do you really think this article exists because I need instructions about rewriting model classes in Magento, after 2.5 years of coding it?
    You can’t rewrite that class via standard way. 😉

  9. Ops…i forgot the code tags and the xml nodes has gone away…ok, i’ll try again. It sould be something like this:
    /app/code/local/YOUR_MOLULE_NAME/etc/Config.xml

    <config>
    	<global>
    		<models>
    			<core>
    				<rewrite>
    					<locale_config>
    						YOUR_MODULE_NAME_Model_locale_config
    					</locale_config>
    				</rewrite>
    			</core>
    		</models>
    	</global>
    </config>

    /app/code/local/YOUR_MOLULE_NAME/Model/Locale/Config.php

    class YOUR_MODULE_NAME_Model_Locale_Config extends Mage_Core_Model_Locale_Config
    {
    	/**
    	* List of allowed locales
    	*
    	* @var array
    	*/
    	protected $_allowedLocales = array(
    	‘eu_ES’ /*Basque (Basque)*/, ‘es_ES’ /*Spanish (Spain)*/, ‘en_US’ /*English (United States)*/, ‘fr_FR’ /*French (France)*/
    	);
    }

    And believe me…it’s working 😉

  10. Hello,
    Try to rewrite Mage_Core_Model_Locale_Config just adding this in config.xml:

    YOUR_MODULE_NAME_Model_locale_config

    The class should look like this:

    class YOUR_MODULE_NAME_Model_Locale_Config extends Mage_Core_Model_Locale_Config
    {
    /**
    * List of allowed locales
    *
    * @var array
    */
    protected $_allowedLocales = array(
    ‘eu_ES’ /*Basque (Basque)*/, ‘es_ES’ /*Spanish (Spain)*/, ‘en_US’ /*English (United States)*/, ‘fr_FR’ /*French (France)*/
    );
    }

    That’s the cleannest and easiest way i found out…and of course, works!

  11. Hello Angelo,

    Maybe this is not the correct way to do it, but I comment out the languages that I do not need:
    /app/code/core/Mage/Core/Model/Locale/Config.php

    protected $_allowedLocales = array(
    ‘af_ZA’ /*Afrikaans (South Africa)*/, …
    );

    to

    protected $_allowedLocales = array(
    // ‘af_ZA’ /*Afrikaans (South Africa)*/, …
    );

    Hope that helps
    * sorry for my bad English…

  12. Hi Angelo.

    There are no files to modify here. You should make your own module.

    Now, after few years of Magento’s life, that should be something fairy easy to learn how to do it since there is is plenty of tutorials on this site and on other portions of internet.

    So for your module you should have this two files at right places and make modifications to suit your need.

    Good luck! 😉

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <blockquote cite=""> <code> <del datetime=""> <em> <s> <strike> <strong>. You may use following syntax for source code: <pre><code>$current = "Inchoo";</code></pre>.

Tell us about your project

Drop us a line. We'd love to know more about your project.