Создание модуля PrestaShop: инструкция
Модули — это идеальный способ выразить свой талант и воображение, а также проявить себя, поскольку они дают много возможностей.
Привет, ребята!
Учусь разрабатывать модули Престашоп. И хочу поделиться с вами накопленными знаниями и материалами. Кстати, огромная благодарность всем авторам, которые уделяли свое время написанию обучающих статей и публикации советов по разработке! Сегодня в блоге веб-мастерской MAKE-WEBSITE.ru проведем общий анализ структуры модуля PrestaShop и разработаем простой модуль, выводящий на сайт интернет-магазина небольшой текстовый блок. Пусть это будет своеобразным конспектом по написанию модуля. Но прежде чем приступим к разбору модуля и его кода, давайте вначале рассмотрим несколько понятий, с которыми сталкивается разработчик на Престашоп. Поговорим про хуки, smarty и работу с базой данных.
Про хуки
Хуки – это способ связать ваш код с некоторыми конкретными событиями PrestaShop. Есть 2 типа хуков:
- Display (дисплей). Эти хуки приводят к тому, что что-то отображается либо в фронт-офисе, либо в бэк-офисе. Другими словами хуки используются для вывода результатов работы модуля в определенном месте страницы. Это могут быть: номер телефона в шапке сайта или блок «Популярные товары» в левой колонке.
Примеры: displayHeader, displayFooter, displayLeftColumn. - Action (действие). Эти хуки запускаются конкретными событиями, которые происходят в PrestaShop. Например, фиксировать заход посетителя на главную страницу.
Примеры: actionObjectProductAddAfter, actionObjectProductDeleteBefore, actionCarrierUpdate.
Примеры хуков типа Display:
Использование хуков в модуле
Для этого в классе модуля создается публичный метод, начинающийся с “hook” и содержащий имя хука. Например, для вывода информации в левом столбце код будет выглядеть так:
public function hookDisplayNameOfHook($params)
{
// Код хука.
}
В метод передается только одна переменная, содержащая массив параметров, отправляемых хуку. Чтобы метод вызывался в хуке, необходимо зарегистрировать его, используя registerHook(). Регистрация обычно делается во время установки модуля.
public function install()
{
return parent::install() && $this->registerHook('NameOfHook');
}
При удалении модуля PrestaShop самостоятельно удалит эту регистрацию.
Полезные ссылки по теме хуков:
Документация:
https://devdocs.prestashop.com/1.7/modules/concepts/hooks/
Механизм "хуков"
http://prestalab.ru/wiki/mexanizm-xukov?s%5b%5d=хуки
Классная статья про Хуки на английском:
https://belvg.com/blog/hooks-in-prestashop.html
Smarty шаблоны .tpl
Шаблонизатор Smarty – это обработчик шаблонов PHP. Это один из инструментов, который позволяет отделить визуальную часть от серверной части сайта.
Ниже приведен пример файла шаблона news.tpl. Фактически это обычный html с вставками переменных и конструкций циклов. Все переменные заключены в фигурные скобки.
<html>
{foreach from=$news item=item}
Заголовок: {$item.title}Текст новости:
{item.description}<a href="index.php?id={$item.id}" mce_href="index.php?id={$item.id}">Подробнее...</a>
{/foreach}</html>
Этот пример выводит 10 извлечённых из базы данных новостей.
Почитать о Smarty:
Руководство по Smarty
https://www.smarty.net/docsv2/ru/
How to Use Smarty Template Engine in PrestaShop 1.7
https://belvg.com/blog/smarty-template-engine-in-prestashop-1-7-basics-examples-functions.html
Configuration: работа без создания таблицы в базе данных
Данные могут быть сохранены в БД магазина без создания отдельной таблицы для конкретного модуля. В этом случае используется таблица ps_configuration. Таблица Конфигурации содержит список свойств key => value (s), к которым можно обращаться из любого места, в том числе в модуле.
Класс Configuration – это интерфейс, позволяющий каждому разработчику модуля получать или хранить данные в таблице конфигурации.
Методы
- Configuration::get('myVariable'): извлекает определенное значение из базы данных.
- Configuration::getMultiple(array('myFirstVariable', 'mySecondVariable', 'myThirdVariable')): извлекает несколько значений из базы данных и возвращает массив PHP.
- Configuration::updateValue('myVariable', $value): обновляет существующую переменную базы данных с новым значением. Если переменная еще не существует, она создает ее с этим значением.
- Configuration::deleteByName('myVariable'): удаляет переменную базы данных.
Получение внешних значений из таблицы данных ps_configuration
Вы не ограничены своими собственными переменными. PrestaShop сохраняет все свои собственные настройки конфигурации в таблице ps_configuration. Есть буквально сотни настроек, и вы можете получить к ним доступ так же легко, как и доступ к своим собственным. Покопайтесь в этой таблице, чтобы обнаружить множество других настроек! В сегодняшнем уроке вдобавок к переменным нашего модуля мы воспользуемся значением BLOCKCONTACTINFOS_PHONE.
Статья в Документации:
https://devdocs.prestashop.com/1.7/modules/concepts/configuration/
Что такое модуль PrestaShop?
Модули представляют собой небольшие программы, которые используют функциональность движка, меняя или расширяя ее. С помощью модулей легко можно настроить любой требующийся функционал и преобразить внешний вид сайта.
Итак, модули предназначены для изменения отображаемого контента или реакции на события. Они выполняют множество задач: пакетное обновление, импорт, экспорт, взаимодействуют с другими программами и многое другое.
Структура папки модуля
На рисунке представлено примерное содержимое модуля. Каких-то папок может не быть, все зависит от конкретной ситуации. Как видим, модуль включает в себя:
- controllers – папка содержит сontroller файлы.
- translations – папка для файлов перевода.
- upgrade – папка для файлов обновления.
- views– папка, содержащая файлы шаблонов .tpl:
- /templates/admin/ – отображение чего-либо в бэк-офисе
- /templates/hook/ – отображение чего-либо в фронт-офисе
- config.xml – файл конфигурации кэша. Если он еще не существует, этот файл автоматически генерируется PrestaShop, когда модуль будет установлен впервые.
- my_module.php – основной PHP файл.
- index.php – индексный файл.
- logo.png – файл логотипа, представляющего этот модуль в бэк-офисе.
Кроме того модуль может содержать следующие папки:
- classes
- config
- controllers
- override
- src
- themes
Подробнее об этом:
https://devdocs.prestashop.com/1.7/modules/creation/module-file-structure/
Основной PHP файл
Имя файла
Имя должно являться названием класса модуля в нижнем регистре. Например: mws_contentbox.
Варианты конструкций:
- block + название
Например: blockreassurance, blockcontactinfos. - аббревиатура автора модуля + нижнее подчеркивание + название
Напимер: ps_contactinfo (prestashop_contactinfo), mws_contentbox (make-website_contentbox – наш сегодняшний модуль, разработанный в веб-мастерской MAKE-WEBSITE.ru).
Основной PHP файл должен иметь то же имя, что и корневая папка модуля. Так же назовите файл шаблона вывода модуля в фронт-офис. В нашем случае: mws_contentbox\views\templates\hook\mws_contentbox.tpl.
Mws_contentbox – модуль сегодняшнего урока
В этом туториале мы создадим модуль, который выводит на сайт текстовый блок с телефоном, временем работы и каким-нибудь сообщением для покупателей.
Главный файл отвечает за инсталляцию модуля, настройку и привязку к системе посредством хуков. Сущность модуля в PrestaShop реализуется классом, наследованным от системного класса Module. В нашем случае это class Mws_contentbox.
Код основного PHP файла модуля mws_contentbox
<?php
/**
* 2007-2019 PrestaShop
*
* NOTICE OF LICENSE
*
* This source file is subject to the Academic Free License (AFL 3.0)
* that is bundled with this package in the file LICENSE.txt.
* It is also available through the world-wide-web at this URL:
* http://opensource.org/licenses/afl-3.0.php
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to license@prestashop.com so we can send you a copy immediately.
*
* DISCLAIMER
*
* Do not edit or add to this file if you wish to upgrade PrestaShop to newer
* versions in the future. If you wish to customize PrestaShop for your
* needs please refer to http://www.prestashop.com for more information.
*
* @author PrestaShop SA <contact@prestashop.com
* @copyright 2007-2019 PrestaShop SA
* @license http://opensource.org/licenses/afl-3.0.php Academic Free License (AFL 3.0)
* International Registered Trademark & Property of PrestaShop SA
*/
if (!defined('_PS_VERSION_')) {
exit;
}
class Mws_contentbox extends Module
{
protected $config_form = false;
public function __construct()
{
$this->name = 'mws_contentbox';
$this->tab = 'front_office_features';
$this->version = '1.0.0';
$this->author = 'make-website.ru';
$this->need_instance = 1;
/**
* Set $this->bootstrap to true if your module is compliant with bootstrap (PrestaShop 1.6)
*/
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Content box');
$this->description = $this->l('Place your content everywhere!');
$this->confirmUninstall = $this->l('Are you sure you want to uninstall?');
$this->ps_versions_compliancy = array('min' => '1.6', 'max' => _PS_VERSION_);
}
/**
* Don't forget to create update methods if needed:
* http://doc.prestashop.com/display/PS16/Enabling+the+Auto-Update
*/
public function install()
{
Configuration::updateValue('MWS_CONTENTBOX_SCHEDULE', null);
Configuration::updateValue('MWS_CONTENTBOX_SOME_MESSAGE', null);
return parent::install() &&
$this->registerHook('header') &&
$this->registerHook('displayNav1');
}
public function uninstall()
{
Configuration::deleteByName('MWS_CONTENTBOX_SCHEDULE');
Configuration::deleteByName('MWS_CONTENTBOX_SOME_MESSAGE');
return parent::uninstall();
}
/**
* Load the configuration form
*/
public function getContent()
{
/**
* If values have been submitted in the form, process.
*/
if (((bool)Tools::isSubmit('submitMws_contentboxModule')) == true) {
$this->postProcess();
}
$this->context->smarty->assign('module_dir', $this->_path);
$output = $this->context->smarty->fetch($this->local_path.'views/templates/admin/configure.tpl');
return $output.$this->renderForm();
}
/**
* Create the form that will be displayed in the configuration of your module.
*/
protected function renderForm()
{
$helper = new HelperForm();
$helper->show_toolbar = false;
$helper->table = $this->table;
$helper->module = $this;
$helper->default_form_language = $this->context->language->id;
$helper->allow_employee_form_lang = Configuration::get('PS_BO_ALLOW_EMPLOYEE_FORM_LANG', 0);
$helper->identifier = $this->identifier;
$helper->submit_action = 'submitMws_contentboxModule';
$helper->currentIndex = $this->context->link->getAdminLink('AdminModules', false)
.'&configure='.$this->name.'&tab_module='.$this->tab.'&module_name='.$this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->tpl_vars = array(
'fields_value' => $this->getConfigFormValues(), /* Add values for your inputs */
'languages' => $this->context->controller->getLanguages(),
'id_language' => $this->context->language->id,
);
return $helper->generateForm(array($this->getConfigForm()));
}
/**
* Create the structure of your form.
*/
protected function getConfigForm()
{
return array(
'form' => array(
'legend' => array(
'title' => $this->l('Settings'),
'icon' => 'icon-cogs',
),
'input' => array(
array(
'col' => 3,
'type' => 'text',
'prefix' => '',
'desc' => $this->l('For example: 10:00 - 20:00 daily'),
'name' => 'MWS_CONTENTBOX_SCHEDULE',
'label' => $this->l('Schedule'),
),
array(
'col' => 3,
'type' => 'text',
'prefix' => '',
'desc' => $this->l('For example: March 8 is a day off!'),
'name' => 'MWS_CONTENTBOX_SOME_MESSAGE',
'label' => $this->l('Some message'),
),
),
'submit' => array(
'title' => $this->l('Save'),
),
),
);
}
/**
* Set values for the inputs.
*/
protected function getConfigFormValues()
{
return array(
'MWS_CONTENTBOX_SCHEDULE' => Configuration::get('MWS_CONTENTBOX_SCHEDULE', null),
'MWS_CONTENTBOX_SOME_MESSAGE' => Configuration::get('MWS_CONTENTBOX_SOME_MESSAGE', null),
);
}
/**
* Save form data.
*/
protected function postProcess()
{
$form_values = $this->getConfigFormValues();
foreach (array_keys($form_values) as $key) {
Configuration::updateValue($key, Tools::getValue($key));
}
}
/**
* Add the CSS & JavaScript files you want to be added on the FO.
*/
public function hookHeader()
{
// Здесь можно добавить стили и скрипты
// $this->context->controller->addJS($this->_path.'/views/js/front.js');
// $this->context->controller->addCSS($this->_path.'/views/css/front.css');
}
public function hookDisplayNav1()
{
// Назначаем переменные для шаблона smarty
$this->context->smarty->assign([
'MWS_CONTENTBOX_SCHEDULE' => Configuration::get('MWS_CONTENTBOX_SCHEDULE'),
'MWS_CONTENTBOX_SOME_MESSAGE' => Configuration::get('MWS_CONTENTBOX_SOME_MESSAGE'),
// Добавим из таблицы БД ps_configuration телефон:
'BLOCKCONTACTINFOS_PHONE' => Configuration::get('BLOCKCONTACTINFOS_PHONE')
]);
return $this->display(__FILE__, 'mws_contentbox.tpl');
}
}
Располагаться наш модуль будет в хуке displayNav1. Скриншот страницы Дизайн/Расположение блоков:
Давайте разберем код основного файла нашего модуля.
В самом начале проверяем наличие константы PrestaShop (номер версии). Если она не существует, то останавливаем загрузку модуля. Единственная цель этого — не допустить, чтобы злоумышленники загружали этот файл напрямую.
<?php
if (!defined('_PS_VERSION_')) {
exit;
}
Конструктор
Этот обязательный метод класса определяет наименование модуля, вкладку для его отображения в Админке, название в списке модулей, описание, версию и любые другие константы, которые могут пригодиться в работе. И не забываем про родительский конструктор.
Методы install() и uninstall()
Метод инсталляции осуществляет создание таблиц в базе данных, если нужно, или добавление записей в уже имеющуюся таблицу, а также регистрацию хуков. Метод uninstall() удаляет записи из БД и деинсталлирует модуль.
После установки модуля в таблице БД ps_configuration появятся строки с нашими переменными:
Страница настройки модуля в Админке:
Метод getContent()
Отвечает за настройку модуля в Админке. То есть, если метод с таким названием есть, то на странице управления модулями автоматически создается ссылка "Настроить" для данного модуля. Метод должен обеспечить вывод формы на странице настройки модуля в бэк-офисе и обработать пришедшие от админа данные настроек, сохранив их в базу данных (метод postProcess()).
Подробно об этом можно почитать в Документации:
Добавление страницы конфигурации
https://devdocs.prestashop.com/1.7/modules/creation/adding-configuration-page/
Метод renderForm()
Здесь происходит создание формы, которая будет отображаться на странице конфигурации нашего модуля.
HelperForm – это вспомогательный класс, который позволяет генерировать стандартные элементы HTML для бэк-офиса, а также для страниц конфигурации модуля.
Метод getConfigForm()
Возвращает массив, включающий заголовок, поля формы и кнопку Сохранить - все то, что мы увидим на странице конфигурации модуля в Админке. Вызывается эта функция в методе отрисовки формы renderForm().
Метод getConfigFormValues()
protected function getConfigFormValues()
{
return array(
'MWS_CONTENTBOX_SCHEDULE' => Configuration::get('MWS_CONTENTBOX_SCHEDULE', null),
'MWS_CONTENTBOX_SOME_MESSAGE' => Configuration::get('MWS_CONTENTBOX_SOME_MESSAGE', null),
);
}
Здесь устанавливаем значения полей формы конфигурации. В дальнейшем мы можем использовать массив, который возвращает этот метод, перебрав его с помощью цикла foreach и обновив значения наших переменных. Происходит это в методе postProcess():
protected function postProcess()
{
$form_values = $this->getConfigFormValues();foreach (array_keys($form_values) as $key) {
Configuration::updateValue($key, Tools::getValue($key));
}
}
Метод hookDisplayNav1() и шаблон mws_contentbox.tpl
Выводим результат работы модуля в конкретный хук. Здесь происходит вывод содержимого (например выборки из БД) в массив и передача этого массива в шаблон smarty.
Переводы строк на русский язык
Все строки, предназначенные для прочтения человеком, рекомендуется оборачивать в функцию Module::l(). Это делает возможным их перевод на любой язык. После установки модуля на странице Админки Интернационализация/Переводы вы можете перевести все строки на русский язык.
Об этом еще можно почитать тут:
Локализация собственных модулей
https://ida-freewares.ru/prestashop-1-6-lokalizatsiya-sobstvennykh-modulej-dlya-novichkov.html
Готовый модуль Content box: результат урока
Итак, мы добавили в хедер интернет-магазина номер телефона, график работы и короткое сообщение для покупателей. У нас получился вполне рабочий модуль для одноязычного сайта. На его базе можно разработать модули для вывода любого небольшого контента на ваш сайт.
Скачать архив с модулем Content box (Скачиваний: 229)
Модуль разработан в веб-мастерской MAKE-WEBSITE.ru. Тестировался на PrestaShop 1.7.6.3.
Совет:
Чтобы получить начальный каркас модуля, воспользуйтесь Module Generator. В посте Заготовка PrestaShop модуля при помощи Генератора описана последовательность действий при генерации собственного модуля.
Полезные ссылки по разработке Престашоп модуля
Документация: Понимание вашего первого модуля
https://devdocs.prestashop.com/1.7/modules/creation/
Русская документация PrestaShop 1.6
https://bestprogrammer.xyz/sozdanie-pervogo-modulya/
PrestaShop 1.6 - памятка для авторов модулей (для новичков)
https://ida-freewares.ru/prestashop-1-6-pamyatka-dlya-avtorov-modulej-dlya-novichkov.html
Еще хорошие статьи по созданию модуля:
http://kupreev.com/page/prestashop-shopbyprice-module-fix
http://hncoder.blogspot.com/2013/11/prestashop-v15.html
http://webnewbie.ru/modules/blogwp/wordpress/prestashop/detalnyj-analiz-modulya-prestashop-1-5.html
Пишите вопросы в комментариях. И буду благодарен за ваши мнения и отзывы!
Создаю современные
высококонверсионные сайты
Прочитайте еще посты:
-
Создание сайтов для слабовидящих пользователей: ключевые особенности инклюзивной веб-разработки
Для людей с нарушениями зрения доступ к веб-сайтам и навигация по ним могут оказаться сложной задачей. Чтобы обеспечить равный доступ к Интернету, веб-разработчикам важно создавать веб-сайты с учетом потребностей слабовидящих пользователей.
Подробнее -
Как улучшить свой JavaScript код
Некоторые рекомендации и полезные ссылки из сети по преобразованию своего JavaScript кода для начинающего фронтенд разработчика.
Подробнее
17 Марта 2020
Просмотров: 9513
Комментариев: 3
веб разработка, cms, prestashop, рецепты
Теги
- веб разработка (13)
- рецепты (8)
- javascript (7)
- медицина (7)
- сайт-визитка (7)
- сайт под ключ (6)
- календарь (6)
- cms (6)
- интернет-магазин (6)
- prestashop (6)
- modx (5)
- веб дизайн (4)
- продвижение (4)
- виджеты (3)
- стандарты (3)
- php (3)
- лендинг (3)
- мода (2)
- дублирование контента (2)
- редиректы (2)
- seo оптимизация (2)
- логотипы (2)
- блог (2)
- vue.js (2)
- HostCMS (2)
Содержание
Оставьте свой комментарий!
Комментарии (3)
Давайте общаться
Я хотел бы поговорить о вашем бизнесе, отправьте мне письмо на make.website.info@gmail.com.
avyazovoi: Май 12, 2021г. в 10:34
Благодарю, получил ответы на все вопросы при создании своего первого модуля на престе :)
ОтветитьPrestaNoob: Январь 06, 2023г. в 20:07
Благодарю за данный урок, по больше уроков на PrestaShop, это отличный опенсорс магазин
Ответитьkvant08: Январь 15, 2023г. в 18:27
Очень хорошая статья. У меня такой вопрос: престашоп 8 как убрать поле доставка в модуле корзина?
Ответить