I've created a module to add a custom category attribute (custom canonical URL) to a category page. Here is my block:
<?php
namespace Vendor\Module\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;
$this->_logger = $logger;
parent::__construct($context, $layerResolver, $registry, $categoryHelper, $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 = $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;
}
}Inside the protected function _prepareLayout() within CanonicalUrl.php it seems $category->getCurrentCategory() seems to work because if I insert $category->getId() immediately after it, the correct Id of the category is retrieved. Also later in the code, $category->getUrl() also correctly retrieves the url of the category.
However, $category->getMetaTitle(), $category->getMetaKeywords(), and $category->getCustomCanonicalUrl() (which should retrieve the attribute 'custom_canonical_url' I added to the Search Engine Optimization group in my module's InstallData.php) all return null, so I'm unable to insert the custom_canonical_url attribute value in the category page.
Why are all these returning null? I assume the reason is the same for all three.