Skip to content

Commit 5475033

Browse files
authored
Update 10_Как создать свой модуль в Evolution.md
1 parent aa4ebb6 commit 5475033

1 file changed

Lines changed: 32 additions & 28 deletions

File tree

ru/02_Разработка/07_Elements/20_Modules/10_Как создать свой модуль в Evolution.md

Lines changed: 32 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,19 @@
33

44
#### Главная страница модуля ####
55
Список товаров из нужного раздела, у каждого товара есть заголовок, аннотация и редактирование. Тв-параметры мы брать не будем, это всё же модуль для обучения.
6-
6+
![screenshot_1](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/1.png)
77

88
#### Процесс редактирования ####
9-
10-
9+
![screenshot_2](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/2.png)
1110

1211
#### Дополнительная вкладка ####
13-
12+
![screenshot_3](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/3.png)
1413
По функционалу она тут не нужна, сделаем её для примера.
1514

16-
17-
1815
#### Структура модуля ####
1916
1. Лезем в assets/modules и создаём папки и пустые файлы.
2017

21-
18+
![screenshot_4](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/4.png)
2219

2320
Основная папка модуля — contentEditor. В ней всего 1 файл — это core.php. Ядро и основной функционал нашего будущего модуля. В css будут стили, в templates шаблоны, в lang языковые версии.
2421

@@ -29,10 +26,11 @@
2926
Создаём файл main.html. У всех файлов указывать кодировку utf-8 (без BOM)!
3027
Давайте ещё раз глянем на стартовую страницу нашего будущего модуля и определимся, что нужно верстать.
3128

32-
29+
![main](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/5.png)
3330

3431
Для того, чтобы мы могли использовать стили и некоторые возможности Evo, пишем в секции head следующее:
35-
```
32+
33+
```html
3634
<head>
3735
<meta content="text/html; charset=[+modx_charset+]" http-equiv="Content-Type">
3836
<title>[+store_name+]</title>
@@ -51,9 +49,11 @@
5149
Зачем мы это сделали? Чтобы наш модуль брал стили из той темы админки, которая установлена в настройках сайта в данный момент.
5250

5351
Для примера я меняю тему на старую, и вот так теперь выглядит модуль в стиле старой-доброй зелёненькой админки из версии 1.15.
52+
![115](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/6.png)
5453

5554
Едем дальше. Как мы видим, наверху модуля у нас есть заголовок, аннотация и кнопка «Обновить». Давайте их сделаем. Открываем body и пишем:
56-
```
55+
56+
```html
5757
<h1>[+store_name+]</h1>
5858
<div id="actions">
5959
<ul class="actionButtons">
@@ -75,7 +75,7 @@ Hint: Если полазать в папке media/style/папка темы/im
7575

7676
Делаем тело страницы. Посмотрите на макет — нам нужны две вкладки. В первой из них будет таблица с ячейкой заголовков и содержимым. Во второй только текст.
7777

78-
```
78+
```html
7979
<div class="sectionBody">
8080
<p>[+module_description+]</p>
8181
<div class="tab-pane" id="tabPanel">
@@ -119,26 +119,29 @@ Hint: Если полазать в папке media/style/папка темы/im
119119
Класс sectionBody — это стиль Эво и используется он для тела модуля.
120120

121121
Создадим разметку табов. Она начинается созданием слоя-оболочки с классом tab-pane и идентификатором tabPanel. Идентификатор может быть произвольным. Сразу же после открывающего тега запускаем стандартный скрипт Эво для панелей. Это вызов функции WebFXTabPane, которой мы передаём в качестве аргумента id созданного слоя-оболочки.
122+
122123
Сделаем вкладки. Каждая из них должна иметь уникальный id и класс tab-page. Сразу же внутри вкладки нужно разместить заголовок панели
123124

124-
```
125+
```html
125126
<h2 class="tab">[+tab1_header+]</h2>
126127
```
127128

128129
Что такое [+tab1_header+] вы уже догадались? Правильно, это название панели, которое мы позже зададим в файлах языка.
129130

130131
Промотайте код до 27-й линии. Мы создаём 2-ю вкладку:
131132

132-
```
133+
```html
133134
<div class="tab-page" id="startTab2">
134135
```
135136

136137
Всё по аналогии с первой, за исключением id. Напомню, у каждой вкладки он должен быть уникален. Для того, чтобы вкладки работали и переключались, нужно их добавить в обработчик.
137138

138139
За это отвечает строка скрипта
139-
```
140+
141+
```js
140142
mypanel.addTabPage(document.getElementById("startTab"));
141143
```
144+
142145
Строку надо вызывать в теге script внутри каждой из вкладок. Как видите, в первой вкладке мы использовали id первой вкладки, во втором — второй.
143146

144147
Сразу закончим со вкладкой номер два, так как она попроще. Единственное содержимое там это плейсхолдер [+tab1_text+]. Это некий статичный текст, который также будет подгружен сюда позже.
@@ -151,18 +154,19 @@ mypanel.addTabPage(document.getElementById("startTab"));
151154
Начинаем делать самое интересное, ядро модуля. Открываем core.php, проверяем кодировку. Должна быть utf-8 без BOM.
152155

153156
Первой же строкой после открывающего тега php мы проверим, может ли пользователь открывать этот файл.
154-
```
157+
```php
155158
if(IN_MANAGER_MODE!='true' && !$modx->hasPermission('exec_module')) die('ERROR');
156-
159+
```
157160
Зададим несколько переменных, которые нам понадобятся в работе со скриптом
161+
```php
158162
$Template=new Template;//новый класс. О нём позже
159163
$bigAction = $_GET['a'];//текущее значение аргумента a из урла
160164
$moduleId = $_GET['id'];//айди модуля
161165
$FullTableName = $modx->getFullTableName('site_content');//полное имя таблицы контента
162166
```
163167

164168
Пишем класс для шаблонизации.
165-
```
169+
```php
166170
class Template{
167171
public $lang;
168172
function __construct(){
@@ -195,7 +199,7 @@ class Template{
195199
Он подключает языковые файлы, исходя из того, какая версия языка выбрана в админке, инициализирует переменную-массив lang. В этот массив мы будем писать наши плейсхолдеры, кстати. Далее он парсит переданный ему шаблон, ищет соответствия между плейсхолдером в шаблоне и значением в lang-файле и возвращает результат — собранную страницу. Как пользоваться классом, мы рассмотрим чуть ниже. Пока же просто скопируйте его в core.php
196200

197201
Теперь начинаем думать над функционалом. Модуль должен делать 2 вещи. Первая — показать нам список товаров. Вторая — редактировать выбранный товар. Конечно, можно заморочиться с серьёзной шаблонизацией, роутингом и классами для каждого действия, но задача сейчас проще. Поэтому все наши действия заворачиваем в switch-case и получаем вот такой большой скрипт.
198-
```
202+
```php
199203
switch($_REQUEST['action']){
200204
default: // Действия при загрузке модуля
201205
$section=$params['sectionId']; // Получаем из конфига id раздела
@@ -255,28 +259,28 @@ switch($_REQUEST['action']){
255259
break;
256260
}
257261
```
258-
Итак, мы имеем разделение на 2 действия в case. В самом начале ловим переданный нам $_REQUEST['action']
262+
Итак, мы имеем разделение на 2 действия в case. В самом начале ловим переданный нам $\_REQUEST['action']
259263

260264
Действие default происходит по-умолчанию при загрузке модуля, когда никакой action нам не передан.
261265

262266
Здесь возникает вопрос, что за $params['sectionId'] такая. Если вы лазали в конфигурации модулей, то могли увидеть там похожую картину:
263267

264-
268+
![config](https://raw.githubusercontent.com/0test/docs/master/ru/02_Разработка/07_Elements/20_Modules/7.png)
265269

266270
Это параметры модуля, особенность Эво. Скрипт модуля всегда их получает в массиве $params. Как задать параметр? Для начала надо создать новый модуль. Перейти во вкладку «Свойства» и там задать параметры в формате json. Нам нужен только 1 параметр, sectionId. В него будем писать, из какого раздела брать документы. Заполняем свойства
267-
```
271+
```php
268272
{ "sectionId": [{"label": "ID родителя", "type": "integer","value": "2","default": "2","desc": "" }]}
269273
```
270274
Всё. Я указал раздел с id=2. Теперь в тело модуля пишите подключение скрипта ядра
271-
```
275+
```php
272276
include_once('../assets/modules/contentEditor/core.php');
273277
```
274278
Заполняйте название и описание. Можно смело обновлять страницу админки, модуль будет установлен. А мы продолжим разбираться со скриптом.
275279

276280
Как видите, в действии по-умолчанию мы делаем запрос к базе, разбираем его и в цикле присваиваем переменной lang['phpwork'] результат работы, строчка за строчкой. А phpwork — ничего не напоминает? Это наш плейсхолдер, заданный в шаблоне. Т.е. мы будем выводить на его месте результаты работы скрипта.
277281

278282
А как будем это делать, скажут эти 2 строчки вызова класса.
279-
```
283+
```php
280284
$tpl = Template::parseTemplate($Template->getTpl(dirname( __FILE__ ).'/templates/main.html'),$modx->config);
281285
$tpl = Template::parseTemplate($tpl ,$Template->lang);
282286
```
@@ -285,15 +289,15 @@ $tpl = Template::parseTemplate($tpl ,$Template->lang);
285289
В действии edit мы проверяем, пришёл ли пост-запрос. Если да, то обновляем содержимое полей в базе и выводим отчёт о работе, либо положительный, либо отрицательный. Если запрос не пришёл, рисуем форму. Ловим переданный нам параметр editDoc, делаем запрос, отображаем поля для редактирования и в них текущие значения pagetitle и introtext.
286290

287291
Пора сделать языковой файл. Если вы обратили внимание на код класса, то могли заметить, что подключение языка происходит по вот такой схеме:
288-
```
292+
```php
289293
include_once(dirname(__FILE__) . '/lang/'.$lang.'.php')
290294
```
291295
где $lang это текущий язык системы, взятый из конфига Эво.
292296

293297
Руководствуясь этим, создаём 2 файла в папке lang: russian-UTF8.php и english.php
294298

295299
Приведу для примера русский файл. Любой файл любого другого языка абсолютно такой же, за исключением, разумеется, перевода.
296-
```
300+
```php
297301
$_field['store_name'] = "Редактор товаров";
298302
$_field['module_description'] = "<p>Модуль редактирования товаров.</p>";
299303
$_field['close'] = "Закрыть";
@@ -313,14 +317,14 @@ $_field['save_success']='Сохранили';
313317
$_field['save_error']='Ошибка сохранения';
314318
?>
315319
```
316-
Как видите, внутри массива $_field мы создали элементы массива, ключи которых полностью совпадают с теми плейсхолдерами, которые заданы в шаблоне main.html.
320+
Как видите, внутри массива $\_field мы создали элементы массива, ключи которых полностью совпадают с теми плейсхолдерами, которые заданы в шаблоне main.html.
317321

318322
Попробуйте запустить модуль. У вас должны работать табы, отображаться товары. Но пока что не работает редактирование. Давайте это исправим.
319323

320324
Посмотрите внимательно на вызов парсера при действии edit. Мы вызываем практически всё точно также, за исключением шаблона. Для редактирования применим новый шаблон, edit.html. Создайте такой файл в папке templates
321325

322326
Вот его полный листинг:
323-
```
327+
```html
324328
<!DOCTYPE html>
325329
<html>
326330
<head>
@@ -379,4 +383,4 @@ $_field['save_error']='Ошибка сохранения';
379383

380384
Дальше никаких изменений нет, и в phpwork подставляется содержимое переменных из секции case 'edit': файла core.php.
381385

382-
Конечно, в этот модуль можно было добавить ТВ-параметры, аякс-редактирование и многие другие интересные вещи, однако, статья получилась и без того объёмная.
386+
Конечно, в этот модуль можно было добавить ТВ-параметры, аякс-редактирование и многие другие интересные вещи, однако, статья получилась и без того объёмная.

0 commit comments

Comments
 (0)