2015-10-22 130 views
9

我想从我的opencart网店重写我的产品网址。 Opencart本身有一个真正糟糕的seo实现。我已经更新了seo实现,以便能够使用多个类别的相同关键字,请参阅:Opencart duplicate URL keywords 但这只适用于类别。对于我想要的产品,我只需要一个htaccess重写规则。URL重写OpenCart产品SEO

原始URL看起来是这样的:

http://domain.com/index.php?route=product/product&path=25_28_93&product_id=1759

我的URL看起来像这样的时刻:

http://domain.com/In-Stock/Retreaded-Tires/Agricultural?product_id=1759

正如你所看到的类别也变化了。

而且我希望它是这样的:

http://domain.com/In-Stock/Retreaded-Tires/Agricultural/1759/1050-50R32-Mega-X-Bib

然后进行分页(类别内)我有这个网址:

http://domain.com/index.php?route=product/category&path=36_70_67&page=2

我已经做了这个分为:

http://domain.com/Tire-Retreading/Equalizing/&page=2

但我想这是

http://domain.com/Tire-Retreading/Equalizing/2

我htaccess文件是这样的:

Options +FollowSymlinks 
Options -Indexes 
<FilesMatch "(?i)((\.tpl|\.ini|\.log|(?<!robots)\.txt))"> 
Order deny,allow 
Deny from all 
</FilesMatch> 
RewriteEngine On 
RewriteBase/
RewriteRule ^sitemap.xml$ index.php?route=feed/google_sitemap [L] 
RewriteRule ^googlebase.xml$ index.php?route=feed/google_base [L] 
RewriteRule ^download/(.*) /index.php?route=error/not_found [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] 

我seo_url.php文件,该文件是有点改变了这个样子的:

public function index() { 
    $this->load->model('catalog/category'); 
    // 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_']); 

     // remove any empty arrays from trailing 
     if (utf8_strlen(end($parts)) == 0) { 
      array_pop($parts); 
     } 

     $categories = array(); 

     for ($i = 0; $i < count($parts); $i++) { 
      $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($parts[$i]) . "'"); 

      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') { 
        $categories[$i] = $this->model_catalog_category->getCategory($url[1]); 

        if (!isset($this->request->get['path'])) { 
         $this->request->get['path'] = $categories[$i]['category_id']; 
        } else { 
         foreach ($query->rows as $row) { 
          $url = explode('=', $row['query']); 
          $category_id = $url[1]; 

          $category = $this->model_catalog_category->getCategory($category_id); 

          if ($category['parent_id'] == $categories[$i - 1]['category_id']) { 
           $this->request->get['path'] .= '_' . $category['category_id']; 
          } 
         } 
        } 
       } 

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

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

       if ($query->row['query'] && $url[0] != 'information_id' && $url[0] != 'manufacturer_id' && $url[0] != 'category_id' && $url[0] != 'product_id') { 
        $this->request->get['route'] = $query->row['query']; 
       } 

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

       break; 
      } 
     } 

     if (!isset($this->request->get['route'])) { 
      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 new Action($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 && $query->row['keyword']) { 
        $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 && $query->row['keyword']) { 
         $url .= '/' . $query->row['keyword']; 
        } else { 
         $url = ''; 

         break; 
        } 
       } 

       unset($data[$key]); 
      } else { 
       $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE `query` = '" .$data['route'] . "'"); 

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

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

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

     $query = ''; 

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

      if ($query) { 
       $query = '?' . str_replace('&', '&amp;', 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; 
    } 
} 

分页代码如下:

class Pagination { 
    public $total = 0; 
    public $page = 1; 
    public $limit = 20; 
    public $num_links = 8; 
    public $url = ''; 
    public $text_first = '|&lt;'; 
    public $text_last = '&gt;|'; 
    public $text_next = '&gt;'; 
    public $text_prev = '&lt;'; 

    public function render() { 
     $total = $this->total; 

     if ($this->page < 1) { 
      $page = 1; 
     } else { 
      $page = $this->page; 
     } 

     if (!(int)$this->limit) { 
      $limit = 10; 
     } else { 
      $limit = $this->limit; 
     } 

     $num_links = $this->num_links; 
     $num_pages = ceil($total/$limit); 

     $this->url = str_replace('%7Bpage%7D', '{page}', $this->url); 

     $output = '<ul class="pagination">'; 

     if ($page > 1) { 
      $output .= '<li><a href="' . str_replace('{page}', 1, $this->url) . '">' . $this->text_first . '</a></li>'; 
      $output .= '<li><a href="' . str_replace('{page}', $page - 1, $this->url) . '">' . $this->text_prev . '</a></li>'; 
     } 

     if ($num_pages > 1) { 
      if ($num_pages <= $num_links) { 
       $start = 1; 
       $end = $num_pages; 
      } else { 
       $start = $page - floor($num_links/2); 
       $end = $page + floor($num_links/2); 

       if ($start < 1) { 
        $end += abs($start) + 1; 
        $start = 1; 
       } 

       if ($end > $num_pages) { 
        $start -= ($end - $num_pages); 
        $end = $num_pages; 
       } 
      } 

      for ($i = $start; $i <= $end; $i++) { 
       if ($page == $i) { 
        $output .= '<li class="active"><span>' . $i . '</span></li>'; 
       } else { 
        $output .= '<li><a href="' . str_replace('{page}', $i, $this->url) . '">' . $i . '</a></li>'; 
       } 
      } 
     } 

     if ($page < $num_pages) { 
      $output .= '<li><a href="' . str_replace('{page}', $page + 1, $this->url) . '">' . $this->text_next . '</a></li>'; 
      $output .= '<li><a href="' . str_replace('{page}', $num_pages, $this->url) . '">' . $this->text_last . '</a></li>'; 
     } 

     $output .= '</ul>'; 

     if ($num_pages > 1) { 
      return $output; 
     } else { 
      return ''; 
     } 
    } 
} 

编辑:

我的网页全部被重定向到http://domain.com/index.php 从那里,它决定哪个目录/文件从路由参数使用。 因此route=product/product告诉去目录产品中的product.php。目录产品还包含导致路由的categories.phproute=product/category

字符串中的Path变量表示类别的ID。在我的示例中,25代表In-Stock25_28代表In-Stock/Retreaded-Tires等。

product_id变量代表产品的相应ID。

页面变量代表分页并用于类别内的产品列表中。此列表可以具有可变长度,因为它可以计算某个类别中有多少产品以及他应该在1页上显示多少个产品。 所以,如果原始URL具有&page=2与路线route=product/category应该作出这样的网址:http://domain.com/Tire-Retreading/Equalizing/2

+2

其中是重写方法,它必须位于此控制器中。 – mcklayin

+0

重写方法添加了我的错误,我离开了那个方法。 – Baklap4

+0

你能否澄清一下你的意思是'什么更经常使用,我应该使用?' - 在句子结尾处似乎缺少一个词,并且尚不清楚您尝试在哪个选项之间作出决定。我不熟悉Opencart,但知道我的方式.htaccess。但是,从您提供的URL中很难确定哪些部分是哪些部分(不经过您的所有代码)。你想要的URL如何分解成不同的元素? (也就是说,原始“丑陋”网址中的路线,产品,路径,类别等转化为所需的“干净”网址中的内容)?谢谢。 – Kay

回答

2

我仍然觉得增加的解释令人困惑,这听起来像你对我不太知道如何URL重写工作,所以我将尝试解释一些URL重写基础

你可以用URL重写做的是翻译“漂亮”的网址段(网址显示给用户)实际,长,“非相当”的URL段(其中使用变量来服务某些内容)。你可以通过使用正则表达式来匹配漂亮的段,然后给你的php变量提供预定义的值或匹配的值。

因此,你首先要做的是找出你漂亮的网址应该如何看起来,以及他们的个体细分如何转化为你的变量。 (虽然你当然也可以使用任意数量的新变量,其值可以再转换并分配到已有的或预先定义的PHP脚本变量。)

你给了这个例子: http://example.com/Tire-Retreading/Equalizing/2

此网址似乎是由的要转化为变量三个部分:

  • Tire-Retreading(可变route
  • Equalizing(可变path
  • 2(可变page

你必须建立自己的正则表达式,基于所有可能的方式将各段可以被拼写,包括允许任何特殊字符等你的段匹配一旦完成,您可以使用反向引用将匹配的值传递给变量(或者您可以定义自己的值以供变量使用)。

使用反向引用,你可能使用此:

RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)$ index.php?route=$1&path=$2&page=$3 [NC,L] 

你必须把个人正则表达式段匹配(如[A-Za-z-]+)圆括号能够结果分配给你的php在$1形式,$2

取决于用户是否也应该被允许浏览你的产品/类别或路径“概览”页面或不变量,你可能要开始你从最小的可能“改写漂亮'的URL到最长的一个。

E.g.

RewriteRule ^([A-Za-z-]+)$ $1/ [NC,R] 
RewriteRule ^([A-Za-z-]+)/$ index.php?route=$1 [NC,L] 
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)$ $1/$2/ [NC,R] 
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/$ index.php?route=$1&path=$2 [NC,L] 
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)$ $1/$2/$3/ [NC,R] 
RewriteRule ^([A-Za-z-]+)/([A-Za-z-]+)/([0-9]+)/$ index.php?route=$1&path=$2&page=$3 [NC,L] 

重写域本身在所有'路径'重写之前。

您还需要弄清楚哪些标记 - 最后的方括号中的部分 - 您需要使用,这意味着您需要更详细地阅读URL rewriting。在上面的例子中,用户输入的所有URL都不以斜线结尾,它们会自动重定向到同一个URL,但带有斜杠。所以,http://example.com/blah会重定向到http://example.com/blah/

根据您所提供的信息,你就会有网址开始有两个可能的领域之一:

http://example.com/In-Stock/... 

http://example.com/Product-or-Category/.... 

所以,你必须格外小心,这两个不要混淆。如果In-Stock已被集中到自己的变量中,并且总是拼写完全一样,那么您可能希望使第一条规则处理该问题,并在稍后使用RegEx来匹配产品/类别(所有重写规则均按时间顺序处理,一个接一个地)。

我希望有帮助。