Extension du complexType nommé «imageType» avec un type d'image personnalisé

22

Le but d'un module que je développe actuellement est d'ajouter un type d'image personnalisé appelé "opengraph_image". J'ai ajouté un nouvel attribut EAV via mon script InstallData.php qui fonctionne bien. Lorsque je me connecte maintenant au backend Magento2 et modifie un produit, je peux choisir le type d'image "opengraph_image" lors du téléchargement ou de la modification des images du produit.

Cependant, sur le frontend, je voudrais afficher cette image. J'ai donc créé un fichier etc / view.xml dans mon module avec le contenu suivant:

<?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>

Mais maintenant, j'obtiens l'erreur suivante:

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

La raison en est qu'il ne semble pas charger mon custom.xsd situé dans: app/code/Esites/SEO/etc/custom.xsdoù je définis l'opengraph_image. Au lieu de cela, il semble simplement charger son fichier XSD par défaut:vendor/magento/framework/Config/etc/view.xsd

Le contenu de mon custom.xsd est une copie (à des fins de test) de ce view.xsd d'origine où j'ai ajouté ce qui suit à la ligne 75:

 <xs:enumeration value="opengraph_image"/>

Le frontend fonctionne sans erreur si j'inclus la ligne ci-dessus dans le fichier view.xsd d'origine. J'ai suivi la documentation sur: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/build/XSD-XML-validation.html et mes chemins sont construits selon les informations sur cette page. Le cache est effacé plusieurs fois.

Qu'est-ce que je rate?

langezwieper
la source
Avez-vous essayé de changer module="Magento_Catalog" pour module="Esites_SEO"?
Raphael au Digital Pianism

Réponses:

9

Charges Magento2 par défaut view.xsd parce ConfigView Reader à l' aide lib/internal/Magento/Framework/Config/SchemaLocator.phpet il retourne par défautview.xsd

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

J'ai pu le remplacer en suivant les étapes ci-dessous:

  • Créer une nouvelle extension, par exemple Magento_SampleMinimal
  • Créez la définition du plugin dans {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>
  • Créer un plugin dans {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;
        }
    }

    Mise à jour pour Magento 2.0. version

  • Copier lib/internal/Magento/Framework/Config/etc/view.xsdvers{MODULE}/etc/view.xsd

Pour Magento 2.1. version, copierVendor/Magento/Framework/Config/etc/view.xsdvers{MODULE}/etc/view.xsd * Modifier{MODULE}/etc/view.xsdet ajouter un nouveau type demedia_attribute

Yaroslav Voronoy
la source
Êtes-vous sérieux .. Est-ce le seul moyen? Semble exagéré, et probablement ridicule que vous ne pouvez pas ajouter votre propre image sans écraser le noyau XSD
Erfan
Voilà la bonne solution. Merci beaucoup pour ce Yaroslav.
medina
C'est super merci! Cependant, je recommanderais d'écrire le plugin Magento\Framework\Config\Dom\UrnResolvercar il y a des endroits qui l'utilisent directement au lieu de le traverser SchemaLocator.
quickshiftin
0

Cela semble être un défaut de conception, en combinaison avec un bug de Magento 2. J'ai créé un rapport de bogue ici: https://github.com/magento/magento2/issues/10161

Si vous utilisez le générateur d'image directement dans un modèle pour sortir l'image opengraph_image, une meilleure solution consiste à passer des attributs personnalisés (en utilisant Magento\Catalog\Block\Product\ImageBuilder::setAttributes, ou le troisième paramètre de Magento\Catalog\Block\Product\View::getImage).

Cependant, cela ne fonctionnera pas (compte tenu de mon rapport de bogue), vous devrez donc toujours remplacer la createméthode d' ImageBuilder pour transmettre ces attributs à l'aide d'image de catalogue.

Erfan
la source
0

Il existe un moyen plus simple que la réponse de Yaroslav. Il est possible de changer les paramètres du constructeur en SchemaLocator dans le di.xml de votre module. Comme:

<type name="Magento\Framework\Config\SchemaLocator" >
    <arguments>
        <argument name="realPath" xsi:type="string">urn:magento:module:VendorName_ModuleName:etc/view.xsd</argument>
    </arguments>
</type>

Pas besoin de plugin.

David Stone
la source
Attention, cette solution ne fonctionne que si vous avez $ realPath comme argument dans SchemaLocator. Dépend de la version de Magento 2.
Pol Ravalitera
-1

Vous n'avez pas besoin de modifier ou de remplacer view.xsd, ce fichier est juste pour la validation.
J'ai récemment implémenté ma solution en procédant comme suit: Créez un attribut de catalogue d'images (disons que le nouvel attribut ID 162). Une fois que vous avez créé l'attribut, vous pourrez l'appliquer sur n'importe quelle image de catalogue. Vous devez maintenant lui appliquer le bon modèle et la bonne visibilité frontale. Vous pouvez le faire par programme ou en suivant ce guide.

  1. Ouvrez votre base de données avec phpMyAdmin ou MySQL et essayez de refléter n'importe quel attribut système comme small_image

    use magento2_database_name;
    SELECT * FROM  `eav_attribute`;
    UPDATE `magento2_database_name`.`eav_attribute` SET `frontend_model` = 'Magento\\Catalog\\Model\\Product\\Attribute\\Frontend\\Image' WHERE  `eav_attribute`.`attribute_id` =162;
    SELECT * FROM  `catalog_eav_attribute`;
    UPDATE `magento2_database_name`.`catalog_eav_attribute` SET `is_visible` = '1', 'using_in_product_listing' = '1' WHERE `catalog_eav_attribute`.`attribute_id` =162;
  2. Accédez à www_root/magento2_root/app/design/frontend/Theme/package/etc/view.xmlet ajoutez votre nouveau type d'image:

        <image id="opengraph_image" type="opengraph_image">
            <width>265</width>
            <height>265</height>
        </image>
  3. Mettez à jour les fichiers modèles en ajoutant le nouveau type d'image sur www_root/magento2_root/app/design/frontend/Theme/package/Magento_Catalog/templates/product/
  4. Nettoyez votre cache et vous le verrez à l'avant.

Cela a fonctionné pour moi pour une image de survol sur la liste des produits de la catégorie, espérons cette aide.

JROCA22
la source
thx 7ochem, c'est mon premier vrai post.
JROCA22
Cette solution ne fonctionne pas car Magento valide activement le XSD
barbazul
@barbazul c'est seulement si vous êtes en mode développeur si je me souviens bien ..
Erfan
@Erfan C'est possible. Honnêtement, je n'ai pas vérifié. Mais encore, c'est un signe que ce n'est pas comme ça que vous êtes censé le faire ou qu'il y a quelque chose de mal dans ce XSD particulier
barbazul
Ce n'est peut-être pas la meilleure pratique, mais cela a fonctionné pour moi
JROCA22