OpenCart — от новичка до профессионала: разработка модуля

29 Мая 2022г. в 05:07

Что такое модули OpenCart?
Модули OpenCart аналогичны надстройкам, плагинам или расширениям в других системах управления контентом. Благодаря модулям OpenCart дает нам возможность расширить функционал без необходимости редактировать файлы приложения.

Как и во многих других системах управления контентом, лучшей практикой считается расширение функционала основного приложения через предоставление API — OpenCart мало чем в этом плане отличается. С помощью модулей мы можем вводить, удалять или изменять функции основного приложения через разделение и поддержание.

OpenCart имеет свой собственный Каталог расширений, в котором представлено большое количество готовых решений. Вы также можете найти самые разнообразные модули расширения OpenCart на Envato Market.

Наш первый модуль
В качестве примера давайте создадим простой модуль OpenCart «Hello World». Он предназначен для ввода информации через панели управления и отображения ее через интерфейс сайта. OpenCart содержит несколько предустановленных модулей. Мы постараемся использовать их, когда это будет возможно. Для начала выполните следующие действия:

Создайте контроллер для пути к панели администрирования: admin/controller/module/helloworld.php.

Создайте файл языка для пути к панели администрирования: admin/language/english/module/helloworld.php.

Представление для пути к панели администрирования: admin/view/template/module/helloworld.tpl.

Файл языка
Файл языка состоит из статического текста, который должен отображаться в нашем файле. Следующие переменные в файле helloworld.php содержат текстовые поля которые необходимы для отображения текста в модуле.

<?php
// Заголовок
$_['heading_title'] = 'Hello World';

// Текст
$_['text_module'] = 'Modules';
$_['text_success'] = 'Success: You have modified module Hello World!';
$_['text_content_top'] = 'Content Top';
$_['text_content_bottom'] = 'Content Bottom';
$_['text_column_left'] = 'Column Left';
$_['text_column_right'] = 'Column Right';

// Данные
$_['entry_code'] = 'Hello World Code:';
$_['entry_layout'] = 'Layout:';
$_['entry_position'] = 'Position:';
$_['entry_status'] = 'Status:';
$_['entry_sort_order'] = 'Sort Order:';

// Ошибка
$_['error_permission'] = 'Warning: You do not have permission to modify module Hello World!';
$_['error_code'] = 'Code Required';
?>

<?php
// Заголовок
$_['heading_title'] = 'Hello World';

// Текст
$_['text_module'] = 'Modules';
$_['text_success'] = 'Success: You have modified module Hello World!';
$_['text_content_top'] = 'Content Top';
$_['text_content_bottom'] = 'Content Bottom';
$_['text_column_left'] = 'Column Left';
$_['text_column_right'] = 'Column Right';

// Данные
$_['entry_code'] = 'Hello World Code:';
$_['entry_layout'] = 'Layout:';
$_['entry_position'] = 'Position:';
$_['entry_status'] = 'Status:';
$_['entry_sort_order'] = 'Sort Order:';

// Ошибка
$_['error_permission'] = 'Warning: You do not have permission to modify module Hello World!';
$_['error_code'] = 'Code Required';
?>
Контроллер
Откройте файл контроллера «Hello World», который мы только что создали, и добавьте в него класс class ControllerModuleHelloworld extends Controller {} согласно Конвенции о присвоении имен класса . Затем добавьте в этот класс следующий код.

Шаг 1: Функция по умолчанию
private $error = array(); // используется для установки ошибки, если таковая возникла.

public function index() { // функция по умолчанию
$this->language->load('module/helloworld'); // Загрузка файла языка helloworld

$this->document->setTitle($this->language->get('heading_title')); // Устанавливаем заголовок страницы в шапке файла языка, то есть Hello World
$this->load->model('setting/setting'); // Загружаем Setting Model (все модели и общие настройки в OpenCart сохраняются с помощью этой модели)


if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { // Начало If : валидация и проверка данных если они переданы с помощью безопасного метода (POST)
$this->model_setting_setting->editSetting('helloworld', $this->request->post); //Анализ и передача входящих данных в Setting Model для сохранения в базе данных.
$this->session->data['success'] = $this->language->get('text_success'); // Для вывода текста о том что данные успешно сохранены
$this->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL')); // редирект в Module Listing
} // окончание If

/*Назначаем данные языка для анализа и передачи их в представление*/
$this->data['heading_title'] = $this->language->get('heading_title');

$this->data['text_enabled'] = $this->language->get('text_enabled');
$this->data['text_disabled'] = $this->language->get('text_disabled');
$this->data['text_content_top'] = $this->language->get('text_content_top');
$this->data['text_content_bottom'] = $this->language->get('text_content_bottom');
$this->data['text_column_left'] = $this->language->get('text_column_left');
$this->data['text_column_right'] = $this->language->get('text_column_right');

$this->data['entry_code'] = $this->language->get('entry_code');
$this->data['entry_layout'] = $this->language->get('entry_layout');
$this->data['entry_position'] = $this->language->get('entry_position');
$this->data['entry_status'] = $this->language->get('entry_status');
$this->data['entry_sort_order'] = $this->language->get('entry_sort_order');

$this->data['button_save'] = $this->language->get('button_save');
$this->data['button_cancel'] = $this->language->get('button_cancel');
$this->data['button_add_module'] = $this->language->get('button_add_module');
$this->data['button_remove'] = $this->language->get('button_remove');


/*Этот блок возвращает предупреждение*/
if (isset($this->error['warning'])) {
$this->data['error_warning'] = $this->error['warning'];
} else {
$this->data['error_warning'] = '';
}
/*Конец блока*/

/*Этот блок возвращает код ошибки, если таковая возникла*/
if (isset($this->error['code'])) {
$this->data['error_code'] = $this->error['code'];
} else {
$this->data['error_code'] = '';
}
/*Конец блока*/


/* Создание хлебных крошек для вывода их на сайте*/
$this->data['breadcrumbs'] = array();

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => false
);

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_module'),
'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
);

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title'),
'href' => $this->url->link('module/helloworld', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
);

/* Конец блока хлебных крошек*/

$this->data['action'] = $this->url->link('module/helloworld', 'token=' . $this->session->data['token'], 'SSL'); // URL to be directed when the save button is pressed

$this->data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'); // URL to be redirected when cancel button is pressed


/* Этот блок проверяет, задано ли текстовое поле hello world, если да, анализирует его и передает в представление, в противном случае получает значение текстового поля hello world по умолчанию из базы данных и анализирует и передает его*/

if (isset($this->request->post['helloworld_text_field'])) {
$this->data['helloworld_text_field'] = $this->request->post['helloworld_text_field'];
} else {
$this->data['helloworld_text_field'] = $this->config->get('helloworld_text_field');
}
/*конец блока*/

$this->data['modules'] = array();

/*Этот блок анализирует и передает в представление такие настройки модуля как Макет,Позиция,Порядок*/
if (isset($this->request->post['helloworld_module'])) {
$this->data['modules'] = $this->request->post['helloworld_module'];
} elseif ($this->config->get('helloworld_module')) {
$this->data['modules'] = $this->config->get('helloworld_module');
}
/* конец блока*/

$this->load->model('design/layout'); // Загружаем модель макета дизайна

$this->data['layouts'] = $this->model_design_layout->getLayouts(); // Получение макета доступного в системе

$this->template = 'module/helloworld.tpl'; //Загрузка шаблона helloworld.tpl
$this->children = array(
'common/header',
'common/footer'
); // Добавление дочерних элементов для нашего шаблона по умолчанию, т.е. helloworld.tpl

$this->response->setOutput($this->render()); // Отображение
}

private $error = array(); // используется для установки ошибки, если таковая возникла.

public function index() { // функция по умолчанию
$this->language->load('module/helloworld'); // Загрузка файла языка helloworld

$this->document->setTitle($this->language->get('heading_title')); // Устанавливаем заголовок страницы в шапке файла языка, то есть Hello World
$this->load->model('setting/setting'); // Загружаем Setting Model (все модели и общие настройки в OpenCart сохраняются с помощью этой модели)


if (($this->request->server['REQUEST_METHOD'] == 'POST') && $this->validate()) { // Начало If : валидация и проверка данных если они переданы с помощью безопасного метода (POST)
$this->model_setting_setting->editSetting('helloworld', $this->request->post); //Анализ и передача входящих данных в Setting Model для сохранения в базе данных.
$this->session->data['success'] = $this->language->get('text_success'); // Для вывода текста о том что данные успешно сохранены
$this->redirect($this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL')); // редирект в Module Listing
} // окончание If

/*Назначаем данные языка для анализа и передачи их в представление*/
$this->data['heading_title'] = $this->language->get('heading_title');

$this->data['text_enabled'] = $this->language->get('text_enabled');
$this->data['text_disabled'] = $this->language->get('text_disabled');
$this->data['text_content_top'] = $this->language->get('text_content_top');
$this->data['text_content_bottom'] = $this->language->get('text_content_bottom');
$this->data['text_column_left'] = $this->language->get('text_column_left');
$this->data['text_column_right'] = $this->language->get('text_column_right');

$this->data['entry_code'] = $this->language->get('entry_code');
$this->data['entry_layout'] = $this->language->get('entry_layout');
$this->data['entry_position'] = $this->language->get('entry_position');
$this->data['entry_status'] = $this->language->get('entry_status');
$this->data['entry_sort_order'] = $this->language->get('entry_sort_order');

$this->data['button_save'] = $this->language->get('button_save');
$this->data['button_cancel'] = $this->language->get('button_cancel');
$this->data['button_add_module'] = $this->language->get('button_add_module');
$this->data['button_remove'] = $this->language->get('button_remove');


/*Этот блок возвращает предупреждение*/
if (isset($this->error['warning'])) {
$this->data['error_warning'] = $this->error['warning'];
} else {
$this->data['error_warning'] = '';
}
/*Конец блока*/

/*Этот блок возвращает код ошибки, если таковая возникла*/
if (isset($this->error['code'])) {
$this->data['error_code'] = $this->error['code'];
} else {
$this->data['error_code'] = '';
}
/*Конец блока*/


/* Создание хлебных крошек для вывода их на сайте*/
$this->data['breadcrumbs'] = array();

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_home'),
'href' => $this->url->link('common/home', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => false
);

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('text_module'),
'href' => $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
);

$this->data['breadcrumbs'][] = array(
'text' => $this->language->get('heading_title'),
'href' => $this->url->link('module/helloworld', 'token=' . $this->session->data['token'], 'SSL'),
'separator' => ' :: '
);

/* Конец блока хлебных крошек*/

$this->data['action'] = $this->url->link('module/helloworld', 'token=' . $this->session->data['token'], 'SSL'); // URL to be directed when the save button is pressed

$this->data['cancel'] = $this->url->link('extension/module', 'token=' . $this->session->data['token'], 'SSL'); // URL to be redirected when cancel button is pressed


/* Этот блок проверяет, задано ли текстовое поле hello world, если да, анализирует его и передает в представление, в противном случае получает значение текстового поля hello world по умолчанию из базы данных и анализирует и передает его*/

if (isset($this->request->post['helloworld_text_field'])) {
$this->data['helloworld_text_field'] = $this->request->post['helloworld_text_field'];
} else {
$this->data['helloworld_text_field'] = $this->config->get('helloworld_text_field');
}
/*конец блока*/

$this->data['modules'] = array();

/*Этот блок анализирует и передает в представление такие настройки модуля как Макет,Позиция,Порядок*/
if (isset($this->request->post['helloworld_module'])) {
$this->data['modules'] = $this->request->post['helloworld_module'];
} elseif ($this->config->get('helloworld_module')) {
$this->data['modules'] = $this->config->get('helloworld_module');
}
/* конец блока*/

$this->load->model('design/layout'); // Загружаем модель макета дизайна

$this->data['layouts'] = $this->model_design_layout->getLayouts(); // Получение макета доступного в системе

$this->template = 'module/helloworld.tpl'; //Загрузка шаблона helloworld.tpl
$this->children = array(
'common/header',
'common/footer'
); // Добавление дочерних элементов для нашего шаблона по умолчанию, т.е. helloworld.tpl

$this->response->setOutput($this->render()); // Отображение
}
Шаг 2: Метод валидации
Нам нужно проверить данные, сохранённые в функции по умолчанию. Для этого используется такой метод валидации.

/* Функция, которая производит валидацию данных при нажатии кнопки Сохранить */
protected function validate() {

/* Блок проверки прав доступа пользователя для работы с модулем*/
if (!$this->user->hasPermission('modify', 'module/helloworld')) {
$this->error['warning'] = $this->language->get('error_permission');
}
/* Конец блока*/

/* Блок для проверки задан ли helloworld_text_field надлежащим образом и сохранения его в базе данных - в противном случае возвращается ошибка*/
if (!$this->request->post['helloworld_text_field']) {
$this->error['code'] = $this->language->get('error_code');
}
/* Конец блока*/

/*Блок возвращает true если ошибок не обнаружено, в противном случае возвращает false */
if (!$this->error) {
return true;
} else {
return false;
}
/*Конец блока*/
}
/* Конец функции валидации*/

/* Функция, которая производит валидацию данных при нажатии кнопки Сохранить */
protected function validate() {

/* Блок проверки прав доступа пользователя для работы с модулем*/
if (!$this->user->hasPermission('modify', 'module/helloworld')) {
$this->error['warning'] = $this->language->get('error_permission');
}
/* Конец блока*/

/* Блок для проверки задан ли helloworld_text_field надлежащим образом и сохранения его в базе данных - в противном случае возвращается ошибка*/
if (!$this->request->post['helloworld_text_field']) {
$this->error['code'] = $this->language->get('error_code');
}
/* Конец блока*/

/*Блок возвращает true если ошибок не обнаружено, в противном случае возвращает false */
if (!$this->error) {
return true;
} else {
return false;
}
/*Конец блока*/
}
/* Конец функции валидации*/
Теперь сохраните этот файл. Мы закончили создание контроллера администрирования для нашего модуля Hello World.

Файл представления
Как мы делали это раньше в контроллере, теперь нам нужно создать HTML-код для представления. Для этого мы сделаем следующее:

Шаг 1. Создание основных элементов управления
form — это элемент, который содержит такие элементы как: input, textarea и кнопки для сохранения введенных данных или отмены ввода. Чтобы создать эту форму, используется такой код:

<?php echo $header; ?>
<div id="content">
<div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<?php echo $breadcrumb['separator']; ?><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a>
<?php } ?>
</div>
<?php if ($error_warning) { ?>
<div class="warning"><?php echo $error_warning; ?></div>
<?php } ?>
<div class="box">
<div class="heading">
<h1><img src="view/image/module.png" alt="" /> <?php echo $heading_title; ?></h1>
<div class="buttons"><a onclick="$('#form').submit();" class="button"><?php echo $button_save; ?></a><a href="<?php echo $cancel; ?>" class="button"><?php echo $button_cancel; ?></a></div>
</div>
<div class="content">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form">
<table class="form">
<tr>
<td><span class="required">*</span> <?php echo $entry_code; ?></td>
<td><textarea name="helloworld_text_field" cols="40" rows="5"><?php echo $helloworld_text_field; ?></textarea>
<?php if ($error_code) { ?>
<span class="error"><?php echo $error_code; ?></span>
<?php } ?></td>
</tr>
</table>

<?php echo $header; ?>
<div id="content">
<div class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<?php echo $breadcrumb['separator']; ?><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a>
<?php } ?>
</div>
<?php if ($error_warning) { ?>
<div class="warning"><?php echo $error_warning; ?></div>
<?php } ?>
<div class="box">
<div class="heading">
<h1><img src="view/image/module.png" alt="" /> <?php echo $heading_title; ?></h1>
<div class="buttons"><a onclick="$('#form').submit();" class="button"><?php echo $button_save; ?></a><a href="<?php echo $cancel; ?>" class="button"><?php echo $button_cancel; ?></a></div>
</div>
<div class="content">
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form">
<table class="form">
<tr>
<td><span class="required">*</span> <?php echo $entry_code; ?></td>
<td><textarea name="helloworld_text_field" cols="40" rows="5"><?php echo $helloworld_text_field; ?></textarea>
<?php if ($error_code) { ?>
<span class="error"><?php echo $error_code; ?></span>
<?php } ?></td>
</tr>
</table>
Шаг 2. Добавление табличного списка.
В form выводится список table, в котором мы можем разместить параметры позиции модуля и страницы на которой модуль будет отображаться.

<table id="module" class="list">
<thead>
<tr>
<td class="left"><?php echo $entry_layout; ?></td>
<td class="left"><?php echo $entry_position; ?></td>
<td class="left"><?php echo $entry_status; ?></td>
<td class="right"><?php echo $entry_sort_order; ?></td>
<td></td>
</tr>
</thead>
<?php $module_row = 0; ?>
<?php foreach ($modules as $module) { ?>
<tbody id="module-row<?php echo $module_row; ?>">
<tr>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][layout_id]">
<?php foreach ($layouts as $layout) { ?>
<?php if ($layout['layout_id'] == $module['layout_id']) { ?>
<option value="<?php echo $layout['layout_id']; ?>" selected="selected"><?php echo $layout['name']; ?></option>
<?php } else { ?>
<option value="<?php echo $layout['layout_id']; ?>"><?php echo $layout['name']; ?></option>
<?php } ?>
<?php } ?>
</select></td>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][position]">
<?php if ($module['position'] == 'content_top') { ?>
<option value="content_top" selected="selected"><?php echo $text_content_top; ?></option>
<?php } else { ?>
<option value="content_top"><?php echo $text_content_top; ?></option>
<?php } ?>
<?php if ($module['position'] == 'content_bottom') { ?>
<option value="content_bottom" selected="selected"><?php echo $text_content_bottom; ?></option>
<?php } else { ?>
<option value="content_bottom"><?php echo $text_content_bottom; ?></option>
<?php } ?>
<?php if ($module['position'] == 'column_left') { ?>
<option value="column_left" selected="selected"><?php echo $text_column_left; ?></option>
<?php } else { ?>
<option value="column_left"><?php echo $text_column_left; ?></option>
<?php } ?>
<?php if ($module['position'] == 'column_right') { ?>
<option value="column_right" selected="selected"><?php echo $text_column_right; ?></option>
<?php } else { ?>
<option value="column_right"><?php echo $text_column_right; ?></option>
<?php } ?>
</select></td>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][status]">
<?php if ($module['status']) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select></td>
<td class="right"><input type="text" name="helloworld_module[<?php echo $module_row; ?>][sort_order]" value="<?php echo $module['sort_order']; ?>" size="3" /></td>
<td class="left"><a onclick="$('#module-row<?php echo $module_row; ?>').remove();" class="button"><?php echo $button_remove; ?></a></td>
</tr>
</tbody>
<?php $module_row++; ?>
<?php } ?>
<tfoot>
<tr>
<td colspan="4"></td>
<td class="left"><a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a></td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>

<table id="module" class="list">
<thead>
<tr>
<td class="left"><?php echo $entry_layout; ?></td>
<td class="left"><?php echo $entry_position; ?></td>
<td class="left"><?php echo $entry_status; ?></td>
<td class="right"><?php echo $entry_sort_order; ?></td>
<td></td>
</tr>
</thead>
<?php $module_row = 0; ?>
<?php foreach ($modules as $module) { ?>
<tbody id="module-row<?php echo $module_row; ?>">
<tr>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][layout_id]">
<?php foreach ($layouts as $layout) { ?>
<?php if ($layout['layout_id'] == $module['layout_id']) { ?>
<option value="<?php echo $layout['layout_id']; ?>" selected="selected"><?php echo $layout['name']; ?></option>
<?php } else { ?>
<option value="<?php echo $layout['layout_id']; ?>"><?php echo $layout['name']; ?></option>
<?php } ?>
<?php } ?>
</select></td>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][position]">
<?php if ($module['position'] == 'content_top') { ?>
<option value="content_top" selected="selected"><?php echo $text_content_top; ?></option>
<?php } else { ?>
<option value="content_top"><?php echo $text_content_top; ?></option>
<?php } ?>
<?php if ($module['position'] == 'content_bottom') { ?>
<option value="content_bottom" selected="selected"><?php echo $text_content_bottom; ?></option>
<?php } else { ?>
<option value="content_bottom"><?php echo $text_content_bottom; ?></option>
<?php } ?>
<?php if ($module['position'] == 'column_left') { ?>
<option value="column_left" selected="selected"><?php echo $text_column_left; ?></option>
<?php } else { ?>
<option value="column_left"><?php echo $text_column_left; ?></option>
<?php } ?>
<?php if ($module['position'] == 'column_right') { ?>
<option value="column_right" selected="selected"><?php echo $text_column_right; ?></option>
<?php } else { ?>
<option value="column_right"><?php echo $text_column_right; ?></option>
<?php } ?>
</select></td>
<td class="left"><select name="helloworld_module[<?php echo $module_row; ?>][status]">
<?php if ($module['status']) { ?>
<option value="1" selected="selected"><?php echo $text_enabled; ?></option>
<option value="0"><?php echo $text_disabled; ?></option>
<?php } else { ?>
<option value="1"><?php echo $text_enabled; ?></option>
<option value="0" selected="selected"><?php echo $text_disabled; ?></option>
<?php } ?>
</select></td>
<td class="right"><input type="text" name="helloworld_module[<?php echo $module_row; ?>][sort_order]" value="<?php echo $module['sort_order']; ?>" size="3" /></td>
<td class="left"><a onclick="$('#module-row<?php echo $module_row; ?>').remove();" class="button"><?php echo $button_remove; ?></a></td>
</tr>
</tbody>
<?php $module_row++; ?>
<?php } ?>
<tfoot>
<tr>
<td colspan="4"></td>
<td class="left"><a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a></td>
</tr>
</tfoot>
</table>
</form>
</div>
</div>
</div>
Шаг 3. Добавление JavaScript.
Как видите, в предыдущем шаге мы создали кнопку « Add Module». В частности у нас есть:

<a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a>

<a onclick="addModule();" class="button"><?php echo $button_add_module; ?></a>
где пользователь может добавить несколько строк для отображения модуля с помощью разных макетов и в разных местах.

Для этого нам нужно создать JavaScript, который добавит строку в табличный список. Это улучшит пользовательский интерфейс для тех, кто использует наш модуль:

<script type="text/javascript"><!--
var module_row = <?php echo $module_row; ?>;

function addModule() {
html = '<tbody id="module-row' + module_row + '">';
html += ' <tr>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][layout_id]">';
<?php foreach ($layouts as $layout) { ?>
html += ' <option value="<?php echo $layout['layout_id']; ?>"><?php echo addslashes($layout['name']); ?></option>';
<?php } ?>
html += ' </select></td>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][position]">';
html += ' <option value="content_top"><?php echo $text_content_top; ?></option>';
html += ' <option value="content_bottom"><?php echo $text_content_bottom; ?></option>';
html += ' <option value="column_left"><?php echo $text_column_left; ?></option>';
html += ' <option value="column_right"><?php echo $text_column_right; ?></option>';
html += ' </select></td>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][status]">';
html += ' <option value="1" selected="selected"><?php echo $text_enabled; ?></option>';
html += ' <option value="0"><?php echo $text_disabled; ?></option>';
html += ' </select></td>';
html += ' <td class="right"><input type="text" name="helloworld_module[' + module_row + '][sort_order]" value="" size="3" /></td>';
html += ' <td class="left"><a onclick="$(\'#module-row' + module_row + '\').remove();" class="button"><?php echo $button_remove; ?></a></td>';
html += ' </tr>';
html += '</tbody>';

$('#module tfoot').before(html);

module_row++;
}
//--></script>

<script type="text/javascript"><!--
var module_row = <?php echo $module_row; ?>;

function addModule() {
html = '<tbody id="module-row' + module_row + '">';
html += ' <tr>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][layout_id]">';
<?php foreach ($layouts as $layout) { ?>
html += ' <option value="<?php echo $layout['layout_id']; ?>"><?php echo addslashes($layout['name']); ?></option>';
<?php } ?>
html += ' </select></td>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][position]">';
html += ' <option value="content_top"><?php echo $text_content_top; ?></option>';
html += ' <option value="content_bottom"><?php echo $text_content_bottom; ?></option>';
html += ' <option value="column_left"><?php echo $text_column_left; ?></option>';
html += ' <option value="column_right"><?php echo $text_column_right; ?></option>';
html += ' </select></td>';
html += ' <td class="left"><select name="helloworld_module[' + module_row + '][status]">';
html += ' <option value="1" selected="selected"><?php echo $text_enabled; ?></option>';
html += ' <option value="0"><?php echo $text_disabled; ?></option>';
html += ' </select></td>';
html += ' <td class="right"><input type="text" name="helloworld_module[' + module_row + '][sort_order]" value="" size="3" /></td>';
html += ' <td class="left"><a onclick="$(\'#module-row' + module_row + '\').remove();" class="button"><?php echo $button_remove; ?></a></td>';
html += ' </tr>';
html += '</tbody>';

$('#module tfoot').before(html);

module_row++;
}
//--></script>
Шаг 4: Добавление футера
Теперь нам нужно добавить футер в конце представления:

<?php echo $footer; ?>

<?php echo $footer; ?>
На данный момент мы закончили подготовку нашего первого модуля Hello World . Теперь пришло время проверить, работает ли он. Для этого войдите в панель управления и перейдите на страницу Расширения — Модули, где вы можете увидеть список модулей OpenCart System. В списке вы увидите пункт «Hello World» со статусом «Не установлен», нажмите «Установить» и на экране должна появиться панель приведенная на скриншоте ниже:



Вы можете попробовать ввести случайное значение и сохранить его. Теперь попробуйте снова отредактировать модуль, и вы увидите, что введенное вами значение установлено как значение по умолчанию.

Заключение
В этой статье мы создали базовый модуль OpenCart, используя MVC. Если вы знакомы с основными концепциями MVC, вам будет просто работать с модулями OpenCart. Основные принципы создания модулей я описал. В следующей статье мы начнем работу с интерфейсом и попробуем расширить его различными элементами.