Advertisement
  1. Code
  2. Coding Fundamentals
  3. Databases & SQL

How to Rewrite Custom URLs in OpenCart

Scroll to top

In the course of this tutorial, we'll go through the details of custom SEO-friendly URLs. It's an important aspect you should look at while developing custom modules, and it affects the overall search engine rankings as well.

We'll use the latest version of OpenCart, so make sure that you've installed that to follow the code.

What We Are Going to Do—in a Nutshell

Here's a summary of the steps we'll need to take to achieve custom URLs in OpenCart:

  • First, we will need to understand how it works in the core.
  • We'll go through the changes required in the core files.
  • We'll take a quick look at the SQL queries to insert our custom URL mappings.
  • We'll cover how to use built-in rewrite functions.

So, that's the quick glance of what's coming up next. Let's move on to the first topic.

The URL Mappings in a Database

First of all, it's important to understand how SEO URLs work in the core of OpenCart.

Go ahead and explore the entries in the "url_alias" MySQL table using phpMyAdmin or something similar. You'll see mappings like this.

1
product_id=48       ipod-classic
2
category_id=20      desktops
3
manufacturer_id=8   apple
4
information_id=6    delivery

There are two important columns to note here. The first one is the query column which stores the actual path, and the other is keyword, which stores the SEO alias for that URL.

As you can see, there are mappings for different entities like product, category, information, and manufacturer. Whenever any entity is saved in the back-end of OpenCart, an associated entry is added to this table.

In the front-end, whenever the user accesses the URL, OpenCart finds the related mapping from the "url_alias" table. In this way, the actual entity is mapped to the SEO-friendly URL.

Go ahead and open the file catalog/controller/common/seo_url.php, and let's explore the following snippet from the index method.

1
public function index() {
2
	// Add rewrite to url class

3
	if ($this->config->get('config_seo_url')) {
4
		$this->url->addRewrite($this);
5
	}
6
7
	// Decode URL

8
	if (isset($this->request->get['_route_'])) {
9
		$parts = explode('/', $this->request->get['_route_']);
10
11
		// remove any empty arrays from trailing

12
		if (utf8_strlen(end($parts)) == 0) {
13
			array_pop($parts);
14
		}
15
16
		foreach ($parts as $part) {
17
			$query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");
18
19
			if ($query->num_rows) {
20
				$url = explode('=', $query->row['query']);
21
22
				if ($url[0] == 'product_id') {
23
					$this->request->get['product_id'] = $url[1];
24
				}
25
26
				if ($url[0] == 'category_id') {
27
					if (!isset($this->request->get['path'])) {
28
						$this->request->get['path'] = $url[1];
29
					} else {
30
						$this->request->get['path'] .= '_' . $url[1];
31
					}
32
				}
33
34
				if ($url[0] == 'manufacturer_id') {
35
					$this->request->get['manufacturer_id'] = $url[1];
36
				}
37
38
				if ($url[0] == 'information_id') {
39
					$this->request->get['information_id'] = $url[1];
40
				}
41
42
				if ($query->row['query'] && $url[0] != 'information_id' && $url[0] != 'manufacturer_id' && $url[0] != 'category_id' && $url[0] != 'product_id') {
43
					$this->request->get['route'] = $query->row['query'];
44
				}
45
			} else {
46
				$this->request->get['route'] = 'error/not_found';
47
48
				break;
49
			}
50
		}
51
52
		if (!isset($this->request->get['route'])) {
53
			if (isset($this->request->get['product_id'])) {
54
				$this->request->get['route'] = 'product/product';
55
			} elseif (isset($this->request->get['path'])) {
56
				$this->request->get['route'] = 'product/category';
57
			} elseif (isset($this->request->get['manufacturer_id'])) {
58
				$this->request->get['route'] = 'product/manufacturer/info';
59
			} elseif (isset($this->request->get['information_id'])) {
60
				$this->request->get['route'] = 'information/information';
61
			}
62
		}
63
64
		if (isset($this->request->get['route'])) {
65
			return new Action($this->request->get['route']);
66
		}
67
	}
68
}

As you can see, we are fetching the associated entry from the "url_alias" table. After that, the query parameter is parsed and an associated internal path is returned.

So, this is the way it works in the core. Unfortunately, the setup only works for core URLs—for custom URLs we need to alter the core code. That's the recipe of our next section.

The Core File Changes

Go ahead and open the file catalog/controller/common/seo_url.php, and replace the rewrite method with the following one.

1
public function rewrite($link) {
2
    $url_info = parse_url(str_replace('&', '&', $link));
3
4
    $url = '';
5
6
    $data = array();
7
    parse_str($url_info['query'], $data);
8
9
    foreach ($data as $key => $value) {
10
        if (isset($data['route'])) {
11
            if (($data['route'] == 'product/product' && $key == 'product_id') || (($data['route'] == 'product/manufacturer/info' || $data['route'] == 'product/product') && $key == 'manufacturer_id') || ($data['route'] == 'information/information' && $key == 'information_id')) {
12
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($key . '=' . (int)$value) . "'");
13
14
                if ($query->num_rows && $query->row['keyword']) {
15
                    $url .= '/' . $query->row['keyword'];
16
17
                    unset($data[$key]);
18
                }
19
            } elseif ($key == 'path') {
20
                $categories = explode('_', $value);
21
22
                foreach ($categories as $category) {
23
                    $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = 'category_id=" . (int)$category . "'");
24
25
                    if ($query->num_rows && $query->row['keyword']) {
26
                        $url .= '/' . $query->row['keyword'];
27
                    } else {
28
                        $url = '';
29
30
                        break;
31
                    }
32
                }
33
34
                unset($data[$key]);
35
            // OUR CUSTOM CODE

36
            } else {
37
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $data['route'] . "'");
38
39
                if ($query->num_rows && $query->row['keyword']) {
40
                    $url .= '/' . $query->row['keyword'];
41
                } else {
42
                    $url = '';
43
                    
44
                    break;
45
                }
46
            }
47
            // OUR CUSTOM CODE

48
        }
49
    }
50
51
    if ($url) {
52
        unset($data['route']);
53
            $query = '';
54
55
        if ($data) {
56
            foreach ($data as $key => $value) {
57
                $query .= '&' . rawurlencode((string)$key) . '=' . rawurlencode((string)$value);
58
            }
59
60
            if ($query) {
61
                $query = '?' . str_replace('&', '&', trim($query, '&'));
62
            }
63
        }
64
65
        return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query;
66
    } else {
67
        return $link;
68
    }
69
}

The rewrite method is used to convert an internal URL into an SEO-friendly URL. But it does this only for internal URLs. Hence, we need to add custom code to make it work for our custom modules as well. In our code changes, we have provided the last else case which loads the mapping for our custom module. We have not added our custom mapping yet, so let's do it in our next section.

Although we have modified the core file directly, it's just for the sake of simplicity. You should use OCMOD to alter the core file without actually modifying it.

Add MySQL Entries

In this section, we will add an SEO URL mapping for our custom module. Again, it's a plain SQL for example purposes—you can achieve that using module install scripts.

1
INSERT INTO `url_alias` (`query`, `keyword`) VALUES ('custom/custom', 'custom-rewrite');

Go ahead and run it in your OpenCart database.

In the next and final section, we will see how to use the helper function to produce SEO-friendly links.

How It Works

Go ahead and create a new file catalog/controller/custom/custom.php with the following contents.

1
<?php
2
class ControllerCustomCustom extends Controller {
3
    function index() {
4
        $data['customlink'] = $this->url->link('custom/custom');
5
        $this->response->setOutput('<a href="'.$data['customlink'].'">Custom URL Rewrite Link</a>');
6
    }
7
}

Now, in the front-end, open the URL http://www.yourstore.com/index.php?route=custom/custom.

Yeah, it's a plain white screen just with one link, and that is what we intended. The important thing to note here is the URL of that link— it's now SEO-friendly! Click on that and it will load the same page, as we have added the mapping for that in the "url_alias" table.

So, that's the whole concept demonstrated in a simple way. You could extend it and make a model to insert SEO-friendly links for your custom module.

Conclusion

Today, we have discussed an important topic in OpenCart—custom SEO-friendly URLs. We took a very simple approach to explain it, and I hope that it was useful for you.

If you're looking for additional OpenCart tools, utilities, extensions, and so on that you can leverage in your own projects or for your own education, don't forget to see what we have available in the marketplace.

Feel free to post your queries and suggestions using the feed below.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.