КАК НАПИСАТЬ МОДУЛЬ OPENCART (ЧАСТЬ 3)
Часть третья — представление админки.
В этой части будет разобран языковой файл и файл представления (tpl).
Согласно из структуры модуля из первой части, строчки текста лежат у нас у language/russian/module/comments.
Рассматривать почти нечего, вот листинг этого файла:
$_['heading_title'] = 'Комменты админка'; // Text $_['text_module'] = 'Модули'; $_['text_success'] = 'Настройки модуля обновлены!'; $_['text_edit'] = 'Редактирование модуля'; // table $_['table_image'] = 'Аватарка'; $_['table_name'] = 'Имя'; $_['table_text'] = 'Комментарий'; $_['table_header'] = 'Имеющиеся коментарии'; $_['table_edit'] = 'Редактировать'; $_['table_delete'] = 'Удалить'; $_['table_id'] = 'Номер'; $_['title_add'] = 'Добавить/Изменить'; // Entry $_['entry_name'] = 'Название'; $_['entry_banner'] = 'Баннер2'; $_['entry_dimension'] = 'Размеры (Ширина x Высота)2'; $_['entry_width'] = 'Ширина2'; $_['entry_height'] = 'Высота2'; $_['entry_status'] = 'Статус2'; // Error $_['error_permission'] = 'У Вас нет прав для управления этим модулем!2'; $_['error_name'] = 'Название модуля должно быть от 3 до 64 символов!2'; $_['error_width'] = 'Необходимо указать ширину!2'; $_['error_height'] = 'Необходимо указать высоту!2';
Видим, что переменные начинаются с $_ и образуют собой асоциативный массив. Контроллер админки, либо пользовательской части получает доступ к этому массиву через такую функцию:
$this->load->language('module/comments');
Весь этот асоциативный массив подгружается к объекту language, из которого мы в любой части контроллера ПОСЛЕ того, как подключен языковой файл можем вытащить любую строку. К примеру, так:
$this->language->get('heading_title');
«Найти глобальный класс с которыйм мы работаем, найти в нем объект языков (автоматически выберется системный язык, их может быть несоклько), и с помощью метода get получить значение строки heading_title»
Так же эти строки нужно передавать на отрисовку:
$data['heading_title'] = $this->language->get('heading_title');
Это так же строка из контроллера, мы просто передаем массиву data, который уйдет как информация для отрисовки, нужный текст.
Итак, на данный момент у нас есть модель, которая описывает что можно доставать из БД. У нас есть все основные стандартные фразы, которые есть в модуле (или странице, они работают так же). Со всем этим контроллер делает примерно следующее:
— Получает нужные данные из БД
— Получает данные с помощью GET или POST (тот момент, когда происходит клик по чему либо мышкой)
— Получает текстовые строки и объединяет их в массив для отрисовки (может быть несколько языковых файлов с разных мест)
— Обрабатывает все это как нужно программисту (меняет строки, проиводит арифметические действия, сравнивает, проверяет условия и так и далее)
— Результаты обработки запихивает в тот же массив на отрисовку ($data[])
— Отправляет этот массив файлу tpl (либо строкой json, либо еще как надо может быть по заданию).
Что же делает файл tpl? Это точно такой же шаблон, как в десятках других cms.
Нам нужно вывести данные, которые мы успешно обработали контроллер в админской части движка. Что мы должны вывести:
— Свои стили для модуля. Нужно или подключать css файл, или, в данном случае, когда стилей немного — просто написать их в
<style>
.coments-wrap h3 {
padding-bottom: 15px;
padding-top: 10px;
font-weight: bold!important;
}
.coments-wrap td {
text-align: center;
vertical-align: middle;
padding: 10px;
font-size: 14px;
}
.coments-wrap table tr:nth-child(2n-1) {
background: #D8D6D6;
}
.coments-wrap thead tr {
background: #444444!important;
color: white;
}
.coments-wrap img {
width: 50px;
}
input#ret {background: #444444;border: 0;transition: 0.2s;margin-top: 20px;display: block;margin-right: 0;width: 100px;margin-left: auto;padding: 10px;color: white;text-transform: uppercase;border-radius: 4px;font-size: 16px;}
input#ret:hover {
background: #D8D6D6;
color: #444444;
box-shadow: 0px 0px 3px #444444;
}
td#add_text textarea {
height: 100px;
width: 500px;
padding: 5px;
}
.add_com input {
padding: 5px;
}
</style>
Далее следуют переменные для отладки, их нужно удалить, когда модуль готов:
<?php print_r($ret); ?> <?php print_r($ok); ?> <?php print_r($success); ?>
В контроллере мы передавали массив $data[], названия — $data[‘ret’] ячеек массива совпадают с переменной в шаблоне. Таким образом в контроллере можно ввести такую строку:
if ( какое то условие ) {
$data['ret'] = 1;
// какой то код
} else {
$data['ret'] = 2;
}
И в браузере мы узнаем — выполнилось ли условие, а с ним и код. Таким образом, если отключены ошибки php можно отлаживать код и искать место на каком он ломается.
Далее по тексту нам нужно вывести все стандартные панели и кнопки — обычно их можно взять с любого модуля, который есть в админке:
<?php echo $header; ?><?php echo $column_left; ?>
<div id="content">
<div class="page-header">
<div class="container-fluid">
<div class="pull-right">
<button type="submit" form="form-banner" data-toggle="tooltip" title="<?php echo $button_save; ?>" class="btn btn-primary"><i class="fa fa-save"></i></button>
<a href="<?php echo $cancel; ?>" data-toggle="tooltip" title="<?php echo $button_cancel; ?>" class="btn btn-default"><i class="fa fa-reply"></i></a></div>
<h1><?php echo $heading_title; ?></h1>
<ul class="breadcrumb">
<?php foreach ($breadcrumbs as $breadcrumb) { ?>
<li><a href="<?php echo $breadcrumb['href']; ?>"><?php echo $breadcrumb['text']; ?></a></li>
<?php } ?>
</ul>
</div>
</div>
<div class="container-fluid">
На данном этапе появилась шапка, хлебные крошки и левая панель с кнопками.
<?php if ($error_warning) { ?>
<div class="alert alert-danger"><i class="fa fa-exclamation-circle"></i> <?php echo $error_warning; ?>
<button type="button" class="close" data-dismiss="alert">×</button>
</div>
<?php } ?>
Строка с ошибками, которые контроллер записывает в error_warning, взято тоже из стандартного оформления, но подставлены свои значения в текст.
<div class="panel panel-default coments-wrap">
<div class="panel-heading">
<h3 class="panel-title"><?php echo $table_header; ?></h3>
<table style="width: 100%;">
<thead>
<tr>
<td><?php echo $table_id;?></td>
<td><?php echo $table_name;?></td>
<td><?php echo $table_image;?></td>
<td><?php echo $table_text;?></td>
<td><?php echo $table_edit;?></td>
<td><?php echo $table_delete;?></td>
</tr>
</thead>
<?php if(!$comments) { echo "no comments"; } ?>
<?php foreach ($comments as $comment) { ?>
<tr>
<td class="comment-id"><?php echo $comment['id']; ?></td>
<td class="comment-name"><?php echo $comment['name']; ?></td>
<td class="comment-image"><img width="100" src="<?php echo '/image/'; if ($comment['image']) echo $comment['image']; ?>"/><span style="display:none"><?php echo $comment['image']; ?></span></td>
<td class="comment-text"><?php echo $comment['text']; ?></td>
<td><a href="<?php echo $comment['id']; ?>" data-toggle="tooltip" title="" class="btn btn-primary comments-edit" data-original-title="Редактировать"><i class="fa fa-pencil"></i><input type="hidden" name="id" value="<?php echo $comment['id']; ?>"/></a></td>
<td><a href="#" data-toggle="tooltip" title="" class="btn btn-danger comment-delete" data-original-title="Удалить без подтверждения"><i class="fa fa-trash-o"><input type="hidden" name="id" value="<?php echo $comment['id']; ?>"/></i></a></td>
</tr>
<?php } ?>
</table>
<div class="add_com" style="margin-top:50px;">
<h3><?php echo $title_add;?></h3>
<table width="100%">
<thead>
<tr>
<td><?php echo $table_id;?></td>
<td><?php echo $table_name;?></td>
<td><?php echo $table_image;?></td>
<td><?php echo $table_text;?></td>
</tr>
</thead>
<tbody>
<tr>
<td id="add_id"></td>
<td id="add_name"><input type="text" name="name"/></td>
<td id="add_image">
<div>
<a href="" id="thumb-image" data-toggle="image" class="img-thumbnail">
<img src="/image/catalog/avatars/no_ava.png" alt="" title="" data-placeholder="" />
</a>
<input type="hidden" name="image" value="catalog/avatars/no_ava.png" id="input-image" />
</div>
</td>
<td id="add_text"><textarea type="text" name="text"></textarea></td>
</tr>
</tbody>
</table>
<input type="submit" id="ret" value="add"/>
</div>
<form action="<?php echo $action; ?>" method="post" enctype="multipart/form-data" id="form-account" class="form-horizontal">
<div class="form-group">
<label class="col-sm-2 control-label" for="input-status"><?php echo 11; ?></label>
<div class="col-sm-10">
<select name="comments_status" id="input-status" class="form-control">
<?php if ($comments_status) { ?>
<option value="1" selected="selected"><?php echo 1; ?></option>
<option value="0"><?php echo 0; ?></option>
<?php } else { ?>
<option value="1"><?php echo 1; ?></option>
<option value="0" selected="selected"><?php echo 0; ?></option>
<?php } ?>
</select>
</div>
</div>
</form>
</div>
<div class="panel-body">
</div>
</div>
А это уже верстка нашего модуля. Верстка на свой вкус, основные рабочие приемы — вместо текста в верстку вставляются переменные из массива $data[], так же эти переменные можно пихать в условия, по типу «Если контроллер передал в этой переменной 1 то выводим эту переменную, если нет — то другую». Пример такого условия в конце в форме, рассмотрите пример — он позволяет вывести на нужную option у select select=selected. Это нужно для того, чтобы когда человек заходит в админку, выводились те значения, которые записаны в БД, иначе если просто открыть модуль и закрыть — установятся дефолтные значения.
Далее закрывает теги и вставляем стандартный футер:
</div> </div> <?php echo $footer; ?>
На этом моменту у нас есть верстка и модуль выведется в админке. Но кнопки будут не работать, для этого нужно дописать немного js. (перед футером, так как в футере закрывается )
1. Кнопка редактирования комента:
$('.comments-edit').click(function(){
tr = $(this).parents('tr');
temp_id = tr.find('.comment-id').html();
temp_name = tr.find('.comment-name').html();
temp_img = tr.find('.comment-image span').html();
temp_text = tr.find('.comment-text').html();
$('#add_id').html(temp_id+' <input type="hidden" value="'+temp_id+'" name="id"/>');
$('#add_name input').val(temp_name);
$('#add_image img').attr({'src':'/image/'+temp_img});
$('#add_image input').val(temp_img);
$('#add_text input').val(temp_text);
return false;
});
Мы просто записываем данные из нее в форму, включая id.
Затем можно редактировать форму. Вывод формы выбора картинок достоин отдельной статьи, поэтому пока просто принимаем его на веру =)
2. Кнопка удаления комента:
$('.comment-delete').click(function(){
gems = $(this).find('input');
$.ajax({
url: 'index.php?route=module/comments/deleteComment&token=<?php echo $token; ?>',
type: 'post',
data: gems,
dataType: 'json',
beforeSend: function() {
console.log(gems);
},
error: function (json) {
console.log(json);
},
success: function(json) {
console.log(json);
location.reload();
}
});
return false;
});
Мы ищем input для установления какой же нам нужен id записи и отправляем ajax запрос на удаление к нашему КОНТРОЛЛЕРУ. Т.е. путь к контроллеру/функция контроллера. Так можно получить доступ к любой функции любого контроллера. Если все удачно — перезагружаем страницу.
3. Добавление/изменение комента (по сути это одна почти одна и та же операция)
$('#ret').click(function(){
$.ajax({
url: 'index.php?route=module/comments/addComment&token=<?php echo $token; ?>',
type: 'post',
data: $('.add_com input[type=\'text\'],.add_com input[type=\'hidden\'],.add_com textarea'),
dataType: 'json',
beforeSend: function() {
console.log($('.add_com input[type=\'text\']'));
},
error: function (json) {
console.log('error');
console.log(json);
},
success: function(json) {
console.log('added');
console.log(json);
location.reload();
}
});
return false;
});
Тут так же все несложно, ты отправляем функции в контроллере запрос, в котором отправляем поля из формы. Если все хорошо — обновляем страницу.
Полные версии файлов (языковая и представления):