Magento 2提供了大量的搜索引擎优化选项,但对于类别页面,我们只能选择添加规范的meta标签。 在这篇博客中,我们将尝试通过实现我们自己的规范标签的变体,并添加rel=“next”rel=“prev”标签来帮助具有分页。

实现上述功能有几种方法,但第一步很可能涉及创建新的Magento 2模块我决定使用事件观察器的方式来实现我们的逻辑,所以我们要做的第一件事是配置我们的模块来观察某些事件。我们通过在模块etc/frontend文件夹中创建events.xml文件,然后创建我们的observer类来完成此操作。

<?xml version="1.0"?>
 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
    <event name="layout_generate_blocks_after">
        <observer name="categorySeo" instance="Magease\CategorySeo\Observer\Category" />
    </event>
</config>

从上面的XML中可以看出,我们正在观察layout_generate_blocks_after事件。由于此事件不是类别页面所独有的,因此我们在观察者执行方法中首先要检查我们是否确实在类别视图页面上。这很简单,因为我们已经在事件对象数据中包含完整的操作名称。

if ('catalog_category_view' != $observer->getEvent()->getFullActionName()) {
    return $this;
}

 

替换默认的规范标签

我们这样做是因为在默认实现中,规范化标签总是指向根类别URL,而不管应用的是哪个页面或筛选器组合。

要删除默认的规范标签,我们需要类别模型实例。您可以使用registry (current_category)检索它。在这个例子中,我使用layout对象,因为它也是事件对象数据的一部分。

/** @var \Magento\Catalog\Block\Product\ListProduct $productListBlock */
$productListBlock = $observer->getEvent()->getLayout()->getBlock('category.products.list');
$category = $productListBlock->getLayer()->getCurrentCategory();
 
/**
 * Remove default canonical tag
 */
if ($this->categoryHelper->canUseCanonicalTag()) {
    $this->pageConfig->getAssetCollection()->remove($category->getUrl());
}

我们现在可以添加自己的规范标签。为此,我们将使用页块实例(\Magento\Theme\Block\Html\Pager)生成我们的规范URL和页面配置(\Magento\Framework\View\Page\Config)来插入它。

/** @var \Magento\Catalog\Block\Product\ProductList\Toolbar $toolbarBlock */
$toolbarBlock = $productListBlock->getToolbarBlock();
/** @var \Magento\Theme\Block\Html\Pager $pagerBlock */
$pagerBlock = $toolbarBlock->getChildBlock('product_list_toolbar_pager');
$pagerBlock->setAvailableLimit($toolbarBlock->getAvailableLimit())
    ->setCollection($productListBlock->getLayer()->getProductCollection());
 
/**
 * Add rel canonical with page var
 */
$this->pageConfig->addRemotePageAsset(
    $this->getPageUrl([
        $pagerBlock->getPageVarName() => $pagerBlock->getCurrentPage()
    ]),
    'canonical',
    ['attributes' => ['rel' => 'canonical']]
);

您可能会注意到我们正在使用自己的getPageUrl方法。这是该方法的一个稍微定制的版本,可以在\Magento\Theme\Block\Html\Pager类中找到

/**
* Retrieve page URL by defined parameters
*
* @param array $params
* @return string
*/
protected function getPageUrl($params = [])
{
    $urlParams = [];
    $urlParams['_current'] = false;
    $urlParams['_escape'] = true;
    $urlParams['_use_rewrite'] = true;
    $urlParams['_query'] = $params;
 
    return $this->urlBuilder->getUrl('*/*/*', $urlParams);
}

 

添加rel =“prev”和rel =“next”

最后一步涉及添加rel =“prev”rel =“next”以指示分页内容。通过这样做,我们告诉搜索引擎将这些页面视为逻辑顺序,从而巩固它们的链接属性,并且通常将搜索器发送到第一页面。

/**
 * Add rel prev and rel next
 */
if (1 < $pagerBlock->getCurrentPage()) {
    $this->pageConfig->addRemotePageAsset(
        $this->getPageUrl([
            $pagerBlock->getPageVarName() => $pagerBlock->getCollection()->getCurPage(-1)
        ]),
        'link_rel',
        ['attributes' => ['rel' => 'prev']]
    );
}
if ($pagerBlock->getCurrentPage() < $pagerBlock->getLastPageNum()) {
    $this->pageConfig->addRemotePageAsset(
        $this->getPageUrl([
            $pagerBlock->getPageVarName() => $pagerBlock->getCollection()->getCurPage(+1)
        ]),
        'link_rel',
        ['attributes' => ['rel' => 'next']]
    );
}