16

I am trying to get rewrite product url from the load product in custom module. I am getting url in http://localhost/m2/catalog/product/view/id/1401/category/23/ format .

But I want http://localhost/m2/juno-jacket.html

Here is the code

in constructor

public function __construct(
    \Magento\Catalog\Helper\Product $catalogProductHelper,
) {
    $this->catalogProductHelper = $catalogProductHelper;
}

Custom function

public function abc(){
    $product_id = '123';
    return  $this->catalogProductHelper->getProductUrl($product_id);
}

abc() method return url like http://localhost/m2/catalog/product/view/id/1401/category/23/

7
  • rebuild your indexes
    – Marius
    Mar 17, 2016 at 14:30
  • @Marius : i have rebuild too. It is not returning product rewrite url. Mar 17, 2016 at 15:01
  • is your product associated to any website?
    – Marius
    Mar 17, 2016 at 15:05
  • I have assigned product in main website Mar 17, 2016 at 15:09
  • getProductUrl() is supposed to return the rewritten URL if the entry exist in url_rewrite. Did you delete records from this table manually?
    – laketuna
    Mar 17, 2016 at 15:12

3 Answers 3

6

Here is the method I used to get the product url.

It is definitely not optimal as I have to load the entire product to get it so very bad in terms of performance.

First you need to inject a Magento\Catalog\Model\ProductRepository in your constructor:

use Magento\Catalog\Model\ProductRepository;
//...
public function __construct(
    ProductRepository $productRepository
) {
    $this->_productRepository = $productRepository;
}

Then you load the product based on the product id:

$product = $this->_productRepository->getById($productId);

Finally you can get the URL model to retrieve the rewritten URL:

return $product->getUrlModel()->getUrl($product);
6
  • The double comma at the end isn't intended, isn't it?
    – Max
    Oct 19, 2016 at 11:31
  • @Max yeah totally, I removed it Oct 19, 2016 at 11:38
  • 5
    I am facing the same and I have tried your code but still the urls are incorrect for me. Please advise. Feb 7, 2017 at 7:36
  • Another way (and less perf-killer) may be to force the addition of URL rewrites on product collection load. See my answer. May 26, 2017 at 11:25
  • same error can you please tell me where i can put this code ? Jul 22, 2017 at 10:51
3

This may not really answer the question but chances are that, if you are missing the URL rewrite, you may be getting your product out of a product collection. And adding URL rewrite info is not automatic as you can see in \Magento\Catalog\Model\ResourceModel\Product\Collection::$_addUrlRewrite.

The way I managed forcing the addition of URL rewrites is by creating a plugin on the create() method of \Magento\Catalog\Model\ResourceModel\Product\CollectionFactory. And as soon as your code (or Magento's core code) uses this factory for instanciating a product collection (and it should as of best practices), this plugin forces the \Magento\Catalog\Model\ResourceModel\Product\Collection::$_addUrlRewrite to true.

Then, products URL rewrites are successfully added to the products without the need to loop on them and reload them. It thus fixes the perf downside that @Raphael spoke about.

Here is the plugin XML definition (in your di.xml file):

<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Catalog\Model\ResourceModel\Product\CollectionFactory">
        <plugin name="your_plugin_unique_nane" type="Your\Plugin\Namespace\Plugin" />
    </type>
</config>

And the plugin code:

namespace Your\Plugin\Namespace;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as CoreCollectionFactory;

class Plugin
{
    /**
     * @param CoreCollectionFactory $subject
     * @param Collection $collection
     * @return Collection
     */
    public function afterCreate(CoreCollectionFactory $subject, Collection $collection)
    {
        $collection->addUrlRewrite();

        return $collection;
    }
}
1
  • I tried this way, but plugin class is not executing. Do you know why?
    – Deeps
    May 24, 2018 at 11:23
0

Export your products to a csv file

from the csv file in Excel use this formula for the url_key column

="https://www.yourdomain.com/"&P103&".html"

where "P103" is the url_key column

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.