Сегодня сделаем полезную с точки зрения SEO доработку OpenCart — добавим в административной части возможность самостоятельно определять тег <title>
и тег <h1>
для товаров и категорий, а также выводить их в пользовательской части. Я буду делать это правками в файлах ядра OpenCart для наглядности процесса, хотя крайне рекомендую делать это через vqmod или ocmod. Приступим!
Административная часть
Итак, мы будем исправлять все элементы MVC(L), т.к. у нас и форма редактирования товаров изменится, и в БД будем хранить информацию, языковые переменные будут и конечно Контроллер, который соберет это все вместе. Начнем с языковых переменных. Я советую делать правки в двух языковых версиях – основной (как правило, это russian
или ukrainian
) и «запасной» (english
). Дело в том, что если нет перевода на выбранном в настройках OpenCart языке, движок попытается найти его в english переводе, если и там не будет такой переменной, то уже выведет ошибку. Поэтому подстрахуемся.
Для товаров
Идем в admin/language/russian/catalog/product.php
и добавляем в секции //Entry
после $_['entry_meta_description'] = 'Мета-тег "Описание":';
$_['entry_meta_title'] = 'Тег "Title":'; $_['entry_meta_h1'] = 'Тег "H1":';
Для категорий
Идем в admin/language/russian/catalog/category.php
и добавляем в секции //Entry
после $_['entry_meta_description'] = 'Мета-тег "Описание":';
$_['entry_meta_title'] = 'Тег "Title":'; $_['entry_meta_h1'] = 'Тег "H1":';
Скажу, что такие имена переменных не совсем корректны, т.к. ни <h1>
ни <title>
по сути в HTML мета тегами не являются, это скорее дань сеошникам, т.к. все это они условно называют «мета тегами» в купе с <meta name='description' content='...'>
, как весомые факторы внутренней поисковой оптимизации сайта.
Аналогичные правки делаем с английским переводом товарных переменных admin/language/english/product.php
и категорий admin/language/english/category.php
$_['entry_meta_title'] = 'Tag "Title":'; $_['entry_meta_h1'] = 'Tag "H1":';
На этом мы закончили с языковыми переменными. Перейдем к Модели. Первым делом, добавим в БД новые колонки meta_title
и meta_h1
. Сделаем это с помощью phpMyAdmin и небольшой команды. И тут нужно сделать очередную профессиональную оговорку. Дело в том, что через прямое обращение к БД через внешние средства нельзя предусмотреть различные префиксы для таблиц. В зависимости от вашей версии и редакции OpenCart (ocStore, OpenCart) этот префикс может отличаться от oc_
или вовсе отсутствовать. Обычно это либо oc_
либо префикс отсутствуюет вообще. Однако и в этом случае, если вы не сильны в SQL запросах, приведенный код может не сработать. Узнать какой у вас именно префикс можно в сonfig.php в корне установки OpenCart. За это отвечает строка define('DB_PREFIX', '');
в секции //DB
. Как видите в моем примере там пусто, у вас же может быть define('DB_PREFIX', 'oc_');
или что-то еще. Теперь сам код SQL, который нужно ввести в консоль phpMyAdmin
ALTER TABLE product_description ADD meta_title varchar(255) NOT NULL; ALTER TABLE product_description ADD meta_h1 varchar(255) NOT NULL; ALTER TABLE category_description ADD meta_title varchar(255) NOT NULL; ALTER TABLE category_description ADD meta_h1 varchar(255) NOT NULL
Можно сходить в таблицы и убедиться по структуре category_description
, что все добавилось:
Аналогично и в product_description
:
В принципе можно ограничить максимальное количество знаков в полях согласно рекомендациям Google или Яндекс — 72 знака, для этого в коде запроса к БД заменить varchar(255)
на varchar(72), однако я не советую это делать, если вы используете какие-то массовые изменения на сайте. В этом случае часть значений может просто не записаться. Даже если <title>
будет длиннее 72 знаков, Google или Яндекс его просто обрежут. Это не красиво, но будет давать эффект, в то время как пустое поле в БД как раз никакого SEO эффекта не окажет.
Так же можно воспользоваться функцией в Контроллере. Например, так для admin/controller/catalog/category.php
после public function index() {
добавляем:
$query = $this->db->query("DESC ".DB_PREFIX."category_description meta_title"); if (!$query->num_rows) { $this->db->query("ALTER TABLE `" . DB_PREFIX . "category_description` ADD `meta_title` varchar(255) NOT NULL;"); } $query = $this->db->query("DESC ".DB_PREFIX."category_description meta_h1"); if (!$query->num_rows) { $this->db->query("ALTER TABLE `" . DB_PREFIX . "category_description` ADD `meta_h1` varchar(255) NOT NULL;"); }
Этот метод работы с БД имеет как плюсы так и минусы. Плюсы в том, что у вас нет необходимости нарушать основы паттерна MVC(L) — не делать правок руками в БД, а работь через Контроллер или Модель. Следовательно, можно использовать константы PHP и избежать в т.ч. проблем с различными префиксами в БД.
А минус этого подхода стал причиной появления ocmod (в том числе). В OpenCart 1.5.x нет четко обозначенного метода установки модификаций при которых можно выполнять единоразово какие-то действия в БД, например добавление или изменение полей или структуры. Речь не про модули, которые имеют свои интерфейсы, а именно модификаторы интерфейса уже существующих элементов OpenCart, например административной панели. Единственный лайфхак, который доступен это цикл if, как это реализовано выше. Однако в этом случае мы обречены на постоянное выполнение этого цикла при каждом обращении к фунции, т.е. оптимизацией тут не пахнет.
Теперь можем приступить к редактированию Моделей. Нам нужно изменить блоки в функциях создания и редактирования категорий. Идем в admin/model/catalog/category.php
ищем такие строки в фунции public function addCategory($data)
:
foreach ($data['category_description'] as $language_id => $value) { $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', description = '" . $this->db->escape($value['description']) . "'"); }
Заменяем на:
foreach ($data['category_description'] as $language_id => $value) { $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_h1 = '" . $this->db->escape($value['meta_h1']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', description = '" . $this->db->escape($value['description']) . "'"); }
Такие же правки делаем в функции public function editCategory($category_id, $data)
. Ищем:
foreach ($data['category_description'] as $language_id => $value) { $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', description = '" . $this->db->escape($value['description']) . "'"); }
Заменяем на:
foreach ($data['category_description'] as $language_id => $value) { $this->db->query("INSERT INTO " . DB_PREFIX . "category_description SET category_id = '" . (int)$category_id . "', language_id = '" . (int)$language_id . "', name = '" . $this->db->escape($value['name']) . "', meta_keyword = '" . $this->db->escape($value['meta_keyword']) . "', meta_description = '" . $this->db->escape($value['meta_description']) . "', meta_h1 = '" . $this->db->escape($value['meta_h1']) . "', meta_title = '" . $this->db->escape($value['meta_title']) . "', description = '" . $this->db->escape($value['description']) . "'"); }
Дальше, в коде:
foreach ($query->rows as $result) { $category_description_data[$result['language_id']] = array( 'name' => $result['name'], 'meta_keyword' => $result['meta_keyword'], 'meta_description' => $result['meta_description'], 'description' => $result['description'] ); }
Меняем на:
foreach ($query->rows as $result) { $category_description_data[$result['language_id']] = array( 'name' => $result['name'], 'meta_keyword' => $result['meta_keyword'], 'meta_h1' => $result['meta_h1'], 'meta_title' => $result['meta_title'], 'meta_description' => $result['meta_description'], 'description' => $result['description'] ); }
Все, с Моделью мы разобрались. Приступим к Контроллеру и закончим Представлением.
Идем в admin/controller/catalog/category.php
и вставим там языковые перменные для новых полей Представления после $this->data['entry_meta_description'] = $this->language->get('entry_meta_description');
$this->data['entry_meta_title'] = $this->language->get('entry_meta_title'); $this->data['entry_meta_h1'] = $this->language->get('entry_meta_h1');
Закончили с Контроллером и перейдем к последнему пункту административной части — Представлению, которое отвечает за форму редактирования конкретной категории admin/view/template/catalog/category_form.tpl
Мне нравится, чтобы поля редактирования title и h1 находились сразу под под полем для Названия. Поэтому после этого кода
<tr> <td><span class="required">*</span> <?php echo $entry_name; ?></td> <td><input type="text" name="category_description[<?php echo $language['language_id']; ?>][name]" size="100" value="<?php echo isset($category_description[$language['language_id']]) ? $category_description[$language['language_id']]['name'] : ''; ?>" /> <?php if (isset($error_name[$language['language_id']])) { ?> <span class="error"><?php echo $error_name[$language['language_id']]; ?></span> <?php } ?></td> </tr>
добавляем
<tr> <td><?php echo $entry_meta_title; ?></td> <td><input type="text" name="category_description[<?php echo $language['language_id']; ?>][meta_title]" size="100" value="<?php echo isset($category_description[$language['language_id']]) ? $category_description[$language['language_id']]['meta_title'] : ''?>" /></td> </tr> <tr> <td><?php echo $entry_meta_h1; ?></td> <td><input type="text" name="category_description[<?php echo $language['language_id']; ?>][meta_h1]" size="100" value="<?php echo isset($category_description[$language['language_id']]) ? $category_description[$language['language_id']]['meta_h1'] : ''?>" /></td> </tr>
Давайте посмотрим, что у нас получилось
Если вы все сделали правильно, но так и не увидели результатов труда, почистите системный кеш и кеш vqmod в /vqmod/vqcache
и /system/cache
Во второй части напишем пользовательскую часть.
А для карточки товара достаточно только:
Идем в admin/language/russian/catalog/product.php и добавляем в секции //Entry после $_[‘entry_meta_description’] = ‘Мета-тег «Описание»:’;
$_[‘entry_meta_title’] = ‘Тег «Title»:’;
$_[‘entry_meta_h1’] = ‘Тег «H1»:’;
и создать таблицы в БД
??
Катерина, конечно нет. Все указанные действия практически, на 99% аналогичны для карточки товаров. Следовательно их ВСЕ нужно выполнить, подразумевая замену category на product. В логике OpenCart, то что касается модели и контроллера, категория и товар очень схожи.
Я не ставил за цель написать пошаговую инструкцию, а скорее дать поле для фантазии. Если вы знаете немного PHP и метод аналогии, у вас все получится :)
P.S. Задавайте вопросы, если застрянете.
А подойдет эта инструкция для opencart шаблона GlobeHTM версия 3.0.2.0?
Подойдет инструкция к шаблону Globehtm Opencart 3.0.2.0?
Странно, что поля эти есть в OpenCart 1.5, но их нужно дорабатывать. Хорошо, что в oc 2 проблема решена.
Эти поля по-умолчанию есть только в русской сборке ocStore. В чистом OpenCart их нет ни в какой версии :)
Добрый день!
Спасибо большое за статью.
Подскажите, пожалуйста, как сделать данные манипуляции с помощью OCMOD?
Заранее благодарю!
Подобные модули и с OCMOD есть на opencartforum.com, бесплатно :)
Это модификация для версии движка 1.5?