demo 0 demo Тестовый модуль
Первый параметр (demo) код модуля, который передается в адресной строке в параметре «a»: http://xxx/cgi-bin/stat.pl?a=demo. 3й параметр указывает на файл без расширения pl. Т.е. если в адресной строке, кроме прочих параметров будет присутствовать a=demo, то будет выполнен скрипт demo.pl:
use strict; sub go { ToTop 'Вас приветствует тестовый модуль'; Error 'Он ничего не делает, но выводит окно с ошибкой'; } 1;
use strict; sub go { ToTop 'Строка вверху страницы'; ToLeft 'Строка в левой части экрана'; ToRight 'Строка в правой части экрана'; ToTop 'Еще одна строка вверху страницы'; Error 'Ошибка'; Show 'Эта строка не будет выведена т.к. Error() не только выводит ошибку, '. 'но и завершает выполнение модуля'; } 1;
Движок NoDeny позволяет формировать html разными способами.
Show "<p><b>Не рекомендую писать html в коде.</b> ". "<span class='error'>Это строка напечатана красным цветом</b></p>";
use strict; sub go { my($Url) = @_; if( ses::input_exists('num') ) { my $num = ses::input('num'); $num =~ /^\d+$/ or Error 'Вы не ввели целое положительное число'; Show Center "OK. Вы ввели $num"; return; } my $form = $Url->form( _('[p][p h_center][p h_center]', 'Введите целое положительное число:', v::input_t(name=>'num'), v::submit('Далее') ) ); Show Center MessageBox( $form ); } 1;
Переменные, которые были переданы браузером (POST или GET параметры) доступны через ses::input('имя переменной'). В примере ses::input('num') возвращает параметр с именем num. Т.е. если ввести в адресной строке http://../stat.pl?a=demo&num=55, то ses::input('num') вернет 55.
ses::input_exists('num') проверяет была ли вообще передана переменная num. При открытии нашего плагина, в адресной строке не будет num, поэтому условие if( ses::input_exists('num') ) не выполнится и сработает код:
my $form = создание формы ввода; Show отображение формы ввода;
my $form = $Url->form(...) создает в переменной $form код html-формы, в которой находится текстовое поле ввода с именем num, а также кнопка «Далее». Читайте здесь о создании форм. Функция _() похожа на sprintf - в первом параметре задается шаблон, остальные параметры подставляются в этот шаблон. Шаблон кодируется квадратными скобками и в большинстве случаев конвертируется по такому правилу:
[имя_тега класс] → <имя_тега class='класс'></имя_тега>
ToTop _('Здравствуйте, [span bold]. Сегодня [span big]', 'Администратор', 'Пятница!');
преобразуется в Здравствуйте, <span class='bold'>Администратор</span>. Сегодня <span class='big'>Пятница!</span>
use strict; sub go { my($Url) = @_; Adm->chk_privil_or_die(30); my $db = Db->sql("SELECT id, name, balance FROM users WHERE balance<0 ORDER BY name"); $db->ok or Error('не выполнился sql'); $db->rows > 0 or Error('Нет ни одного клиента с отрицательным балансом'); my $tbl = tbl->new( -class=>'td_wide td_medium' ); while( my %p = $db->line ) { my $err_msg = Adm->why_no_usr_access($p{id}); $err_msg && next; $tbl->add('*', 'll', $p{name}, $p{balance}); } Show Center $tbl->show; } 1;
Adm->chk_privil_or_die проверяет есть ли у текущего администратора определенная привилегия. В данном случае проверяется привилегия «просмотр платежей» (код 30, см. файл RU_admin.pl). Если привилегии нет, действие скрипта будет прекращено с выводом сообщения об отсутствии прав доступа, расширенная ошибка пойдет в debug.
Db->sql применяется когда нужно получить выборку нескольких строк, Db->line - одной строки. Разница в том, что в первом случае возвращается объект, из которого можно запрашивать строку за строкой, во втором случае сразу возвращается строка в виде хеша. Если выборка не возвращает ни одной строки, причина может быть в том, что условию не соответствует ни одна строка либо же ошибочный sql, дисконнект БД и др. ошибки. Хорошим тоном является обработка ошибок, в примере это $db->ok or Error(...).
tbl->new создает объект html-таблица с css 'td_wide td_medium'. Класс td_wide делает широкими ячейки таблицы (большой padding по ширине), td_medium делает средний вертикальный padding. Обычно таких параметров достаточно, чтобы данные в разных столбцах не сливались, т.е. между ними был достаточный промежуток. Документация по таблицам.
Adm->why_no_usr_access проверяет есть ли у текущего админа доступ к учетной записи клиента с заданным id. Если у админа нет доступа к группе клиента, то возвращается строка «нет доступа к группе». Если никаких ошибок при проверке не возникло и доступ есть, возвращается пустая строка.
Еще один пример. Модуль выводит список клиентов в виде таблицы, максимально 10 строк за раз, вверху отображая постраничную навигацию. Заголовки столбцов - ссылки, при нажатии на которые происходит сортировка по текущему столбцу.
use strict; sub go { my($Url) = @_; my %fields = ( id => 'id', fio => 'ФИО', name => 'логин', ); my $order = ses::input('order'); $order = 'id' if !exists $fields{$order}; my $sql = 'SELECT * FROM users ORDER BY '.$order; $Url->{order} = $order; my($sql, $page_buttons, $rows, $db) = Show_navigate_list($sql, ses::input_int('start'), 10, $Url); my $tbl = tbl->new( -class=>'td_ok' ); $tbl->add('head', 'lll', map{ [ $Url->a($fields{$_}, order=>$_) ] } sort{ $a cmp $b } keys %fields); while( my %p = $db->line ) { $tbl->add('*', 'lll', map{ $p{$_} } sort{ $a cmp $b } keys %fields); } Show Center $page_buttons; Show Center MessageBox( $tbl->show ); } 1;
Хеш %fields содержит поля таблицы клиентов, которые будут выводится, соответственно по этим полям возможна сортировка. $order = 'id' if !exists $fields{$order} - делает скрипт безопасным, если оператор в адресной строке подменит имя реального поля на недействительное, например sql инъекцию, то оно будет заменено на дефолтное: id.
$Url->{order} = $order добавляет в объект $Url параметр order - поскольку при постраничной навигации необходимо сохранять сортировку. В противном случае, при нажатии на любую страницу в навигации, была бы принята сортировка по умолчанию, в нашем случае по id.
$Url->a() рендерит объект $Url в гиперрсылку. Первый параметр - текст гиперссылки, остальные параметры добавляются в url. Например,
$Url->a('Привет', hi=>1);
преобразуется в <a href='?a=demo&hi=1'>Привет</a>. Почему в url появился параметр a=demo? Потому что при передаче управления модулю, в Url по умолчанию находится параметр `a`, ссылающийся на данный модуль.
my $url = url->new( a=>'users' ); Show $url->a('Список клиентов').' '.$url->a('Модуль карточек', a=>'cards');
Получим ссылки: <a href='?a=users'>Список клиентов</a> и <a href='?a=cards'>Модуль карточек</a>. Видно, что параметр `a` переопределяется во втором $url->a().
Написание реального модуля требует изучения документации, в частности структуры базы и модулей calls.pm:
Модуль, обрабатывающий ajax запросы должен возвращать данные в массив @$ses::cmd:
push @$ses::cmd, { id => 'test div', data => 'ok', };
push @$ses::cmd, { id => 'test div', action => 'add', data => 'ok', };
push @$ses::cmd, { type => 'js', data => 'alert("Hi, man!")', };
Команды выполняются в таком же порядке, как они записаны в @$ses::cmd, поэтому, если требуется, протолкнуть команду вперед, то вместо push следует применить unshift.
Если посылка данных идет в элемент с id='modal_window' (см. подпрограмму ajModal_window) - выводится модальное окно. Посылка пустой строки закрывает модальное окно.