Estendendo o complexType chamado “imageType” com um tipo de imagem personalizado

22

O objetivo de um módulo que estou desenvolvendo atualmente é adicionar um tipo de imagem personalizado chamado "opengraph_image". Eu adicionei um novo atributo EAV no meu script InstallData.php, que funciona bem. Quando agora faço login no back-end do Magento2 e altero um produto, posso escolher o tipo de imagem "opengraph_image" enquanto carrega ou edita imagens do produto.

No entanto, no front-end, eu gostaria de exibir esta imagem. Portanto, criei um arquivo etc / view.xml no meu módulo com o seguinte conteúdo:

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

Mas agora eu recebo o seguinte erro:

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

O motivo é que ele não parece carregar meu custom.xsd localizado em: app/code/Esites/SEO/etc/custom.xsdonde eu defino o opengraph_image. Em vez disso, parece carregar apenas o arquivo XSD padrão:vendor/magento/framework/Config/etc/view.xsd

O conteúdo do meu custom.xsd é uma cópia (para fins de teste) deste view.xsd original, onde adicionei o seguinte na linha 75:

 <xs:enumeration value="opengraph_image"/>

O front-end funciona sem erros se eu incluir a linha acima no arquivo view.xsd original. Segui a documentação em: http://devdocs.magento.com/guides/v2.0/extension-dev-guide/build/XSD-XML-validation.html e meus caminhos são construídos de acordo com as informações nessa página. O cache é limpo várias vezes.

o que estou perdendo?

langezwieper
fonte
Você tentou mudar module="Magento_Catalog" para module="Esites_SEO"?
Raphael no Digital Pianism

Respostas:

9

O Magento2 carrega o view.xsd padrão porque o ConfigView Reader está usando lib/internal/Magento/Framework/Config/SchemaLocator.phpe retorna o padrãoview.xsd

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

Consegui substituí-lo seguindo as etapas abaixo:

  • Crie uma nova extensão, por exemplo Magento_SampleMinimal
  • Crie a definição de plug-in em {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>
  • Crie um plugin no {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;
        }
    }

    Atualização para Magento 2.0. versão

  • Copiar lib/internal/Magento/Framework/Config/etc/view.xsdpara{MODULE}/etc/view.xsd

Para o Magento 2.1. versão, CopieVendor/Magento/Framework/Config/etc/view.xsdpara{MODULE}/etc/view.xsd * Editar{MODULE}/etc/view.xsde adicione um novo tipo demedia_attribute

Yaroslav Voronoy
fonte
Você está falando sério .. Esse é o único caminho? Parece exagero, e provavelmente ridículo que você não pode adicionar sua própria imagem sem substituir núcleo XSD
Erfan
Essa é a solução certa. Muito obrigado por esse Yaroslav.
medina
Isso é ótimo, obrigado! No entanto, eu recomendaria escrever o Plugin, Magento\Framework\Config\Dom\UrnResolverpois existem lugares que o usam diretamente em vez de passar SchemaLocator.
usar o seguinte
0

Isso parece ser uma falha de design, em combinação com um bug do Magento 2. Eu criei um relatório de erro aqui: https://github.com/magento/magento2/issues/10161

Se você estiver usando o construtor de imagens diretamente em um modelo para gerar a opengraph_image, uma solução melhor é passar atributos personalizados (usando Magento\Catalog\Block\Product\ImageBuilder::setAttributesou o terceiro parâmetro de Magento\Catalog\Block\Product\View::getImage).

No entanto, como isso não funcionará (dado meu relatório de erros), você ainda precisará substituir o createmétodo do ImageBuilder para passar esses atributos para o Auxiliar de Imagem do Catálogo.

Erfan
fonte
0

Existe uma maneira mais simples do que a resposta de Yaroslav. É possível alterar os parâmetros do construtor para SchemaLocator no di.xml do seu módulo. Gostar:

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

Não há necessidade de um plug-in.

David Stone
fonte
Cuidado, essa solução funciona apenas se você tiver $ realPath como argumento no SchemaLocator. Depende da versão Magento 2.
Pol Ravalitera
-1

Você não precisa modificar ou substituir view.xsd, este arquivo é apenas para validação.
Eu recentemente implementei uma solução my, fazendo o seguinte: Crie um atributo de catálogo de imagens (digamos que o novo atributo ID 162). Depois de criar o atributo, você poderá aplicá-lo em qualquer imagem de catálogo. Agora você deve aplicar a ele o modelo certo e a visibilidade do front end. Você pode fazer isso de forma programática ou seguindo este guia.

  1. Abra seu banco de dados com phpMyAdmin ou MySQL e tente espelhar qualquer atributo do sistema como 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. Vá para www_root/magento2_root/app/design/frontend/Theme/package/etc/view.xmle adicione seu novo tipo de imagem:

        <image id="opengraph_image" type="opengraph_image">
            <width>265</width>
            <height>265</height>
        </image>
  3. Atualize os arquivos de modelo adicionando o novo tipo de imagem em www_root/magento2_root/app/design/frontend/Theme/package/Magento_Catalog/templates/product/
  4. Limpe seu cache e você o verá no front-end.

Funcionou para mim para uma imagem instantânea na lista de produtos da categoria, espero que ajude.

JROCA22
fonte
thx 7ochem, é o meu primeiro post real.
JROCA22
Esta solução não funciona como Magento é validar ativamente o XSD
Barbazul
@barbazul isso é apenas se você estiver no modo de desenvolvedor se bem me lembro ..
Erfan
@ Erfan Poderia ser. Eu não verifiquei, honestamente. Mas ainda assim, é um sinal de que ele não é como você é suposto fazer isso ou que há algo de errado no que XSD especial
Barbazul
Talvez não seja a melhor prática, mas ele trabalhou para mim
JROCA22