Как я могу решить проблему, когда две категории / продукты имеют один и тот же URL-адрес в Opencart? Или если это модуль, который уже делает это?
Например: категории
Ladies -> Trousers (URL: ladies/trousers) Mens -> Trousers (URL: mens/trousers)
Это разрывает Opencart, потому что у нас есть две подкатегории с URL = брюки?
Я разработал этот vqmod для этого точного сценария
Я знаю, что это поздний ответ, но это глубоко укоренившаяся проблема с архитектурой OpenCarts.
Лично я не являюсь поклонником vQmod, так что вот что (что бы кто-то назвал хаком) решением проблемы, не используя ее.
Я видел много изменений в catalog/controller/common/seo_url.php
которые добавляют пользовательские catalog/controller/common/seo_url.php
. Это исправление совместимо с такими модификациями.
Я также хотел бы добавить, что это далеко не самое сложное решение в мире, но это гарантирует, что подкатегории с дублирующимися строками uro будут работать так, как должны.
Найти в catalog/controller/common/seo_url.php
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] == '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']; } } } }
Добавьте следующую строку в начало индекса метода ()
$this->load->model('catalog/category');
Найдите линию …
foreach ($parts as $part) { $query = $this->db->query("SELECT * FROM " . DB_PREFIX . "url_alias WHERE keyword = '" . $this->db->escape($part) . "'");
И замените следующим
$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]) . "'");
Я решил эту проблему, я сделал файл vqmode xml
см. opencart, дайте тот же результат для ниже URL-адресов
http://mycart/mp3-players/iPod-Classic
http://mycart/mp3-players/some-child/iPod-Classic
http://mycart/some-parent/mp3-players/iPod-Classic
http://mycart/iPod-Classic
это будет трудно сделать seo для этого продукта «iPod-Classic»,
поэтому я пишу скрипт «vqmod» с этим скриптом, вы можете перенаправить пользователя на определенную и правильную страницу
даже пользователь вводит неправильный URL-адрес
т.е.
http://mycart/mp3-players/dddfsdgf/sdf/sdf/iPod-Classic
он автоматически перенаправит его на
http://mycart/mp3-players/iPod-Classic
вам просто нужно загрузить 'controller_common_seo_url.xml' из "box" или
<modification> <id>public function index() add more functions</id> <version>1.0</version> <vqmver>2.1.5</vqmver> <author>http://www.bhardwajabhi.wordpress.com</author> <file name=”catalog/controller/common/seo_url.php”> <operation> <search position=”before”><![CDATA[ public function index() { ]]></search> <add><![CDATA[ public function get_seo_title($id, $type) { $query = $this->db->query("SELECT keyword FROM " . DB_PREFIX . "url_alias WHERE query = '". $type ."=" . (int)$id . "'"); if($query->row) return $query->row['keyword']; else return $id; } public function get_path_level($id) { $query = $this->db->query(“select `level` from ” . DB_PREFIX . “category_path where `category_id` = '”. $id. “' order by level desc LIMIT 1″); return $query->row['level']; } public function get_product_relative($parts, $product_id) { if (isset($this->request->server['HTTPS']) && (($this->request->server['HTTPS'] == 'on') || ($this->request->server['HTTPS'] == '1′))) { $this->data['base'] = $this->config->get('config_ssl'); } else { $this->data['base'] = $this->config->get('config_url'); } $path = $this->get_seo_title($product_id, 'product_id'); $query = $this->db->query(“SELECT category_id FROM ” . DB_PREFIX . “product_to_category WHERE product_id = '” . (int)$product_id . “'”); $i =0; foreach($query->rows as $pro_cat): $i++; $sub_query = $this->db->query(“select `path_id` from ” . DB_PREFIX . “category_path where `category_id` = '”. $pro_cat['category_id']. “' order by level desc”); foreach($sub_query->rows as $pro_sub_cat): $path = $this->get_seo_title($pro_sub_cat['path_id'], 'category_id') . “/” . $path; endforeach; $path1 = '/'. $path; $array1 = explode('/', $path1); $array2 = explode('/', $this->request->get['_route_']); $result = array_diff($array1, $array2); $new_path[$i]['path'] = $path; $new_path[$i]['count'] = count($result); $path = $this->get_seo_title($product_id, 'product_id'); endforeach; $min = PHP_INT_MAX; $max = 0; foreach ($new_path as $i) { $min = min($min, $i['count']); } foreach($new_path as $value): if($value['count']==$min): $final_path = $value['path']; break; endif; endforeach; similar_text($this->request->get['_route_'], $final_path, $percent); if($percent<>100) header ('location:' . $this->data['base'] .”. $final_path); } ]]></add> </operation> </file> <file name=”catalog/controller/common/seo_url.php”> <operation info=”After ABC, add 123″> <search position=”after”><![CDATA[ $this->request->get['product_id'] = $url[1]; ]]></search> <add><![CDATA[ /*Start url redirection*/ $this->get_product_relative($parts, $url[1]); /*End Url Redirection*/ ]]></add> </operation> </file> </modification>
теперь так, когда кто-то попадает на любой товар, тележка покажет страницу, например
http://www.yourSiteUrl/parent-category/child-category/product
примечание: вы должны указывать титул seo для каждой категории, дочерней категории и есть продукт, потому что поиск скрипта для названия seo и если титул seo недоступен, тогда он дает идентификатор, так что предположим, что мы не даем seo-title для дочерней категории и vew его продукт тогда url будет как
http://www.yourSiteurl/parent-category/56/product
вы можете получить более подробную информацию об этом здесь
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']; } } } }
это не сработает, если его категория 3 уровня. Надеюсь, у кого-то будет лучшее решение.
В дополнение к @Ian Brindley вы также должны отредактировать еще 2 файла, чтобы вы могли вводить ключевые слова в панели администратора:
Admin/Controller/Catalog/category.php
Найти эти строки кода в методе validateForm
if (utf8_strlen($this->request->post['keyword']) > 0) { $this->load->model('catalog/url_alias'); $url_alias_info = $this->model_catalog_url_alias->getUrlAlias($this->request->post['keyword']); if ($url_alias_info && isset($this->request->get['category_id']) && $url_alias_info['query'] != 'category_id=' . $this->request->get['category_id']) { $this->error['keyword'] = sprintf($this->language->get('error_keyword')); } if ($url_alias_info && !isset($this->request->get['category_id'])) { $this->error['keyword'] = sprintf($this->language->get('error_keyword')); } if ($this->error && !isset($this->error['warning'])) { $this->error['warning'] = $this->language->get('error_warning'); } }
и изменить их на:
if (utf8_strlen($this->request->post['keyword']) > 0) { $this->load->model('catalog/url_alias'); $url_alias_info = $this->model_catalog_url_alias->getUrlAlias($this->request->post['keyword']); if ($url_alias_info && !isset($this->request->get['category_id'])) { $this->error['keyword'] = sprintf($this->language->get('error_keyword')); } if ($this->error && !isset($this->error['warning'])) { $this->error['warning'] = $this->language->get('error_warning'); } }
Это избавит вас от проверки, если ключевое слово seo является дубликатом. Таким образом, вы можете ввести ключевые слова seo в админпанели вместо phpmyadmin