Skip to content
intermediate Phase 25 · Module Backend

Admin System Configuration

Guide to Magento 2 admin configuration: system.xml, adminhtml menu, config fields, backend models, and configuration scopes

45m
0 problems
Topic Progress 0%

system.xml Configuration

Complete system.xml

<?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_prep" type="text" sortOrder="300" showInDefault="1" showInWebsite="1" showInStore="0">
            <label>Vendor Prep</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="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>Module Title</label>
                    <validate>required-entry</validate>
                </field>
            </group>
            <group id="api" type="text" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
                <label>API Settings</label>
                <field id="api_url" type="text" sortOrder="10" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>API URL</label>
                    <validate>required-entry validate-url</validate>
                </field>
                <field id="api_key" type="obscure" sortOrder="20" showInDefault="1" showInWebsite="0" showInStore="0">
                    <label>API Key</label>
                    <backend_model>Magento\Config\Model\Config\Backend\Obfuscate</backend_model>
                </field>
            </group>
        </section>
    </system>
</config>

Field Types

Type Purpose
text Text input
textarea Multi-line text
select Dropdown
multiselect Multiple dropdown
yesno Yes/No (special select)
price Price input
image Image upload
obscure Masked input (password-like)

Admin Menu

menu.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Backend:etc/menu.xsd">
    <menu>
        <!-- Add to existing menu -->
        <add id="Amazon_Prep::prep"
             title="Prep Manager"
             module="Amazon_Prep"
             sortOrder="200
             resource="Amazon_Prep::prep"/>

        <!-- Add child items -->
        <add id="Amazon_Prep::prep_warranties"
             title="Warranties"
             module="Amazon_Prep"
             sortOrder="10"
             parent="Amazon_Prep::prep"
             resource="Amazon_Prep::warranties"/>

        <add id="Amazon_Prep::prep_settings"
             title="Settings"
             module="Amazon_Prep"
             sortOrder="20"
             parent="Magento_Backend::stores"
             action="adminhtml/system_config/edit/section/vendor_prep"
             resource="Amazon_Prep::settings"/>
    </menu>
</config>

Menu Item Attributes

Attribute Description
id Unique identifier (Vendor_Module::item)
title Display text
module Module that owns this item
sortOrder Display order
parent Parent menu item ID
action URL to navigate to
resource ACL resource for permissions

Adding to Existing Menu

<!-- Add under Sales menu -->
<add id="Amazon_Prep::warranties"
     title="Warranties"
     module="Amazon_Prep"
     sortOrder="100"
     parent="Magento_Sales::sales Operations"
     resource="Amazon_Prep::warranties"/>

Source Models and Backend Models

Custom Source Model

<?php
namespace Amazon\Prep\Model\Config\Source;

class WarrantyType implements \Magento\Framework\Option\ArrayInterface
{
    public function toOptionArray(): array
    {
        return [
            ['value' => 'standard', 'label' => __('Standard')],
            ['value' => 'extended', 'label' => __('Extended')],
            ['value' => 'premium', 'label' => __('Premium')],
        ];
    }
}

Use in system.xml:

<field id="warranty_type" type="select" sortOrder="10" showInDefault="1">
    <label>Warranty Type</label>
    <source_model>Amazon\Prep\Model\Config\Source\WarrantyType</source_model>
</field>

Backend Model

<?php
namespace Amazon\Prep\Model\Config\Backend;

class WarrantyDuration extends \Magento\Config\Model\Config\Backend\AbstractBackend
{
    public function afterSave(): void
    {
        $value = $this->getValue();
        if ($value < 1 || $value > 120) {
            throw new \Magento\Framework\Exception\LocalizedException(
                __('Duration must be between 1 and 120 months')
            );
        }
    }

    public function afterLoad(): void
    {
        // Process value after loading from database
    }
}

Use in system.xml:

<field id="warranty_duration" type="text" sortOrder="20" showInDefault="1">
    <label>Duration (months)</label>
    <validate>validate-digits validate-range range-1-120</validate>
    <backend_model>Amazon\Prep\Model\Config\Backend\WarrantyDuration</backend_model>
</field>

Backend Model Methods

Method When Called
beforeSave() Before value is saved
afterSave() After value is saved
beforeLoad() Before value is loaded
afterLoad() After value is loaded
_construct() During initialization

Accessing Configuration Values

ScopeConfigInterface

<?php
namespace Amazon\Prep\Service;

use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Store\Model\ScopeInterface;

class ConfigService
{
    public function __construct(
        private ScopeConfigInterface $scopeConfig
    ) {}

    public function isEnabled(): bool
    {
        return (bool)$this->scopeConfig->getValue(
            'vendor_prep/general/enabled',
            ScopeInterface::SCOPE_STORE
        );
    }

    public function getTitle(): string
    {
        return $this->scopeConfig->getValue(
            'vendor_prep/general/title',
            ScopeInterface::SCOPE_STORE
        ) ?? 'Default Title';
    }

    public function getApiUrl(): string
    {
        return $this->scopeConfig->getValue(
            'vendor_prep/api/api_url',
            ScopeInterface::SCOPE_STORE
        );
    }
}

Configuration Path Format

section/group/field

Example: vendor_prep/general/enabled
         ^^^^^^^ ^^^^^^^^ ^^^^^^^
         section  group    field

Access in Block/Template

// In block class
public function isEnabled(): bool
{
    return (bool)$this->_scopeConfig->getValue(
        'vendor_prep/general/enited'
    );
}

// In template
$isEnabled = $block->isEnabled();

Access in Layout XML

<block class="..." name="...">
    <arguments>
        <argument name="enabled" xsi:type="object">
            Magento\Framework\App\Config\ScopeConfigInterface
        </argument>
    </arguments>
</block>

XMLPath to Scope Config

// Get all config values for a section
$sectionConfig = $this->scopeConfig->getValue('vendor_prep');

// Get nested value
$apiUrl = $sectionConfig['api']['api_url'];

// With default value
$value = $this->scopeConfig->getValue(
    'vendor_prep/general/title',
    ScopeInterface::SCOPE_STORE,
    $storeId
) ?? 'Default';

Quiz

1. What file defines admin menu items?

Question 1 options

2. What does a backend model do?

Question 2 options

3. How do you access a config value in PHP?

Question 3 options

Flashcards

Question

What does system.xml define?

Answer

Admin configuration sections, groups, and fields

Question

What is the config path format?

Answer

section/group/field (e.g., vendor_prep/general/enabled)

Question

What does a source model provide?

Answer

Dropdown options for select fields

Question

How do you add an admin menu item?

Answer

Use menu.xml with add elements

Question

What interface provides config values?

Answer

ScopeConfigInterface

Revision Notes

Key Takeaways

  • 1. system.xml defines admin config sections, groups, fields
  • 2. menu.xml defines admin menu items and hierarchy
  • 3. Source models provide dropdown options; backend models handle save logic
  • 4. Access config values via ScopeConfigInterface::getValue()
  • 5. Config path format: section/group/field

Interview Tips

  • Explain the system.xml section/group/field hierarchy
  • Know how to create custom source and backend models
  • Be ready to add admin menu items and configuration sections
  • Discuss configuration scopes (default, website, store)

Cheat Sheet

system.xml: section → group → field
menu.xml: <add id="..." parent="..."/>

Source model: implements ArrayInterface
Backend model: extends AbstractBackend
Access: $this->scopeConfig->getValue('section/group/field')