Magento system.xml

The Magento system.xml files are files that contain configuration information about Magento’s System -> Configuration area. They are located in the same directory as the modules’ config.xml configuration file: in the modules’ etc directory.

So how does the Magento system.xml file get loaded? This controller responsible for loading the System -> Configuration area belongs in the Mage_Adminhtml module, and we need to look at the indexAction() method of this ConfigController.


public function indexAction()
{
    $this->_forward('edit');
}

We get forwarded to the editAction() method. This method checks if there are any $current, $website and $store parameters and passes the $current parameter into the getSections() method. If you have clicked on the Configuration link from within the System dropdown menu in the admin, the $current variable will be blank.


public function editAction()
{
    $this->_title($this->__('System'))->_title($this->__('Configuration'));

    $current = $this->getRequest()->getParam('section');
    $website = $this->getRequest()->getParam('website');
    $store   = $this->getRequest()->getParam('store');

    Mage::getSingleton('adminhtml/config_data')
        ->setSection($current)
        ->setWebsite($website)
        ->setStore($store);

    $configFields = Mage::getSingleton('adminhtml/config');
    $sections     = $configFields->getSections($current);
    $section      = $sections->$current;
    $hasChildren  = $configFields->hasChildren($section, $website, $store);
    if (!$hasChildren && $current) {
        $this->_redirect('*/*/', array('website'=>$website, 'store'=>$store));
    }

    $this->loadLayout();

    $this->_setActiveMenu('system/config');
    $this->getLayout()->getBlock('menu')->setAdditionalCacheKeyInfo(array($current));

    $this->_addBreadcrumb(Mage::helper('adminhtml')->__('System'), Mage::helper('adminhtml')->__('System'),
        $this->getUrl('*/system'));

    $this->getLayout()->getBlock('left')
        ->append($this->getLayout()->createBlock('adminhtml/system_config_tabs')->initTabs());

    if ($this->_isSectionAllowedFlag) {
        $this->_addContent($this->getLayout()->createBlock('adminhtml/system_config_edit')->initForm());

        $this->_addJs($this->getLayout()
            ->createBlock('adminhtml/template')
            ->setTemplate('system/shipping/ups.phtml'));
        $this->_addJs($this->getLayout()
            ->createBlock('adminhtml/template')
            ->setTemplate('system/config/js.phtml'));
        $this->_addJs($this->getLayout()
            ->createBlock('adminhtml/template')
            ->setTemplate('system/shipping/applicable_country.phtml'));

        $this->renderLayout();
    }
}

The getSections() method is found in the Mage_Adminhtml_Model_Config class. It checks to see if the sections property is empty, and if it is, delegates to the _initSectionsAndTabs() method.

public function getSections($sectionCode=null, $websiteCode=null, $storeCode=null)
{
    if (empty($this->_sections)) {
        $this->_initSectionsAndTabs();
    }

    return $this->_sections;
}

The _initSectionsAndTabs() method then loads the configuration of the Magento system.xml files.

protected function _initSectionsAndTabs()
{
    $config = Mage::getConfig()->loadModulesConfiguration('system.xml')
        ->applyExtends();

    Mage::dispatchEvent('adminhtml_init_system_config', array('config' => $config));
    $this->_sections = $config->getNode('sections');
    $this->_tabs = $config->getNode('tabs');
}

Magento uses tabs and sections to define the layout of the configuration area in the Admin. Looking at the system.xml file from within the Mage_Core module, we can see that it defines the General, Services and Advanced tabs.


<config>
    <tabs>
        <general translate="label" module="core">
            <label>General</label>
            <sort_order>100</sort_order>
        </general>
        <service translate="label" module="core">
            <label>Services</label>
            <sort_order>99999</sort_order>
        </service>
        <advanced translate="label" module="core">
            <label>Advanced</label>
            <sort_order>999999</sort_order>
       </advanced>
    </tabs>
</config>

The tabs have two pairs of XML nodes: label and sort_order. The value of the label is displayed on the frontend of the System -> Configuration area, and the sort_order defines the position of the tabs on the left hand side.

If we look further down the file, we can see some of the sections defined.


<config>
    <tabs>
        <general translate="label" module="core">
            <label>General</label>
            <sort_order>100</sort_order>
        </general>
        ....
    </tabs>
    <sections>
        <general translate="label" module="core">
            <label>General</label>
            <tab>general</tab>
            <frontend_type>text</frontend_type>
            <sort_order>10</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            ....
        </general>
    </sections>
</config>

There are a few more nodes to look at here.

  • tab – the tab that the section belongs to. The value within this node must match the defined tab name
  • frontend_type – the type of field that will be used
  • show_in_default – show the section on the “Default Config” configuration scope
  • show_in_website – show the section on the “Website” configuration scope
  • show_in_store – show the section on the “Store View” configuration scope

Sections are also broken down into groups. When you click on a section in System -> Configuration, there will usually be information in a group (which is the text that sits on the dark grey background). If we click on the General section, the first group that we see is the Countries Options group, which is configured below.


<config>
    <sections>
        <general translate="label" module="core">
            <label>General</label>
            <tab>general</tab>
            <frontend_type>text</frontend_type>
            <sort_order>10</sort_order>
            <show_in_default>1</show_in_default>
            <show_in_website>1</show_in_website>
            <show_in_store>1</show_in_store>
            <groups>
                <country translate="label">
                    <label>Countries Options</label>
                    <frontend_type>text</frontend_type>
                    <sort_order>1</sort_order>
                    <show_in_default>1</show_in_default>
                    <show_in_website>1</show_in_website>
                    <show_in_store>1</show_in_store>
                    ....
                </country>
            </groups>
        </general>
    </sections>
</config>

Groups are also split down into fields. For example, within the Countries Options section, there is a Default Country field dropdown. This can be seen below.


<groups>
    <country translate="label">
        <label>Countries Options</label>
        <frontend_type>text</frontend_type>
        <sort_order>1</sort_order>
        <show_in_default>1</show_in_default>
        <show_in_website>1</show_in_website>
        <show_in_store>1</show_in_store>
        <fields>
            <default translate="label">
                <label>Default Country</label>
                <frontend_type>select</frontend_type>
                <source_model>adminhtml/system_config_source_country</source_model>
                <sort_order>1</sort_order>
                <show_in_default>1</show_in_default>
                <show_in_website>1</show_in_website>
                <show_in_store>1</show_in_store>
            </default>
        </fields>
        ....
    </country>
</groups>

The source_model tags represent the model used to populate a field’s default options. This could be in the form of a dropdown or a multiselect.

In conclusion, this gives us an idea of how to add a custom tab, section(s), group(s) and field(s) when creating our own module.

To view how the adminhtml.xml files load, view this post.

Note: This article is based on Magento Community/Open Source version 1.9.