System Configuration Structure
Configuration Hierarchy
Magento admin configuration follows a three-level hierarchy:
Section -> Group -> Field
- Section: Top-level container (e.g., Catalog, Sales, General)
- Group: Logical grouping within a section (e.g., Frontend, Inventory)
- Field: Individual configuration value (e.g., Product Count, Weight Unit)
File Location
Vendor/Module/etc/adminhtml/system.xml
Basic Structure
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="vendor_settings" type="text" sortOrder="100" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Vendor Settings</label>
<tab>general</tab>
<group id="general" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="1">
<label>General Settings</label>
<field id="enabled" type="select" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Enable Module</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
</system>
</config>
Visibility Attributes
| Attribute | Description |
|---|---|
| showInDefault | Show in default (global) config scope |
| showInWebsite | Show in website config scope |
| showInStore | Show in store config scope |
| sortOrder | Display order within parent element |
| type | Field type (text, select, etc.) |
Field Types and Source Models
Common Field Types
<!-- Text input -->
<field id="api_key" type="text" sortOrder="20" showInDefault="1">
<label>API Key</label>
<comment>Enter your API key from the provider</comment>
</field>
<!-- Yes/No dropdown -->
<field id="enabled" type="select" sortOrder="10" showInDefault="1">
<label>Enable Module</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<!-- Textarea -->
<field id="custom_css" type="textarea" sortOrder="30" showInDefault="1">
<label>Custom CSS</label>
<backend_model>Magento\Config\Model\Config\Backend\Textarea</backend_model>
</field>
<!-- Price field -->
<field id="handling_fee" type="price" sortOrder="40" showInDefault="1">
<label>Handling Fee</label>
<backend_model>Magento\Config\Model\Config\Backend\Price</backend_model>
</field>
<!-- Image upload -->
<field id="logo_image" type="image" sortOrder="50" showInDefault="1">
<label>Logo Image</label>
<backend_model>Magento\Config\Model\Config\Backend\Image</backend_model>
<upload_dir>vendor/logo</upload_dir>
</field>
Built-in Source Models
| Source Model | Options |
|---|---|
| Magento\Config\Model\Config\Source\Yesno | Yes/No |
| Magento\Config\Model\Config\Source\Enabledisable | Enable/Disable |
| Magento\Config\Model\Config\Source\Locale | All locales |
| Magento\Config\Model\Config\Source\Store | All stores |
| Magento\Config\Model\Config\Source\Currency\Option\AbstractCurrency | Currency codes |
Custom Source Models
Create your own dropdown options:
namespace Vendor\Module\Model\Config\Source;
class ShippingMethod implements \Magento\Framework\Option\ArrayInterface
{
public function toOptionArray(): array
{
return [
['value' => 'flat', 'label' => __('Flat Rate')],
['value' => 'free', 'label' => __('Free Shipping')],
['value' => 'table', 'label' => __('Table Rate')],
];
}
}
Backend Models and Validation
Backend Models
Backend models handle saving, validation, and processing of configuration values:
namespace Vendor\Module\Model\Config\Backend;
class ApiKey extends \Magento\Config\Model\Config\Backend\AbstractBackend
{
public function afterSave(): void
{
$value = $this->getValue();
if (empty($value)) {
throw new \Magento\Framework\Exception\LocalizedException(
__('API Key cannot be empty')
);
}
// Additional processing after save
}
}
Backend Model in system.xml
<field id="api_key" type="obscure" sortOrder="20" showInDefault="1">
<label>API Key</label>
<backend_model>Vendor\Module\Model\Config\Backend\ApiKey</backend_model>
<comment>Your provider API key</comment>
</field>
Validation Types
<!-- Required field -->
<field id="store_name" type="text" sortOrder="10" showInDefault="1">
<label>Store Name</label>
<validate>required-entry</validate>
</field>
<!-- Email validation -->
<field id="admin_email" type="text" sortOrder="20" showInDefault="1">
<label>Admin Email</label>
<validate>validate-email</validate>
</field>
<!-- URL validation -->
<field id="api_url" type="text" sortOrder="30" showInDefault="1">
<label>API URL</label>
<validate>validate-url</validate>
</field>
<!-- Numeric validation -->
<field id="timeout" type="text" sortOrder="40" showInDefault="1">
<label>Timeout (seconds)</label>
<validate>validate-number validate-digits</validate>
</field>
Field Dependencies
Show/hide fields based on another field's value using comment and JavaScript:
<field id="payment_enabled" type="select" sortOrder="10" showInDefault="1">
<label>Enable Payment</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="payment_method" type="text" sortOrder="20" showInDefault="1">
<label>Payment Method</label>
<depends>
<field id="payment_enabled" value="1"/>
</depends>
</field>
Complete Configuration Example
Full Module Configuration
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="vendor_shipping" type="text" sortOrder="300" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Vendor Shipping</label>
<tab>sales</tab>
<group id="general" type="text" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
<label>General Configuration</label>
<field id="enabled" type="select" sortOrder="10" showInDefault="1" showInWebsite="1" showInStore="0">
<label>Enable Module</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
<field id="title" type="text" sortOrder="20" showInDefault="1" showInWebsite="1" showInStore="1">
<label>Shipping Title</label>
<validate>required-entry</validate>
</field>
</group>
<group id="rates" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Shipping Rates</label>
<field id="flat_rate" type="price" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Flat Rate Fee</label>
<backend_model>Magento\Config\Model\Config\Backend\Price</backend_model>
</field>
<field id="free_threshold" type="price" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
<label>Free Shipping Threshold</label>
<backend_model>Magento\Config\Model\Config\Backend\Price</backend_model>
</field>
</group>
</section>
</system>
</config>
Key Points
- Section defines the top-level container
- Groups organize related fields
- Fields are individual configuration values
- Source models provide dropdown options
- Backend models handle save logic
- Validation rules ensure data integrity
Quiz
1. What is the hierarchy of system configuration in Magento?
2. Which source model provides Yes/No dropdown options?
3. What does the 'obscure' field type do?
Flashcards
Question
What are the three levels of system configuration?
Click to reveal answer
Answer
Section -> Group -> Field
Question
Where does system.xml live in a module?
Click to reveal answer
Answer
Vendor/Module/etc/adminhtml/system.xml
Question
What attribute controls whether a field shows in website scope?
Click to reveal answer
Answer
showInWebsite
Question
How do you access a config value in PHP?
Click to reveal answer
Answer
$this->scopeConfig->getValue('section/group/field')
Question
What validation rule requires a field to have a value?
Click to reveal answer
Answer
required-entry
Revision Notes
Key Takeaways
- 1. system.xml defines admin configuration with Section -> Group -> Field hierarchy
- 2. Field types include text, select, price, textarea, image, obscure
- 3. Source models provide dropdown options; backend models handle save logic
- 4. Visibility is controlled by showInDefault, showInWebsite, showInStore attributes
- 5. Use validate attribute for client-side field validation
Interview Tips
- • Explain the section/group/field hierarchy
- • Know the difference between source models and backend models
- • Be ready to discuss how to create custom dropdown options
- • Understand scope configuration (default, website, store)
Cheat Sheet
<section id="vendor_settings">
<group id="general">
<field id="enabled" type="select">
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>
</group>
</section>
Access: $this->scopeConfig->getValue('vendor_settings/general/enited')
Visibility:
showInDefault="1" showInWebsite="1" showInStore="0"