I've created a module to add a custom category attribute (custom canonical URL) to a category page. The attribute displays in the admin and I can save the value. I've extended _prepareLayout()
function of \Magento\Catalog\Block\Category\View
but it doesn't seem to be working. I'm I missing something or is there a better way to do this?
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__
);