Afficher l'URL canonique personnalisée sur la page de catégorie dans Magento 2

Aug 16 2020

J'ai créé un module pour ajouter un attribut de catégorie personnalisé (URL canonique personnalisée) à une page de catégorie. L'attribut s'affiche dans l'administrateur et je peux enregistrer la valeur. J'ai étendu la _prepareLayout()fonction de \Magento\Catalog\Block\Category\Viewmais cela ne semble pas fonctionner. Je manque quelque chose ou y a-t-il une meilleure façon de faire cela?

Example/CategoryCanonicalUrl/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Example_CategoryCanonicalUrl" setup_version="0.0.1">
    </module>
</config>

Example/CategoryCanonicalUrl/Setup/InstallData.php

<?php

namespace Example\CategoryCanonicalUrl\Setup;

use Magento\Catalog\Setup\CategorySetup;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

class InstallData implements InstallDataInterface
{
    /**
     * @var CategorySetup
     */
    private $categorySetup;

    public function __construct(
        CategorySetup $categorySetup
    ) {
        $this->categorySetup = $categorySetup;
    }

    /**
     * @inheritDoc
     */
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)
    {
        $setup->startSetup();

        $this->categorySetup->addAttribute(
            \Magento\Catalog\Model\Category::ENTITY,
            'custom_canonical_url',
            [
                'type' => 'varchar',
                'label' => 'Custom Canonical URL',
                'required' => false,
                'visible' => 1,
                'visible_on_front' => 1,
                'global' => \Magento\Eav\Model\Entity\Attribute\ScopedAttributeInterface::SCOPE_STORE,
                'group' => 'Search Engine Optimization',
            ]
        );

        $setup->endSetup();
    }
}

Example/CategoryCanonicalUrl/view/adminhtml/ui_component/category_form.xml

<?xml version="1.0"?>
<form xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Ui:etc/ui_configuration.xsd">
    <fieldset name="search_engine_optimization">
        <field name="custom_canonical_url" sortOrder="160" formElement="input">
            <settings>
                <dataType>string</dataType>
                <label translate="true">Custom Canonical URL</label>
                <scopeLabel>[STORE VIEW]</scopeLabel>
                <notice translate="true">URL without forward slash (/) e.g. example-category</notice>
            </settings>
        </field>
    </fieldset>
</form>

Example/CategoryCanonicalUrl/Block/Category/CanonicalUrl.php

<?php

namespace Example\CategoryCanonicalUrl\Block\Category;

class CanonicalUrl extends \Magento\Catalog\Block\Category\View
{
    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry = null;

    /**
     * Catalog layer
     *
     * @var \Magento\Catalog\Model\Layer
     */
    protected $_catalogLayer;

    /**
     * @var \Magento\Catalog\Helper\Category
     */
    protected $_categoryHelper;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Catalog\Helper\Category $categoryHelper
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Helper\Category $categoryHelper,
        array $data = []
    ) {
        $this->_categoryHelper = $categoryHelper;
        $this->_catalogLayer = $layerResolver->get();
        $this->_coreRegistry = $registry;
        parent::__construct($context, $data);
    }

    /**
     * @return $this
     */
    protected function _prepareLayout()
    {
        parent::_prepareLayout();

        $this->getLayout()->createBlock(\Magento\Catalog\Block\Breadcrumbs::class);

        $category = $this->getCurrentCategory();
        if ($category) {
            $title = $category->getMetaTitle();
            if ($title) {
                $this->pageConfig->getTitle()->set($title);
            }
            $description = $category->getMetaDescription();
            if ($description) {
                $this->pageConfig->setDescription($description);
            }
            $keywords = $category->getMetaKeywords();
            if ($keywords) {
                $this->pageConfig->setKeywords($keywords);
            }
            if ($this->_categoryHelper->canUseCanonicalTag()) {
                $customCanonicalUrl = trim($category->getCustomCanonicalUrl());

                if ($customCanonicalUrl) {
                    $canonicalUrl = $customCanonicalUrl;
                } else {
                    $canonicalUrl = $category->getUrl();
                }

                $this->pageConfig->addRemotePageAsset(
                    $canonicalUrl,
                    'canonical',
                    ['attributes' => ['rel' => 'canonical']]
                );
            }

            $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
            if ($pageMainTitle) {
                $pageMainTitle->setPageTitle($this->getCurrentCategory()->getName());
            }
        }

        return $this;
    }
}

Example/CategoryCanonicalUrl/registration.php

<?php \Magento\Framework\Component\ComponentRegistrar::register(
    \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Example_CategoryCanonicalUrl',
    __DIR__
);

Réponses

user3417608 Aug 17 2020 at 21:13

J'ai maintenant ce travail en faisant les changements suivants.

ÉtabliExample/CategoryCanonicalUrl/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">
    <preference for="Magento\Catalog\Block\Category\View" type="Example\CategoryCanonicalUrl\Block\Category\CanonicalUrl"/>
</config>

Ajouté ci-dessous àExample/CategoryCanonicalUrl/etc/module.xml

        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>

Ajusté à car j'obtenais une erreur.parent::__construct($context, $data);parent::__construct($context, $layerResolver, $registry, $categoryHelper, $data);Example/CategoryCanonicalUrl/Block/Category/CanonicalUrl.phpType Error occurred when creating object

Supprimé parent::_prepareLayout();de car j'obtenais des balises de lien canonique en double protected function _prepareLayout().Example/CategoryCanonicalUrl/Block/Category/CanonicalUrl.php

Gestionnaire de magasin ajouté à Example/CategoryCanonicalUrl/Block/Category/CanonicalUrl.phpl'URL canonique complète lorsque, par exemple, example-categoryest ajouté via l' Custom Canonical URLentrée dans la zone d'administration.

<?php

namespace Example\CategoryCanonicalUrl\Block\Category;

use Magento\Store\Model\Store;

class CanonicalUrl extends \Magento\Catalog\Block\Category\View
{
    /**
     * Core registry
     *
     * @var \Magento\Framework\Registry
     */
    protected $_coreRegistry = null;

    /**
     * Catalog layer
     *
     * @var \Magento\Catalog\Model\Layer
     */
    protected $_catalogLayer;

    /**
     * @var \Magento\Catalog\Helper\Category
     */
    protected $_categoryHelper;

    /**
     * Store manager
     *
     * @var \Magento\Store\Model\StoreManagerInterface
     */
    protected $_storeManager;

    /**
     * @param \Magento\Framework\View\Element\Template\Context $context
     * @param \Magento\Catalog\Model\Layer\Resolver $layerResolver
     * @param \Magento\Framework\Registry $registry
     * @param \Magento\Catalog\Helper\Category $categoryHelper
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param array $data
     */
    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        \Magento\Framework\Registry $registry,
        \Magento\Catalog\Helper\Category $categoryHelper,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        array $data = []
    ) {
        $this->_categoryHelper = $categoryHelper;
        $this->_catalogLayer = $layerResolver->get();
        $this->_coreRegistry = $registry;
        $this->_storeManager = $storeManager;
        parent::__construct($context, $layerResolver, $registry, $categoryHelper, $data);
    }

    /**
     * @return $this
     */
    protected function _prepareLayout()
    {
        $this->getLayout()->createBlock(\Magento\Catalog\Block\Breadcrumbs::class);

        $category = $this->getCurrentCategory();
        if ($category) {
            $title = $category->getMetaTitle();
            if ($title) {
                $this->pageConfig->getTitle()->set($title);
            }
            $description = $category->getMetaDescription();
            if ($description) {
                $this->pageConfig->setDescription($description);
            }
            $keywords = $category->getMetaKeywords();
            if ($keywords) {
                $this->pageConfig->setKeywords($keywords);
            }
            if ($this->_categoryHelper->canUseCanonicalTag()) {
                $customCanonicalUrl = trim($category->getCustomCanonicalUrl());

                if ($customCanonicalUrl) {
                    $canonicalUrl = $this->_storeManager->getStore()->getBaseUrl() . $customCanonicalUrl;
                } else {
                    $canonicalUrl = $category->getUrl();
                }

                $this->pageConfig->addRemotePageAsset(
                    $canonicalUrl,
                    'canonical',
                    ['attributes' => ['rel' => 'canonical']]
                );
            }

            $pageMainTitle = $this->getLayout()->getBlock('page.main.title');
            if ($pageMainTitle) {
                $pageMainTitle->setPageTitle($this->getCurrentCategory()->getName());
            }
        }

        return $this;
    }
}