Как правильно настроить канонические url для интернет-магазина на платформе Opencart.

Если вам приходилось создавать магазины на платформе opencart, то вы наверное замечали, что система не совсем корректно генерирует тег canonical для отдлельных товаров.

Например, путь в ссылке товара выглядит таким образом

www.site.com/category/product.html

Но канонический адрес в теге будет выглядеть так:

www.site.com/product.html

Что несовсем корректно с точки зрения SEO.

Как же это исправить и почему разработчкии opencart допустили такуж неточность.

Причина проста - система opencart позволяет назначать товарам несколько категорий, и именно в этом кроется причина такого поведения. Система не знает, какую именно категорию нужно подставить в canonical url.

Решение, которое приведено ниже, расчитано на то, что товар относиться только к одной категории.

Не забываем перед внесением любых правок делать бекапы и сохранять данные!

Для исправления отображения канонических адресов в системе opencart необходимо внести правки в такие файлы catalog/controller/product/product.php и catalog/model/catalog/product.php. (все относиться к 3 версии opencart, для других версий код может не сработать).

Итак, находим в файле catalog/controller/product/product.php код

$this->document->addLink($this->url->link('product/product', 'product_id=' . $this->request->get['product_id']), 'canonical');

и меняем его на:

if($this->model_catalog_product->getCategoryPath($this->request->get['product_id'])!='0'){
    $this->document->addLink($this->url->link('product/product', 'path=' . $this->model_catalog_product->getCategoryPath($this->request->get['product_id']) . '&product_id=' . $this->request->get['product_id']), 'canonical');
}else{
    $this->document->addLink($this->url->link('product/product', 'product_id=' . $this->request->get['product_id']), 'canonical');
}

После этого переходим в файл catalog/model/catalog/product.php и в конце класса перед последней закрывающейся фигурной скобкой добавляем еще один метод для получения категории товара.

}

меняем на

public function getCategoryPath($product_id) {
        $query = $this->db->query("SELECT COUNT(product_id) AS total, category_id as catid FROM " . DB_PREFIX . "product_to_category WHERE product_id = '" . (int)$product_id . "'");

        if($query->row['total']==1){
            $path = array();
            $path[0] = $query->row['catid'];

            $query = $this->db->query("SELECT parent_id AS pid FROM " . DB_PREFIX . "category WHERE category_id = '" . (int)$path[0] . "'");

            $parent = $query->row['pid'];

            $p = 1;
            while($parent>0){
                $path[$p] = $parent;

                $query = $this->db->query("SELECT parent_id AS pid FROM " . DB_PREFIX . "category WHERE category_id = '" . (int)$parent . "'");
                $parent = $query->row['pid'];
                $p++;
            }

            $path = array_reverse($path);

            $fullpath = '';

            foreach($path as $val){
                $fullpath .= '_'.$val;
            }

            return ltrim($fullpath, '_');
        }else{
            return '0';
        }
    }           

Сохраняем файлы и обновлем модификаторы.

После всех операций в канонических url сайта должны корректно отображаться категории.