Scenario: I am a Magento 2 module developer. I want to create a configuration file in app/etc. I want this file to be "scoped" by area


In Magento 1 I'd just create a config.xmland be on my way. The area scoping happened in the XML file itself. However, Magento 2 approaches this very differently

In Magento 2, what class file(s?) should I create for reading these scoped configuration files. It's not clear from the Magento 2 source what "the right" way to do this is. The core code take multiple approaches, and none of them are marked with an @api method. This makes it difficult to know how to proceed with this common module developer task. As a secondary side-effect, it also makes it difficult to know how a Magento module developer should read from core configuration files.

On one hand, it seems like "the right" thing to do is create a file system reader object. For example, Magento seems to load the import.xml file with the following

#File: vendor/magento/module-import-export/Model/Import/Config/Reader.php
namespace Magento\ImportExport\Model\Import\Config;

class Reader extends \Magento\Framework\Config\Reader\Filesystem

    public function __construct(
        $fileName = 'import.xml',
    ) {

The base Magento\Framework\Config\Reader\Filesystem class looks like it has code to resolve the area scope.

However some of the Magento configuration files seem to eschew this pattern. While there are readers for these files (event.xml in this example)


There's also "scoped data" classes that use these readers.

#File: vendor/magento/framework/Event/Config/Data.php
class Data extends \Magento\Framework\Config\Data\Scoped
    public function __construct(
        \Magento\Framework\Event\Config\Reader $reader,
    ) {
        parent::__construct($reader, $configScope, $cache, $cacheId);

This makes it seem like the scoped reader classes are what a module developer should create. But not all configuration files have these scoped readers.

Is there a clear path for Magento 2 module developers to follow? Or is this just something Magento 2 module developers should approach in their own way, and the resulting chaos/non-standard-configuration-loading is just the cost of doing business?

The official documentation does a good job of covering some of the available classes, but nothing that reconciles the fact there's no clear guidance on which concrete implementation we're suppose to use, or if the expectation is every module decides how to do this on its own.


4 Answers 4


To create new configuration type, module developer should create a configuration type class that will be used by clients of configuration.

To make these type classes as simple as possible, all behavior of reading configuration files and caching data was moved to \Magento\Framework\Config\DataInterface with two reusable implementations:

  • \Magento\Framework\Config\Data - for configuration types that only make sense to be loaded in one scope (eav_attributes.xml only in global)
  • \Magento\Framework\Config\Data\Scoped - for configuration types that can be loaded on different scopes (events.xml - global and per-area)

Every configuration type is supposed to have pre-configured Config\DataInterface object. Configuration can be done either with Virtual Type or with inheritance.

Although module developer can technically inherit their configuration type from Config\DataInterface implementation, it's recommended not to extend from core classes. Always better to use composition.

Now \Magento\Framework\Config\Data and Data\Scoped only do caching and delegate configuration reading to \Magento\Framework\Config\ReaderInterface. ReaderInterface is supposed to provide valid configuration in format of PHP array for requested scope (if configuration is scoped). Multiple implementations of ReaderInterface are possible (for example read configuration from DB) but Magento only ships one generic reader: \Magento\Framework\Config\Reader\Filesystem.

\Magento\Framework\Config\Reader\Filesystem does all operations required for reading files from modular filesystem: read files, merge and validate.

Every Config\DataInterface is supposed to have separately configured instance of Config\ReaderInterface. As any instance in system, specific reader can be configured either with Virtual Type or with inheritance. Magento Documentation Describes all Filesystem dependencies.

Every element in this chain is optional (except for Config Type Class itself) and can be substituted with more specific implementation.


I have created a public repository at https://bitbucket.org/magstaging/mbs_customergroupconfig/src/master/

It is small enough to spot right away what is necessary to create a custom config and more importantly how to use/extend it

What I identified is that each custom config has similar structure (even though this structure is in di.xml for my module or in the config models themselves for \Magento\Catalog\Model\ProductTypes\Config); This module attempts to replicate what product types config does.. (see \Magento\Catalog\Model\ProductTypes\ConfigInterface)

To this end, I have created a getAll (see \Mbs\CustomerGroupConfig\Model\Config\DataInterface::getAll) function and it retrieves all the customer groups setup in my custom config xml file.

the structure I suggest is: each config has a Converter, a Schema Locator and a Reader

  1. the Converter parses the xml file and returns the content in the config as an array (see \Mbs\CustomerGroupConfig\Model\Config\Converter)
  2. the Schema Locator pretty much returns the physical location of the xsd file. (see \Mbs\CustomerGroupConfig\Model\Config\SchemaLocator). There is a merge schema file and I do not know what this is for.
  3. finally the Reader just sends the name of the xml file to load to get the config content (in my module, I use a virtual type)

Finally, I added a command in the module, this command shows how we can use the custom config to returns its data.

I see what you are saying in that the parsing is left loose and one could think there is no structure. However, It seems this is on purpose so that the developer can expose the config data he wants and with the right getters. My example has only one getter.


Looks like official documentation has answers to your question.

  • 1
    Thank you for responding, but I'm not sure that documentation does answer my question. It lists a number of interfaces (which is useful, +1 for that) that are available, but doesn't reconcile the fact none of the concrete implementations of those interfaces (Magento\Framework\Config\Data and Magento\Framework\App\Config) aren't marked with @api. If left with only that documentation I'd be under the assumption that, as a module developer, there no standard system for creating and reading configuration files, and that I can do whatever I want. That doesn't seem right. Nov 29, 2015 at 20:54
  • Can you describe cases when you need to read configuration for some other module? For me configuration reader is private api of module.
    – KAndy
    Nov 29, 2015 at 21:02
  • If a developer wanted to contribute to Magento core. If a developer works on multiple modules, not all of which they control, and doesn't want to untangle a UML chart to read a value from a configuration file. See also -- most other PHP frameworks with a configuration system. Regardless, if the intention of the Magento 2 core team is that module configuration is a private and custom per module, that should be stated somewhere. Nov 29, 2015 at 21:06
  • Also also -- (slightly different/tangential) the System Configuration section in the backend of Magento -- building a feature based on an existing section's configuration. Nov 29, 2015 at 21:11
  • 2
    Any api that not annotated with @api is private in sense that if you use it then you responsible for backward compatibility/api changes issues. \Magento\Framework\Config\ReaderInterface have \@api annotation.
    – KAndy
    Nov 29, 2015 at 21:34

There does not, at the time of this writing, appear to be a standard was of reading a merged configuration tree in Magento 2. Each module implements its own configuration reading classes, which means its up to each developer to decide how they want this merging to happen. While Magento offers some stock classes to do this, even among the core code the use of these classes is inconsistent.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.