Module configuration
A module almost always has settings: whether it is enabled, which text to show, how many records to print. In Magento they are not kept in code: fields are described in an XML file, they appear in the admin panel, and an administrator sets the values — separately for each store view if needed.
Where the files live
| File | What it describes |
|---|---|
etc/adminhtml/system.xml | Fields in the admin panel |
etc/config.xml | Default values |
Both files are created by hand.
app/code/Acme/Hello/
├── Model/
│ └── Config.php new file
└── etc/
├── adminhtml/
│ └── system.xml new file
├── config.xml new file
└── module.xmlA setting field
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/adminhtml/system.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Config:etc/system_file.xsd">
<system>
<section id="acme_hello" translate="label" sortOrder="900"
showInDefault="1" showInWebsite="1" showInStore="1">
<label>Hello</label>
<tab>general</tab>
<resource>Magento_Config::config</resource>
<group id="general" translate="label" sortOrder="10"
showInDefault="1" showInWebsite="1" showInStore="1">
<label>General settings</label>
<field id="greeting" translate="label" type="text" sortOrder="10"
showInDefault="1" showInWebsite="1" showInStore="1">
<label>Greeting text</label>
</field>
</group>
</section>
</system>
</config>Run bin/magento cache:clean and open Stores → Configuration → General → Hello in the admin panel. A group with one text field appears there.
Settings form three levels: a section (section), a group (group), a field (field). Their IDs make up the path to a value: acme_hello/general/greeting. The resource tag names a permission; the module gets its own permission in the next lesson.
A default value
<?xml version="1.0"?>
<!-- app/code/Acme/Hello/etc/config.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Store:etc/config.xsd">
<default>
<acme_hello>
<general>
<greeting>Welcome!</greeting>
</general>
</acme_hello>
</default>
</config>The nesting of tags repeats the setting path. Until an administrator saves their own value, this one is used.
Reading in code
Settings are read by ScopeConfigInterface. It is convenient to gather all reads in one class:
// app/code/Acme/Hello/Model/Config.php
namespace Acme\Hello\Model;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;
class Config
{
public function __construct(private ScopeConfigInterface $scopeConfig) {}
public function getGreeting(): string
{
return (string) $this->scopeConfig->getValue('acme_hello/general/greeting', ScopeInterface::SCOPE_STORE);
}
}Add Config to the constructor of the Greeting view model and print getGreeting() in the template: "Welcome!" appears on the /hello page. Change the value in the admin panel and save — the text on the page changes.
Configuration scopes
| Scope | What it is for |
|---|---|
Default (default) | A value for the whole installation |
Website (website) | A value for one website |
Store view (store view) | A value for one language |
A value on a lower level overrides the upper one. The SCOPE_STORE constant in the second argument means "for the current store view": Magento returns its value, and if none is set — the website value or the default one. The showInDefault, showInWebsite, showInStore attributes decide on which levels the field is visible in the admin panel.
A switch and dependent fields
<!-- app/code/Acme/Hello/etc/adminhtml/system.xml -->
<field id="enabled" translate="label" type="select" sortOrder="5"
showInDefault="1" showInWebsite="1" showInStore="1">
<label>Enabled</label>
<source_model>Magento\Config\Model\Config\Source\Yesno</source_model>
</field>A select field takes its options from the source_model class; here they are "Yes" and "No". In code such a switch is read with the isSetFlag() method and the same arguments — it returns true or false. To show a field only when the module is enabled, add a depends tag to it with a nested field id="enabled" and the value 1.
Settings from the console
bin/magento config:set acme_hello/general/greeting "Good afternoon!"
bin/magento config:show acme_hello/general/greetingThe first command saves a value, the second prints it.
Common mistake
A value was changed, but the page shows the old one. Settings are cached: after editing config.xml, system.xml or changing the core_config_data table directly, run bin/magento cache:clean config. When you save in the admin panel, Magento reminds you about the cache with a message at the top of the page.