Jump to content

How to set 2 different URLs for the same product?


Recommended Posts

Hi there,

The product has different categories. And it is displayed on each category page.

For example, product-1 has category-1, category-2, category-3. But the default category is "category-1". So the link to this product will be https://site.com/category-1/product-1.

But I need to set a link to the product depends on the category page from where this product is opened.

So if I open category-2 page the link to this product needs to be https://site.com/category-2/product-1.

If I open category-3 page the link to this product needs to be https://site.com/category-3/product-1.

And I need to have all these links to be working. How can I do it?

Because when I open a link https://site.com/category-2/product-1 it redirects me to the default link - https://site.com/category-1/product-1.

Thanks.

Link to comment
Share on other sites

A basic assumption from a SEO point of view is that there should not be duplicate content, that's why it should be hard to achieve something like this, only by some custom module overriding default code. By default prestashop uses product's default category to build a link.

Link to comment
Share on other sites

Yes, I tried to set another default category for building a link - it works. But when I use this new link it redirects me to the default product link (using default product category). Where do I need to update this functionality?

Regarding duplicate content - I use category name in the product title, description and breadcrumbs - that's why they will be different.

Link to comment
Share on other sites

Here my settings on Traffic & SEO page for product link - {category:/}{rewrite}.html

And here the category is used as default. And the link to the product will be like this - https://site.com/category-1/product-1.

When I open this link https://site.com/category-2/product-1 the site redirects me to https://site.com/category-1/product-1. But I need to have this link https://site.com/category-2/product-1 also working. I understand that I need to do some changes to the source code. But I can't find where exactly.

Link to comment
Share on other sites

  • 1 year later...

Hi there!

I've solved the this task. Probably it may be helpful for someone.

Add these lines in the file /override/classes/Category.php before return.

public function getProducts

...

// Set id_category_link to the current category if ... <condition>
// id_category_link is used to prepare URL
if (in_array($this->id, $array_condition)) {
    foreach ($result as &$product) {
        $product['id_category_link'] = (int)$this->id;
    }
}

return Product::getProductsProperties($idLang, $result);


Add the following functions in the file /override/classes/Product.php

/**
 * Get product default category name for a given product ID or
 * get product category name for a given product ID and category ID
 *
 * @param int $id_product
 * @param int $id_category_default
 * @param int $id_category_link
 *
 * @return string Category Name
 */
public static function getCategoryForProduct($id_product, $id_category_default = 0, $id_category_link = 0)
{
    if (empty($id_product)) return false;

    $id_lang = Context::getContext()->language->id;

    // Check if the product has category ID
    if (!empty($id_category_link) && ($id_category_default != $id_category_link) && Product::checkProductCategoryByID($id_product, $id_category_link)) {
        return Product::getCategoryForProductByID($id_product, $id_category_link);
    } else {
        $sql = 'SELECT cl.name as cat_name FROM `' . _DB_PREFIX_ . 'product` p
                LEFT JOIN ' . _DB_PREFIX_ . 'category_lang cl ON (cl.id_category = p.id_category_default AND cl.id_lang = ' . (int)$id_lang . ')
                ' . Shop::addSqlAssociation('product', 'p') . '
                WHERE p.id_product = ' . (int)$id_product;
        return Db::getInstance(_PS_USE_SQL_SLAVE_)->getValue($sql);
    }
}

/**
 * Get product URL based on category ID and product ID
 *
 * @param string $url
 * @param int $id_product
 * @param int $id_category_default
 * @param int $id_category_link
 *
 * @return string Product URL
 */
public static function getProductURLByCategory($url, $id_product, $id_category_default, $id_category_link)
{
    if (empty($id_category_link) || empty($id_product)) return $url;
    if ($id_category_default == $id_category_link) return $url; // Link is correct - based on default category

    // Check if the product has this category and create a new product URL
    if (Product::checkProductCategoryByID($id_product, $id_category_link)) {
        $link = new Link();
        $id_lang = Context::getContext()->language->id;
        $category_link_rewrite = Category::getLinkRewrite($id_category_link, $id_lang);
        $url = $link->getProductLink($id_product, null, $category_link_rewrite, null, $id_lang);
    }
    
    return $url;
}

And then I did small updates in the tpl files and breadcrumbs. But the major changes in the functionality is described above.

Thanks.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...