Remove index.php?route=common/home from OpenCart

2020-01-26 06:19发布

问题:

I currently have User SEO URL's set to Yes in OpenCart Admin.

System -> Settings -> Store -> Server -> User SEO URL's

So far, all tags and SEO links are working; the command has done the desired effect.

However for the homepage and a few other links; how do I remove:

index.php?route=common/home

From the URL? Do I have to literally do a find and replace in the hardcode PHP files and risk upgrades or is there another way?

(without bloating performance i.e no poor amateur tools such as vQmod)

回答1:

To simply remove that, you can do a basic replace in /catalog/controller/common/seo_url.php

Find:

return $link;

Before it on a new line put:

$link = str_replace('index.php?route=common/home', '', $link);

Edit by TheBlackBenzKid: If you want full SEO just use this line instead of the above:

$link = str_replace('index.php?route=', '', $link);

Also make sure SEO URLs is turned on in the Admin panel of the store.



回答2:

The previous "solutions" are wrong because they are attacking the SEO URL translate. What you want is to deal with the URL generation inside OpenCart.

Let's keep it simple. Go to /system/library/url.php and look at the public function link. Replace the function with this version:

public function link($route, $args = '', $connection = 'NONSSL') {
    if ('NONSSL' == $connection) {
        $url = $this->url;
    } else {
        $url = $this->ssl;  
    }

    if ('common/home' == $route) {
        if ($args) {
            $url .= '?' . str_replace('&', '&', '&' . ltrim($args, '&')); 
        }
    } else {
        $url .= 'index.php?route=' . $route;
        if ($args) {
            $url .= str_replace('&', '&', '&' . ltrim($args, '&')); 
        }
    }

    foreach ($this->rewrite as $rewrite) {
        $url = $rewrite->rewrite($url);
    }

    return $url;
}

Simple like that. I can't belive why this is not in OpenCart's core.

EDIT:

I run some tests and if the SEO URLs are enabled, it becomes necessary to make one single edit in the /catalog/controller/common/seo_url.php to avoid an "Undefined index" error.

Inside public function rewrite, replace this line:

parse_str($url_info['query'], $data);

With this one:

if (isset($url_info['query'])) parse_str($url_info['query'], $data);

Now it really works.



回答3:

I really like Victor Schröder's solution above for it's simplicity. Thanks! I created a vQmod based on his code mods in case it would be helpful to anyone. here is the code:

<modification>

    <file name="system/library/url.php">
        <operation>
            <search position="before"><![CDATA[$url .= 'index.php?route=' . $route;]]></search>
            <add><![CDATA[
                if ('common/home' == $route) {
                    if ($args) {
                        $url .= '?' . str_replace('&', '&amp;', '&' . ltrim($args, '&'));
                    }
                } else {
            ]]></add>
        </operation>
        <operation>
            <search position="before"><![CDATA[foreach ($this->rewrite as $rewrite) {]]></search>
            <add><![CDATA[
                }
            ]]></add>
        </operation>
    </file>

    <file name="catalog/controller/common/seo_url.php">
        <operation>
            <search position="replace"><![CDATA[parse_str($url_info['query'], $data);]]></search>
            <add><![CDATA[
                if (isset($url_info['query'])) parse_str($url_info['query'], $data);
            ]]></add>
        </operation>
    </file>

</modification>


回答4:

How about replacing a link in logo with <?php echo $base; ?>. It will make a link to base domain and will remove index.php?route=common/home.



回答5:

Jay's solution doesn't work for me, after editing I get blank screen. So I made a new one:

Put the line before:

return $link;

Instead of after:

public function rewrite($link) {


回答6:

So, I'm using 1.5.5.1 and no one answer on this question solved my problem. However, combining the answers from @Jay Gilford, @TheBlackBenzKid and @rkaartikeyen I came up with a fully working solution.

Remember to enable seo urls as shown by @TheBlackBenzKid.

An explanation can be found below the code.

[php]
class ControllerCommonSeoUrl extends Controller {
    public function index() {
        // Add rewrite to url class
        if ($this->config->get('config_seo_url')) {
            $this->url->addRewrite($this);
        }

        // Decode URL
        if (isset($this->request->get['_route_'])) {
            $parts = explode('/', $this->request->get['_route_']);

            foreach ($parts as $part) {
                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");

                if ($query->num_rows) {
                    $url = explode('=', $query->row['query']);

                    if ($url[0] == 'product_id') {
                        $this->request->get['product_id'] = $url[1];
                    }

                    if ($url[0] == 'category_id') {
                        if (!isset($this->request->get['path'])) {
                            $this->request->get['path'] = $url[1];
                        } else {
                            $this->request->get['path'] .= '_' . $url[1];
                        }
                    }   

                    if ($url[0] == 'manufacturer_id') {
                        $this->request->get['manufacturer_id'] = $url[1];
                    }

                    if ($url[0] == 'information_id') {
                        $this->request->get['information_id'] = $url[1];
                    }   
                } else {
                    $this->request->get['route'] = 'error/not_found';   
                }
            }

            if (isset($this->request->get['product_id'])) {
                $this->request->get['route'] = 'product/product';
            } elseif (isset($this->request->get['path'])) {
                $this->request->get['route'] = 'product/category';
            } elseif (isset($this->request->get['manufacturer_id'])) {
                $this->request->get['route'] = 'product/manufacturer/info';
            } elseif (isset($this->request->get['information_id'])) {
                $this->request->get['route'] = 'information/information';
            }else {
                $this->request->get['route'] = $this->request->get['_route_'];
            }

            if (isset($this->request->get['route'])) {
                return $this->forward($this->request->get['route']);
            }
        }
    }

    public function rewrite($link) {
        $url_info = parse_url(str_replace('&', '&', $link));

        $url = ''; 

        $data = array();

        parse_str($url_info['query'], $data);

        foreach ($data as $key => $value) {
            if (isset($data['route'])) {
                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')) {
                    $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($key . '=' . (int)$value) . "'");

                    if ($query->num_rows) {
                        $url .= '/' . $query->row['keyword'];

                        unset($data[$key]);
                    }                   
                } elseif ($key == 'path') {
                    $categories = explode('_', $value);

                    foreach ($categories as $category) {
                        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = 'category_id=" . (int)$category . "'");

                        if ($query->num_rows) {
                            $url .= '/' . $query->row['keyword'];
                        }                           
                    }

                    unset($data[$key]);
                }
            }
        }

        if ($url) {
            unset($data['route']);

            $query = '';

            if ($data) {
                foreach ($data as $key => $value) {
                    $query .= '&' . $key . '=' . $value;
                }

                if ($query) {
                    $query = '?' . trim($query, '&');
                }
            }

            return $url_info['scheme'] . '://' . $url_info['host'] . (isset($url_info['port']) ? ':' . $url_info['port'] : '') . str_replace('/index.php', '', $url_info['path']) . $url . $query;
        } else {
            $link = str_replace('index.php?route=', '', $link);
            return $link;
        }
    }   
}

Apparently, @Jay Gilford and @TheBlackBenzKid solve the issue of the urls being properly written on the page.

Line 113

$link = str_replace('index.php?route=', '', $link);

But it seems to break the urls since the Controller can't find the pages and therefore reverts to the error page.

Line 38 - 40

} else {
    $this->request->get['route'] = 'error/not_found';   
}

@rkaartikeyen's solution solves this problem by setting the current route to the requested route

Line 51 - 53

else {
    $this->request->get['route'] = $this->request->get['_route_'];
}


回答7:

Step 01. Enable USE SEO URL’s in your store server settings

Go to the “System” and click on “Settings”. Locate the store you want to alter and click the “Edit” link on the right. Finally click the “Server” tab and set the SEO URL’s radio to “Yes” and save your settings.

Note: The keywords will not be created for you automatically. You must also have Apache mod_rewrite turned on. Most web hosts will have this on by default. Step 3 of this tutorial will explain how to add the keywords.

Step 02. Change some content in your .htaccess file to make your homepage SEO URL Friendly

Go to your host control panel and edit your .htaccess file. Sometimes this file is hidden in order to unhide it you can click on your web host control panel file manager and tick the show hidden files option followed by the “go” button.

Once you locate the .htaccess file change the following lines:

RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]

To:

RewriteBase /
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L]
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_URI} !.*\.(ico|gif|jpg|jpeg|png|js|css)
RewriteRule ^([^?]*) index.php?_route_=$1 [L,QSA]
RewriteCond %{QUERY_STRING} ^route=common/home$
RewriteRule ^index\.php$ http://www.yourwebsite.co.uk? [R=301,L]

If you do the step above your home page will change from something like this: http://yourwebsite.com/index.php?route=common/home to this: http://yourwebsite.com

Step 03. Enter SEO Keywords for URL’s manually Finally, you need to enter SEO keywords for every page, information, product and category you want to have URL rewrite. You can find the field for the SEO Keywords under the Data tab when editing and creating items.

Once you have entered the SEO Keywords your URL’s will be working.

Once you have followed all these instructions you can begin to reap the benefits of higher rankings, increased traffic and more customers.



回答8:

I came late but my solution could be useful for others (tested on Opencart 2.0.3.1):

Open your MySQL console and run this query (change YOURDATABASE with your db name):

INSERT INTO `YOURDATABASE`.`url_alias` (`url_alias_id`, `query`, `keyword`) VALUES (NULL, 'common/home', ' ');

How it works:

The trick consists in adding a WHITE SPACE (' ') for the column "keyword", if you insert an empty string ('') this workaround doesn't work and the url rewriter will return again index.php?route=common/home.



回答9:

/catalog/controller/common/seo_url.php

Open the file and replace the below code

<?php
class ControllerCommonSeoUrl extends Controller {
    public function index() {
        // Add rewrite to url class
        if ($this->config->get('config_seo_url')) {
            $this->url->addRewrite($this);
        }

        // Decode URL
        if (isset($this->request->get['_route_'])) {
            $parts = explode('/', $this->request->get['_route_']);

            foreach ($parts as $part) {

                $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");

                if ($query->num_rows) {
                    $url = explode('=', $query->row['query']);

                    if ($url[0] == 'product_id') {
                        $this->request->get['product_id'] = $url[1];
                    }

                    if ($url[0] == 'category_id') {
                        if (!isset($this->request->get['path'])) {
                            $this->request->get['path'] = $url[1];
                        } else {
                            $this->request->get['path'] .= '_' . $url[1];
                        }
                    }   

                    if ($url[0] == 'manufacturer_id') {
                        $this->request->get['manufacturer_id'] = $url[1];
                    }

                    if ($url[0] == 'information_id') {
                        $this->request->get['information_id'] = $url[1];
                    }   
                } else {
                    $this->request->get['route'] = 'error/not_found';   
                }
            }

            if (isset($this->request->get['product_id'])) {
                $this->request->get['route'] = 'product/product';
            } elseif (isset($this->request->get['path'])) {
                $this->request->get['route'] = 'product/category';
            } elseif (isset($this->request->get['manufacturer_id'])) {
                $this->request->get['route'] = 'product/manufacturer/info';
            } elseif (isset($this->request->get['information_id'])) {
                $this->request->get['route'] = 'information/information';
            }else {
                $this->request->get['route'] = $this->request->get['_route_'];
            }

            if (isset($this->request->get['route'])) {
                return $this->forward($this->request->get['route']);
            }
        }
    }

    public function rewrite($link) {
        if ($this->config->get('config_seo_url')) {
            $url_data = parse_url(str_replace('&amp;', '&', $link));
            $url = ''; 

            $data = array();

            parse_str($url_data['query'], $data);
            foreach ($data as $key => $value) {

                if (isset($data['route'])) {
                    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')) {
                        $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" . $this->db->escape($key . '=' . (int)$value) . "'");

                        if ($query->num_rows) {
                            $url .= '/' . $query->row['keyword'];

                            unset($data[$key]);
                        }                   
                    } elseif ($key == 'path') {
                        $categories = explode('_', $value);

                        foreach ($categories as $category) {
                            $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = 'category_id=" . (int)$category . "'");

                            if ($query->num_rows) {
                                $url .= '/' . $query->row['keyword'];
                            }                           
                        }

                        unset($data[$key]);
                    }else {
                        $url .= '/'.$value;
                    }
                }
            }

            if ($url) {
                unset($data['route']);

                $query = '';

                if ($data) {
                    foreach ($data as $key => $value) {
                        $query .= '&' . $key . '=' . $value;
                    }

                    if ($query) {
                        $query = '?' . trim($query, '&');
                    }
                }

                return $url_data['scheme'] . '://' . $url_data['host'] . (isset($url_data['port']) ? ':' . $url_data['port'] : '') . str_replace('/index.php', '', $url_data['path']) . $url . $query;
            } else {
                return $link;
            }
        } else {
            return $link;
        }       
    }   
}
?>

------------------ WHERE THE CHANGE -------------------------

The below Line i added in Public Function index() also Public Function rewrite.

else {
this->request->get['route'] = $this->request->get['_route_'];
}

index() function Perform like this

  1. Get the query from htaccss "?route=$1" (Ex: the url look like site.com/shirts)
  2. so the route is shirts
  3. now the function check the "shirts" is found in url_alias table if its found then its make a get varible like index.php?categoryID=Value from url_alias Table.
  4. Or else if there are no record in url_alias table for shirts, then its checks weather it is some other pages like information or manufacturer if its found it make a get variable Example index.php?route=information/information or index.php?route=product/manufacturer/info.
  5. But its not check is it found in Layouts. So i added the Code in else block that set the route into get variable like this index.php?route=<route>
  6. So in index() functions its works fine. Like Same i did in rewrite function.


回答10:

i got this http://www.antropy.co.uk/index.php/blog/one-quick-opencart-seo-tip-to-avoid-a-duplicate-home-page/ worked for me in removing the code for my homepage



回答11:

In file \system\library\response.php add next line at the beginning of the public function output()

if (!defined('HTTP_CATALOG')) $this->output = str_replace(array('index.php?route=common/home', '?route=common/home'), '', $this->output);


回答12:

I created a VQMOD for this. Free download here: http://www.opencart.com/index.php?route=extension/extension/info&extension_id=14683

Works well.



回答13:

To remove index.php?route= from urls I simply recommend to edit .htaccess file.

Just add this:

RewriteCond %{THE_REQUEST} \ /index\.php\?_route_=?([^&\ ]*)
RewriteRule ^ /%1? [L,R]

I encounter no problems whatsoever. Just remember that you need to have RewriteEngine enabled. Look for this line: RewriteEngine On. If not present, past it before above code.