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

Posted

技术标签:

【中文标题】如何在 OpenCart 中创建自定义的 SEO 友好 URL?【英文标题】:How can I create custom SEO-friendly URLs in OpenCart? 【发布时间】:2011-11-26 13:01:28 【问题描述】:

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

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

【问题讨论】:

试试这个 vqmod,我用第二个答案代码做了一些编辑来修复一个小错误:pastebin.com/yAsfxqTm 【参考方案1】:

这是一个免费的扩展程序,它添加了自定义 SEO URL,并允许您管理多语言 URL、404、导出/导入和批量编辑。

SEO Module URL

嘿,在您点击之前,请检查扩展名。这是我的扩展,我知道它编码正确,它完全按照用户的要求做,而且更多,而且它是免费的。

我真的希望它对某人有所帮助。

【讨论】:

【参考方案2】:

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

This one 可以在 OpenCart 1.5 和 OpenCart 2 上运行,而且看起来非常可定制。但是,它不支持自定义硬编码 URL 部分,例如“checkout/cart”或“account/wishlist”。

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

例如"checkout/cart" 将变成英语的 "cart",法语的 "panier" 等等。

【讨论】:

【参考方案3】:

我使用的是 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 */

?>

【讨论】:

我将此代码添加到我的控制器/公共文件夹的 seo_url.php 文件中。我正在运行 1.5.5.1。我希望在 url 或产品中看到该类别和子类别以及项目本身 这太棒了,不知道为什么他们默认不包含这个。有点可笑。 这很棒,但有一些问题。因为你重写了url,你可能会遇到没有查询字符串参数的情况,那么你需要在使用它之前检查$url_info['query']是否存在,那么你还需要检查$data['route']是否存在。但是我仍然对某些链接有问题,例如从购物车链接中删除...我制作了此 pastebin.com/yAsfxqTm 的 vqmod 版本 以上代码已成功将网站转换为 SEO 友好,但事件不起作用我正在处理此示例:目录/控制器/帐户/帐户/之后【参考方案4】:

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>

【讨论】:

这对我有用 - 在手动将新的 seo 重写添加到我的数据库 _url_aliases 之后。这比修改文件本身更容易。我正在使用 2.3.0.2【参考方案5】:

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

然后将这个Opencart forum thread中可用的xml文件上传到vqmod/xml/文件夹中。

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

【讨论】:

【参考方案6】:

把它放在 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;

【讨论】:

【参考方案7】:

OpenCart SEO for OpenCart 1.5.X 免费 :)

您可以随意使用。类别名称/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 */

?>

【讨论】:

重复,信息较少。【参考方案8】:

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


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]);
+                        
+                   
                
            

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

第二个扩展了rewrite() 函数以在url_alias 表中查找所有 路由,而不仅仅是产品、制造商和信息页面的路由。


向数据库添加条目:

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

就是这样。 http://example.com/cart 应该返回与 http://example.com/index.php?route=checkout/cart 相同的内容,OpenCart 应该识别 $this-&gt;url-&gt;link('checkout/cart'); 并返回指向漂亮 URL http://example.com/cart 的链接

【讨论】:

这很好用,非常感谢。只是制造业指数有缺陷。 事实证明...这是硬编码在 /template/product/manufacturer_list.tpl @ line 12 你在哪里添加这个? 能否粘贴您的整个控制器文件?这比试图理解 ^^^ 行号和其他内容要容易得多。它看起来是一种完美的方法,如果您能粘贴整个 ControllerCommonSeoUrl 类文件,我将不胜感激。谢谢! 我正在使用 oc 2.0.2.0。我尝试了您的代码以及在数据库中添加的条目,但它不起作用。检查pastebin.com/DVWH7sby。方法对吗?

以上是关于如何在 OpenCart 中创建自定义的 SEO 友好 URL?的主要内容,如果未能解决你的问题,请参考以下文章

Opencart 版本 1.5.1.3 安装在 IIS 7 上。如何获得 SEO 友好的 URL?

如何在 laravel 中创建自定义关系?

如何在 QML 中创建自定义对象?

如何在 Facebook SDK 中创建自定义分享按钮

如何在 React Native 中创建自定义日历?

opencart seo url重写