Search code examples
php.htaccessseoopencart

How can I create custom SEO-friendly URLs in OpenCart?


How can you customize system URLs in OpenCart? For example, I would like http://example.com/index.php?route=checkout/cart to be displayed as http://example.com/cart

I know OpenCart provides SEO URLs for products, categories, manufacturers and information pages, but it doesn't look like there is anything built-in (at least prior to version 1.5.0) for anything else.


Solution

  • It turns out this can be done with a relatively simple change to a single file. No .htaccess rewrite rules, simply patch the catalog/controller/common/seo_url.php file and add your pretty URLs to an existing database table.


    The patch to seo_url.php:

    Index: catalog/controller/common/seo_url.php
    ===================================================================
    --- catalog/controller/common/seo_url.php   (old)
    +++ catalog/controller/common/seo_url.php   (new)
    @@ -48,7 +42,12 @@
                    $this->request->get['route'] = 'product/manufacturer/product';
                } elseif (isset($this->request->get['information_id'])) {
                    $this->request->get['route'] = 'information/information';
    -           }
    +           } else {
    +                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($this->request->get['_route_']) . "'");
    +                if ($query->num_rows) {
    +                    $this->request->get['route'] = $query->row['query'];
    +                }
    +           }
    
                if (isset($this->request->get['route'])) {
                    return $this->forward($this->request->get['route']);
    @@ -88,7 +87,15 @@
                            }
    
                            unset($data[$key]);
    -                   }
    +                   } else {
    +                        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($data['route']) . "'");
    +
    +                        if ($query->num_rows) {
    +                            $url .= '/' . $query->row['keyword'];
    +
    +                            unset($data[$key]);
    +                        }
    +                   }
                    }
                }
    

    There are two edits required. The first extends the index() function to look in the url_alias table for any keyword matching $this->request->get['_route_'].

    The second extends the rewrite() function to look in the url_alias table for all routes, not just those for products, manufacturers, and information pages.


    Adding entries to the database:

    INSERT INTO `url_alias` (`url_alias_id`, `query`, `keyword`) VALUES
    (NULL, 'checkout/cart', 'cart');
    

    That's it. http://example.com/cart should return the same thing that http://example.com/index.php?route=checkout/cart does, and OpenCart should recognize $this->url->link('checkout/cart'); and return a link to the pretty URL http://example.com/cart