Magento – Extending the complexType named “imageType” with a custom image type

magento2xml

The goal of a module I'm currently developing is to add a custom image type called "opengraph_image". I added a new EAV attribute though my InstallData.php script which works fine. When I now login into the Magento2 backend and alter a product I can choose the image type "opengraph_image" while uploading or editing product images.

However, on the frontend I would like to display this image. Therefore I created a etc/view.xml file in my module with the following content:

<?xml version="1.0"?>
<view xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Esites_SEO:etc/custom.xsd">
    <media>
        <images module="Magento_Catalog">
            <image id="opengraph_image" type="opengraph_image">
                <width>265</width>
                <height>265</height>
            </image>
        </images>
    </media>
</view>

But now I get the following error:

Invalid XML in file /var/www/html/vhosts/magento2/app/code/Esites/SEO/etc/view.xml:
Element 'image', attribute 'type': [facet 'enumeration'] The value 'opengraph_image' is not an element of the set {'thumbnail', 'small_image', 'image', 'swatch_image', 'swatch_thumb'}.
Line: 5

Element 'image', attribute 'type': 'opengraph_image' is not a valid value of the local atomic type.
Line: 5

The reason is it doesn't seem to load my custom.xsd located in: app/code/Esites/SEO/etc/custom.xsd where I define the opengraph_image. Instead it seems to just load it's default XSD file: vendor/magento/framework/Config/etc/view.xsd

The content of my custom.xsd is a copy (for testing purposes) of this original view.xsd where I added the following on line 75:

 <xs:enumeration value="opengraph_image"/>

The frontend does work without errors if I include the line above in the original view.xsd file. I followed the documentation on: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/build/XSD-XML-validation.html and my paths are build according to the information on that page. Cache is cleared multiple times.

What am I missing?

Best Answer

Magento2 loads default view.xsd because ConfigView Reader using lib/internal/Magento/Framework/Config/SchemaLocator.php and it returns default view.xsd

$this->schema = $urnResolver
    ->getRealPath('urn:magento:framework:Config/etc/view.xsd');`

I was able to override it by follow steps below:

  • Create new extension for example Magento_SampleMinimal
  • Create the plugin definition in {MODULE}/etc/di.xml

    <?xml version="1.0"?>
    <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
        <type name="Magento\Framework\Config\SchemaLocator">
            <plugin name="SampleMinimal_SchemaLocator" type="Magento\SampleMinimal\Model\Plugin\SchemaLocator" sortOrder="1"/>
        </type>
    </config>
    
  • Create plugin in {MODULE}/Model/Plugin/SchemaLocator.php

    <?php
    namespace Magento\SampleMinimal\Model\Plugin;
    
    use Magento\TestFramework\ObjectManager;
    
    class SchemaLocator
    {
        /**
         * After Get Schema
         *
         * @param \Magento\Framework\Config\SchemaLocator $schemaLocator
         * @param string $result
         * @return array
         */
        public function afterGetSchema(\Magento\Framework\Config\SchemaLocator $schemaLocator, $result)
        {
            $result = sprintf(realpath(__DIR__ . '/../../etc/view.xsd'));
            return $result;
        }
    }
    

    Update For Magento 2.0. version

  • Copy lib/internal/Magento/Framework/Config/etc/view.xsd to {MODULE}/etc/view.xsd

For Magento 2.1. version, Copy Vendor/Magento/Framework/Config/etc/view.xsd to {MODULE}/etc/view.xsd * Edit {MODULE}/etc/view.xsd and add new type of media_attribute