От автора: в этом курсе мы узнаем все о пользовательских SEO-friendly ссылках в OpenCart. Крайне важный аспект при разработке новых модулей, который также влияет на рейтинг в поисковой выдаче. Мы будем работать с последней версией OpenCart. Установите также последнюю версию, чтобы вы могли следовать по нашему коду.
Коротко о нашей задаче
Я составил список шагов, которые необходимо выполнить для создания пользовательских URL’ов в OpenCart:
Сперва необходимо понять принцип работы ссылок в ядре.
Потом мы разберем все нужные изменения в ядре.
Поверхностно изучим SQL запросы для вставки пользовательских URL.
А также узнаем, как работать со встроенной функцией перезаписи.
Примерно этим вы сейчас и займемся. Перейдем к первой теме.
Сопоставление URL в базе данных
Первым делом необходимо понять, как SEO URL’ы работают в ядре OpenCart. В phpMyAdmin откройте MySQL таблицу url_alias, вы увидите что-то похожее.
1 2 3 4 |
product_id=48 ipod-classic category_id=20 desktops manufacturer_id=8 apple information_id=6 delivery |
Внимание нужно обратить на две колонки. Первая query, в ней хранится ссылка, и вторая колонка keyword, в которой хранятся SEO ключевые слова для ссылки.
В таблице есть ссылки на различные вещи: товар, категория, информация и производитель. При каждом сохранении новых данных на стороне back-end в OpenCart ассоциирующаяся с этим информация попадает в эту таблицу.
На стороне front-end’а, когда пользователь запрашивает определенный URL, OpenCart находит соответствующие ему «кирпичики» из таблицы url_alias. Таким образом составные части в целом представляют собой SEO дружелюбную ссылку. Откройте файл catalog/controller/common/seo_url.php, давайте разберем код метода index.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
public function index() { // Добавляем слово rewrite к классу ссылки if ($this->config->get('config_seo_url')) { $this->url->addRewrite($this); } // Декодируем URL if (isset($this->request->get['_route_'])) { $parts = explode('/', $this->request->get['_route_']); // удаляем пустые массивы if (utf8_strlen(end($parts)) == 0) { array_pop($parts); } 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]; } 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']); } } } |
Мы вытягиваем ассоциативные записи из таблицы url_alias. После этого парсится параметр запроса, и возвращается внутренняя ссылка.
Это и есть базовый принцип работы. К сожалению, это работает только для обычных ссылок – для пользовательских URL’ов нам придется переписать код ядра. Об этом и будет наша следующая секция.
Изменения в файлах ядра
Откройте файл catalog/controller/common/seo_url.php и замените метод rewrite на код ниже.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
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 && $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']; } else { $url = ''; break; } } // НАШ КОД } } 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('&', '&', 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; } } |
Метод rewrite используется для конвертации внутренних ссылок в SEO дружелюбные ссылки, но он работает только для внутренних ссылок. Поэтому для работы с пользовательскими модулями нам придется добавить свой код. В нашем методе rewrite в последнем условии мы добавили else, в котором прописан код для нашего кастомного модуля. Мы еще не добавили кастомные ссылки, этим и займемся в следующей части.
Для простоты мы редактировали файл ядра напрямую. На самом деле необходимо работать через OCMOD, чтобы не затронуть код ядра.
Добавляем ключевые слова MySQL
В этой части мы добавим SEO дружелюбные ссылки в наш модуль. И опять для простоты мы пишем на чистом SQL – сделать то же самое можно с помощью скриптов установки модуля.
1 |
INSERT INTO `url_alias` (`query`, `keyword`) VALUES ('custom/custom', 'custom-rewrite'); |
Запустите код выше в базе данных OpenCart. В последней секции мы посмотрим, как использовать хелпер функцию для создания SEO дружелюбных ссылок.
Как это работает
Создайте новый файл catalog/controller/custom/custom.php с кодом:
1 2 3 4 5 6 7 |
<?php class ControllerCustomCustom extends Controller { function index() { $data['customlink'] = $this->url->link('custom/custom'); $this->response->setOutput('<a href="'.$data['customlink'].'">Custom URL Rewrite Link</a>'); } } |
На стороне front-end’а откройте ссылку //www.yourstore.com/index.php?route=custom/custom.
По ссылке вы увидите просто белый экран и ссылку. Посмотрите на эту ссылку, она теперь SEO дружелюбна! Если кликнуть на нее, загрузится та же самая страница, так как мы добавили ссылку на нее в таблицу url_alias. Это была простая демонстрация данной концепции. Ее можно расширить и создать модель для вставки SEO дружелюбных ссылок для своего модуля.
Заключение
Сегодня мы разобрали важную тему в OpenCart – пользовательские SEO дружелюбные ссылки. Для полной ясности мы разобрали самый простой способ. Надеюсь, он был вам полезен.
Автор: Sajal Soni
Источник: //code.tutsplus.com/
Редакция: Команда webformyself.