php 如何在 OpenCart 中创建自定义的 SEO 友好 URL?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7578055/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-26 02:59:08  来源:igfitidea点击:

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

php.htaccessseoopencart

提问by nachito

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

如何在 OpenCart 中自定义系统 URL?例如,我希望http://example.com/index.php?route=checkout/cart显示为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.

我知道 OpenCart 为产品、类别、制造商和信息页面提供了 SEO URL,但看起来并没有内置任何其他内容(至少在 1.5.0 版之前)。

回答by nachito

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.

事实证明,这可以通过对单个文件进行相对简单的更改来完成。没有 .htaccess 重写规则,只需修补 catalog/controller/common/seo_url.php 文件并将您漂亮的 URL 添加到现有的数据库表中。



The patch to seo_url.php:

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_aliastable for anykeyword matching $this->request->get['_route_'].

需要进行两次编辑。第一个扩展index()函数以在url_alias表中查找任何关键字匹配$this->request->get['_route_']

The second extends the rewrite()function to look in the url_aliastable for allroutes, not just those for products, manufacturers, and information pages.

第二个扩展了rewrite()url_alias表格中查找所有路线的功能,而不仅仅是产品、制造商和信息页面的路线。



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/cartshould return the same thing that http://example.com/index.php?route=checkout/cartdoes, and OpenCart should recognize $this->url->link('checkout/cart');and return a link to the pretty URL http://example.com/cart

就是这样。http://example.com/cart应该返回与http://example.com/index.php?route=checkout/cart相同的东西,OpenCart 应该识别$this->url->link('checkout/cart');并返回一个链接到漂亮的 URL http:// example.com/cart

回答by asif03

I'm using Opencart version 1.5.5.1 and this is the exact code that worked for me:

我使用的是 Opencart 版本 1.5.5.1,这是对我有用的确切代码:

<?php 
class ControllerCommonSeoUrl extends Controller {
    /* SEO Custom URL */
    private $url_list = array (
        'common/home'       => '',
        'checkout/cart'     => 'cart',
        'account/register'  => 'register',
                    'account/wishlist'  => 'wishlist',
                    'checkout/checkout' => 'checkout',
                    'account/login'     => 'login',
                    'product/special'   => 'special',
                    'affiliate/account' => 'affiliate',
                    'checkout/voucher'  => 'voucher',
                    'product/manufacturer' => 'brand',
                    'account/newsletter'   => 'newsletter',
                    'account/order'        => 'order',
                    'account/account'      => 'account',
                    'information/contact'  => 'contact',
                    'account/return/insert' => 'return',
                    'information/sitemap'   => 'sitemap',
        );
    /* SEO Custom URL */

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';   
            }
        }
                    /* SEO Custom URL */
                    if ( $_s = $this->setURL($this->request->get['_route_']) ) {
                            $this->request->get['route'] = $_s;
                    }/* SEO Custom URL */

        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';
        }

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

public function rewrite($link) {
    $url_info = parse_url(str_replace('&amp;', '&', $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]);
            }
                                    /* SEO Custom URL */
                                    if( $_u = $this->getURL($data['route']) ){
                                        $url .= $_u;
                                        unset($data[$key]);
                                    }/* SEO Custom URL */       


        }
    }

    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 {
        return $link;
    }
}   
    /* SEO Custom URL */
    public function getURL($route) {
            if( count($this->url_list) > 0) {
                 foreach ($this->url_list as $key => $value) {
                    if($route == $key) {
                        return '/'.$value;
                    }
                 }
            }
            return false;
    }
    public function setURL($_route) {
            if( count($this->url_list) > 0 ){
                 foreach ($this->url_list as $key => $value) {
                    if($_route == $value) {
                        return $key;
                    }
                 }
            }
            return false;
    }/* SEO Custom URL */
}
?>

回答by integris

A simple "no code" method is to install vQmod. Instructions here: vQmod install wiki

一个简单的“无代码”方法是安装 vQmod。此处的说明: vQmod 安装 wiki

And then upload the xml file available in this Opencart forum threadto the vqmod/xml/ folder.

然后将此Opencart 论坛主题中可用的 xml 文件上传到 vqmod/xml/ 文件夹。

The xml contains a relatively easy to read script that maps the urls similar to the two answers above, but without modifying core files. So site updates will not kill it.

该 xml 包含一个相对易于阅读的脚本,该脚本映射类似于上述两个答案的 url,但不修改核心文件。所以网站更新不会杀死它。

回答by daiver

vQmod xml file

vQmod xml 文件

<modification>
<id>Seo All Alias</id>
<version>1.0</version>
<vqmver>2.1.7</vqmver>
<author>noname</author>
<file name="catalog/controller/common/seo_url.php"> 
    <operation>
        <search position="after" offset="2"><![CDATA[
            $this->request->get['route'] = 'information/information';
        ]]></search>
        <add><![CDATA[
        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'];
            }
        }
        ]]></add>
    </operation>

    <operation>
        <search position="after" offset="1" index="2"><![CDATA[
            unset($data[$key]);
        ]]></search>
        <add><![CDATA[
                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]);
                    }
                }
        ]]></add>
    </operation>

</file>

回答by Daniel Baldwin

Put this near the top of your index.php file. It was the only solution that worked for me.

把它放在 index.php 文件的顶部附近。这是唯一对我有用的解决方案。

switch($_SERVER["REQUEST_URI"])
{
    case '/old-url': $three01 = "/new-url"; break;
}

if($three01)
{
    header("HTTP/1.1 301 Moved Permanently"); header("Location: ".$three01); exit;
}

回答by pckedi

OpenCart SEO for OpenCart 1.5.X free :)

OpenCart 1.5.X 免费的 OpenCart SEO :)

You can use as you wish. Category Name / ID / ID for quicker SEO resolving

您可以随意使用。类别名称/ID/ID 用于更快的 SEO 解析

<?php
class ControllerCommonSeoUrl extends Controller {
        /* SEO Custom URL */
        private $url_list = array (
            'common/home'       => 'home',
            'checkout/cart'     => 'cart',
            'account/register'  => 'register',
                        'account/wishlist'  => 'wishlist',
                        'checkout/checkout' => 'checkout',
                        'account/login'     => 'login',
                        'product/special'   => 'special',
                        'affiliate/account' => 'affiliate',
                        'checkout/voucher'  => 'voucher',
                        'product/manufacturer' => 'brand',
                        'account/newsletter'   => 'newsletter',
                        'account/order'        => 'order',
                        'account/account'      => 'account',
                        'information/contact'  => 'contact',
                        'account/return/insert' => 'return/insert',
                        'information/sitemap'   => 'sitemap',
            );
        /* SEO Custom URL */

        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_']);

                                                if ( count($parts) > 1 ) {
                                                        if ($parts[1] == 'category'){
                                                                $this->request->get['path'] = $parts[2];
                                                                for ( $i = 3 ; $i < count($parts); $i++) {      
                                                                        $this->request->get['path'] .= '_' . $parts[$i];
                                                                }
                                                        }elseif( $parts[1] == 'item' ) {
                                                                $this->request->get['product_id'] = $parts[2];
                                                        }
                                                }
                        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';       
                                }
                        }
                        /* SEO Custom URL */
                        if ( $_s = $this->setURL($this->request->get['_route_']) ) {
                                $this->request->get['route'] = $_s;
                        }/* SEO Custom URL */

                        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/product';
                        } elseif (isset($this->request->get['information_id'])) {
                                $this->request->get['route'] = 'information/information';
                        }

                        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/manufacturer/product' || $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 == 'product_id' ) {

                                                $url = '/shop/item/'.$value;
                                                unset($data[$key]);

                                              }elseif ($key == 'path') {

                                                $categories = explode('_', $value);
                                                $url = '/shop/category';
                                                foreach ($categories as $category) {
                                                        $url .= '/'.$category;
                                                }
                                                unset($data[$key]);

                                        }// 
                                        /* SEO Custom URL */
                                        if( $_u = $this->getURL($data['route']) ){
                                            $url .= $_u;
                                            unset($data[$key]);
                                        }/* SEO Custom URL */        


                                }
                        }

                        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;
                }               
        }

        /* SEO Custom URL */
        public function getURL($route) {
                if( count($this->url_list) > 0) {
                     foreach ($this->url_list as $key => $value) {
                        if($route == $key) {
                            return '/'.$value;
                        }
                     }
                }
                return false;
        }
        public function setURL($_route) {
                if( count($this->url_list) > 0 ){
                     foreach ($this->url_list as $key => $value) {
                        if($_route == $value) {
                            return $key;
                        }
                     }
                }
                return false;
        }/* SEO Custom URL */
}
?>

回答by Skippy le Grand Gourou

Depending on the level of customization you need, there are a few extensions available, including free ones.

根据您需要的自定义级别,有一些扩展可用,包括免费的。

This oneworks both on OpenCart 1.5 and OpenCart 2 and seems quite customizable. However it does not support customization of hardcoded URL parts like "checkout/cart" or "account/wishlist".

这个适用于 OpenCart 1.5 和 OpenCart 2,并且似乎非常可定制。但是,它不支持自定义硬编码 URL 部分,例如“结帐/购物车”或“帐户/愿望清单”。

Hereis a vQmod for OpenCart 2.0 (might work with 1.5, not tested) which applies to the forementioned extension and allows to change these hardcoded strings into whatever you want, and support multilanguage websites.

是 OpenCart 2.0 的 vQmod(可能适用于 1.5,未测试),适用于上述扩展并允许将这些硬编码字符串更改为您想要的任何内容,并支持多语言网站。

E.g. "checkout/cart" will become "cart" for English, "panier" for French, etc.

例如,“checkout/cart”将成为英语的“cart”,法语的“panier”等。

回答by Dmitriy Zhuk

here is a free Extension that adds custom SEO URLs, as well as lets you manage multi-langauge URLs, 404s, export/import, and bulk edit.

这是一个免费的扩展,可以添加自定义 SEO URL,还可以让您管理多语言 URL、404、导出/导入和批量编辑。

SEO Module URL

SEO 模块 URL

Hey, before you click down, check the extension. It is my extension, I know that it is coded properly and it does exactly what the user asks for and much more and it is FREE.

嘿,在你点击之前,检查扩展。这是我的扩展程序,我知道它的编码正确并且完全符合用户的要求,而且它是免费的。

I really hope it helps someone.

我真的希望它可以帮助某人。