I've created a module to add a custom category attribute (custom canonical URL) to a category page, based on Display custom canonical URL on category page in Magento 2 question.
Here is the contents of Vendor/Module/Block/Category/CanonicalUrl.php
:
<?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;
}
}
I implemented his answer but it isn't working for me. 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()
return null, so I'm unable to insert the custom_canonical_url
attribute value in the category page.
Also, I notice that I'm getting the following errors in my system.log
:
main.CRITICAL: Invalid template file: 'category/banner.phtml' in module: 'Example_CategoryCanonicalUrl' block's name: 'category_banner' [] []
main.CRITICAL: Invalid template file: 'category/desc_main_column.phtml' in module: 'Example_CategoryCanonicalUrl' block's name: 'category_desc_main_column' [] []
What am I doing wrong?