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) - выводится модальное окно. Посылка пустой строки закрывает модальное окно.