Zippy – компонентний, подієво - орієнтований фреймворк на PHP, призначений для швидкої розробки сайтів. Zippy легкий для вивчення, забезпечує повне відділення дизайну від логіки, а також відділення бізнес-логіки від функцій забезпечення життєвого циклу і стану елементів сторінки.
Головна ідея - надати розробнику необхідний набір компонентів, який дозволить
зосередитися на розробці бізнес-логіки сайту.
Розробнику немає необхідності працювати з запитами, роутерами,
чисельнними API - він працює тільки з подіями і властивостями компоентів сервера.
Обмін даних з браузером, рендеринг шаблону сторінки, обробка
запитів і т.д. забезпечується компонентами, відповідними клієнтськими елементами сторінки. Тобто, якщо ви кликнули
на сторінці за посиланням, або кнопці все що вам потрібно це призначити
на серверній стороні обробник цієї події для даного компонента (компонент - це просто PHP клас) і написати в ньому
код бізнес логіки.
Обмін даними з компонентами проводиться через властивості цих компонетів -
якщо наприклад вам потрібно вивести список, що випадає, ви просто передаєте компоненту асоціативний масив.
Компонентна структура Zippy дозволяє легко розділяти роботу між розробниками, розширювати і створювати нові компоненти і модулі. Найбільш ефективне застосування фреймворка - інтерактивні сайти, які передбачають взаємодію з користувачами аналогічно десктопних додатків (так званий rich-інтерфейс).
Основні архітектурні рішення з розділення логіки та інтерфейсу запозичені з фреймворка Wicket (В певному сенсі можна розглядати як портінг на PHP), а також (Прямо чи опосередковано) ряд ідей з таких рішень як: JSF, ASP.NET, Delphi for PHP і подібних компонентно-орієнтованих систем.
Установка фреймворка проводиться за допомогою Composer.
composer require leon-mbs/zippy
У заголовку сторінки вказати
<link rel="stylesheet" href="/vendor/leon-mbs/zippy/assets/css/bootstrap.css">
<link rel="stylesheet" href="/vendor/leon-mbs/zippy/assets/css/zippy-bundle.min.css">
<script src="/vendor/leon-mbs/zippy/assets/js/jquery.js" type="text/javascript">
<script src="/vendor/leon-mbs/zippy/assets/js/bootstrap.bundle.js" type="text/javascript">
<script src="/vendor/leon-mbs/zippy/assets/js/zippy-bundle.min.js" type="text/javascript">
Ці файли містять необхідні фронт-енд бібліотеки - JQuery, Twitter Bootstrap, Awesome font та всі необхідні плагіни і компоненти.
Крім того, можна завантажити фреймворк в зборі
з усіма необхідними бібліотеками у вигляді архіву.
Разом з фреймворком йде демо додаток з прикладами. Ця програма можна використовувати як стартову (заготовку).
Потрібно тільки замінити сторінки з прикладами на свої. Базову сторінку слід залишити, додавши
необхідні елементи в темплейт (хедер, футер та інші загальні елементи сайту)
можна також завантажити демо-додаток в зборі з фреймворком. Також доступні вихідні коди,
де можна знайти приклади організації роботи з БД, підключення авторизації та ін.
Репозиторій фреймворка на GitHub: Посилання
Документація за класами фреймворка
Генератор, що дає можливість частково автоматизувати генерацію класу сторінки по її шаблону.
Основним елементом сайту, побудованого з використанням Zippy, є сторінка.
Сторінка складається з PHP класу - спадкоємця від класу WebPage
(бекенд) і HTML файлу (фронтенд).
Для кожного елемента (HTML тега) сторінки, пов'язаного з бізнес-логікою, створюється екземпляр
відповідного класу (Zippy-компонент) в PHP коді.
<body>
<span zippy="msg"></span>
<a zippy="onmsg">Клік</a>
</body>
use \Zippy\Html\Label;
use \Zippy\Html\Link\ClickLink;
class Example1 extends \Zippy\Html\WebPage
{
//У конструкторі створюємо екземпляри компонентів
public function __construct($params = null) {
$this->add(new Label('msg'));
$this->add(new ClickLink('onmsg', $this, 'OnClick'));
}
// Оброблювач кліка по посиланню
public function OnClick($sender) {
//Надаємо текст для виведення в тезі span
$this->msg->setText("OK");
}
}
Компонент забезпечує рендеринг в HTML, збереження стану
(В тому числі для елементів введення), а також виклик обробників подій
що виникають при навігації користувача по сторінці. Зв'язок між компонентом
і HTML поданням забезпечується за допомогою атрибута "zippy"
в
відповідних HTML тегах. При створенні екземпляра компонента в його
конструкторі передається значення атрибута "zippy"
яке присвоюється полю
id
визначеному в класі HtmlComponent
, від якого успадковуються всі компоненти.
Таким чином HTML код не включає в себе ніяких скріплет і інших чужорідних
вставок. При рендеринге компоненту маніпулюючи тегом змінюєм його значення і / або
значення його атрибутів, відображаючи таким чином свої дані в вихідному HTML потоці.
Важлива умова - ієрархія компонентів сторінки строго відповідає вкладеності відповідних
(З атрибутом "zippy"
) HTML тегів. Якщо, наприклад посилання, або інший елемент знаходиться в формі і
для форми як і для елемента необхідно створити відповідний серверний компонент то компонент
посилання повинен бути доданий до форми викликом методу Add
попередньо створеного об'єкта форми.
<body>
<form zippy="form1">
<input type="text" zippy="message" />
</form>
</body>
public function __construct($params = null) {
$this->add(new Form('form1'));
$this->form1->add(new TextInput('message');
}
use \Zippy\Html\Label;
use \Zippy\Html\Link\ClickLink;
class Example1 extends \Zippy\Html\WebPage
{
public $counter=0;
// Оброблювач кліка по посиланню
public function OnClick($sender) {
//Надаємо текст для виведення в тезі span
$this->counter++;
$this->msg->setText("Счетчик ". $this->counter);
}
}
Таким чином може бути збережена між оновленнями сторінки будь-яка складна структура.
Природно, якщо потрібно очистити дані в компоненті потрібно робити це явно, аналогічно десктопних додатків.
$this->msg->setText("");
WebApplication
в залежності від аналізу запитів браузера до сервера.
При першому відкритті сторінки додаток створює екземпляр класу сторінки. У конструкторі
сторінки створюються екземпляри всіх компонентів сторінки, виконується Біндінг і призначення обробників
подій. Потім екземпляр класу сторінки серіалізуются з усім вмістом і записується в сесійне
сховище. Після цього додаток завантажує HTML шаблон з місця на диску, зазначеного розробником в
функції getTemplate
, парсить його і викликає метод візуалізації класу сторінки. клас сторінки
рендерить всі дочірні компоненти. Компонент змінює відповідний йому (пов'язаний через атрибут zippy
)
HTML тег коректуючи його зміст і / або атрибути. Після рендеринга сторінки додаток відправляє
змінений HTML код браузеру.
При запиті зі сторінки (наприклад клік по посиланню) додаток десеріалізує екземпляр класу сторінки з сесії і знаходить компонент ініціатор запиту (посилання, кнопка і т.д.). Компонент активізує пов'язаний з ним призначену для користувача функцію - обробник подій яким зазвичай є метод класу сторінки, оскільки це дозволяє мати доступ до всіх компонентів сторінки і таким чином реалізувати всю бізнес логіку пов'язану з поведінкою сторінки, обміном даних і т.д. Потім екземпляр сторінки, разом з екземплярами всіх компонентів (Зберігають поточний стан даних) зберігається в сесійне сховище, виконується рендеринг і відправка відповіді в браузер. Сесійне сховище зберігає історію зміни сторінок що дозволяє віддавати сторінку з відповідним "історичним" станом при навігації браузера кнопками "вперед" / "назад".
Клас додатки. Виконує розбір HTTP запиту, управляє життєвим циклом сторінки
і формує відповідь для клієнта. Для використання створити екземпляр класу наследнінка від WebApplication
і
перевизначити мінімум одну функцію завантаження шаблонів сторінок getTemplate
.
Вхідним параметром є ім'я класу сторінки, вихідним змістом
шаблону. Приклад реалізації можна подивитися в демо ДОДАТОК.
Керуючи завантаженням шаблону можна легко реалізувати змінювані теми сайту.
У складних проектах функцію обробки (або несколлко функцій якщо модульне додаток) можна встановити методом setTemplate
і може задаватся строковим ім'ям,
або лямбдам. В цьому випадку можна не створювати свій екзеспляр заломлення, а використовувати непосредствено WebApplication
.
При створенні екземпляра WebApplication
, або власного класу-спадкоємця в конструктор необхідно передати ім'я класу початкової
сторінки сайту. Приклад коду з index.php
class Application extends \Zippy\WebApplication
{
public function getTemplate($name)
{
//завантаження шаблонів для сторінок
$name = str_replace("Pages\\", "", ltrim($name, '\\'));
$path = __DIR__ . '/' ."templates/" . strtolower($name) . ".html";
$template = file_get_contents($path);
if ($template == false) {
new \Exception('Невірний шлях до шаблону сторінки: ' . $path);
}
return $template;
}
// якщо потрібно роутинг
public function Route($uri){
if($uri == '') $uri = 'page1';
$uria= explode("/",$uri);
if($pages[$uria[0]]=='page1'){
$this->LoadPage("\\Pages\\Page1");
}
else if ($pages[$uria[0]]=='page2'){
$this->LoadPage("\\Pages\\Page2",$uria[1]); //сторінка з параметром
}
else {
$this->getResponse()->to404Page() ;
}
}
}
// створюємо екземпляр програми з параметром класу головної сторінки сайту
$app = new Application('Pages\Main');
$app->Run();
створюємо екземпляр програми з параметром класу головної сторінки сайту WebPage
.
У конструкторі створюються всі компоненти сторінки. Ієрархія компонентів повинна строго
відповідати вкладеності тегів з атрибутом zippy
в шаблоні. Як правило, в класі
сторінки створюються функції обробників подій, а також реалізується логіка роботи
сторінки. Примірники компонентів сторінки створюються один раз при першому зверненні до
сторінки. Відстежувати життєвий цикл сторінки можна перевизначивши методи
beforeRequestHandle ()
, afterRequestHandle ()
та ін.
Принцип роботи класу сторінки наподобі класу бекенда в ASP WebForms, або
десктопних Delphi / WinForms - екземпляр класу сторінки (форми) містить інші елементи як контейнер,
управляє їх життєвим циклом, обробники
подій елементів є методами класу сторінки.
Базовий клас для всіх компонентів. Кожен компонент має унікальний в межах сторінки номер
елемента (поле id
) , відповідного аттрибута zippy
з відповідного тега HTML шаблону.
Кожен компонент розширює базовий клас повинен реалізувати метод RenderImpl()
який відповідає
за рендеринг (промальовування) компонента на сторінці шляхом зміни HTML тега пов'язаного з даними
компонентом. Властивість attributes
дозволяє управляти атрибутами HTML тега. Вміст тега задається
класами нащадками HtmlComponent
в залежності від його типу.
Базовий клас контейнера для компонентів. Контейнерами є: клас сторінки, класу HTML форми,
панелі (зазвичай тег DIV
) та інші компоненти які можуть містити в собі інші об'єкти типу
HtmlComponent
(Тобто HTML теги які можуть містити вкладені теги). Сам HtmlContainer
також є спадкоємцем від HtmlComponent
. У класі перевантажені методи __set()
и __get()
тому
до вкладених компонентів можна звертатися використовуючи динамічне властивість збігається з ID
компонента.
наприклад:
<form zippy="form1">
<input type="text" zippy="username">
</form>
$form = new Form();
$form = add(new TextInput('username'));
...
$form->username->getText();
Label
Виведення текстових даних на сторінці. Як правило відображається з
допомогою тега SPAN
, але можна використовувати TD
, DIV
та інші які можуть мати
текстове вміст всередині тега.
Panel
використовується як контейнер коли треба тимчасово приховати групу елементів.
Наприклад при редагуванні рядки таблиці приховати таблицю і показати форму редагування.
Оскільки робота відбувається в межах тієї ж сторінки, зберігаються всі сортування фільтрація і пагінація таблиці.
Як правило компонент відображається за допомогою тега div
, або іншого блочного елемента.
Фреймворк містить кілька різновидів компонентів для HTML посилань. Всі вони прив'язуються до Тегу <a> шаблону. Найбільш використовувані:
ClickLink
- служить для виклику обробника події в класі Сторінки без можливості
зробити закладку в браузері (оскільки це не має сенсу - посилання не веде на будь-якій
ресурс, а просто викликає обробник.)
public function __construct($params = null) {
$this->add(new ClickLink('onmsg'))->onClick( $this, 'OnClick');
}
// Оброблювач
public function OnClick($sender) {
}
}
BookmarkableLink
- використовується для зовнішнього переходу, або ЧПУ з можливістю створити закладку.
Для вказівки адреси сторінки вказується ім'я класу сторінки з прямими слешом
RedirectLink
- використовується для редиректу на іншу сторінку. Іма класу сторінки задається як параметр
в конструкторі.
SubmitLink
- відправляє форму на сервер, з можливістю викликати оброблювач події по відправці форми.
Компоненти відповідають тегам елементів введення HTML форми. Для прийняття даних по відправці форми компоненти реалізують метод
getRequestData()
в якому зчитують «свої» дані з $_POST
або $_GET
змінних. При рендерінгу як і інші візуальні
компоненти форматують теги відповідно до своїх значеннями. Якщо значення не були змінені,
відображаються дані що були при введенні форми. Таким чином автоматично зберігається стан
всіх елементів форми - полів введення, перемикачів і т.д при перезавантаженні сторінки.
Для реакції на відправку форми форма призначається обробник.
public function __construct($params = null) {
$this->add(new Form('form1'))->onSubmit( $this, 'OnForm1');
}
// Оброблювач
public function OnForm1($sender) {
}
Замість форми обробник може бути призначений одному, або декільком
компонентів типу SubmitLink
, або
SubmitButton
які можуть відправляти форму.
Компонент повинен бути всередині форми.
public function __construct($params = null) {
$this->add(new Form('form1'))->onSubmit( $this, 'OnForm1');
$this->form1->add(new SubmitLink('sl1'))->onClick( $this, 'OnForm1');
}
// Оброблювач
public function OnForm1($sender) {
}
Для взаємодії між собою компонентів, існує набір інтерфейсів, які повинені реалізувати той чи інший компонент. Найбільш використовувані:
Requestable
– компонент здатний обробляти HTTP запит.ClickListener
– компонент може викликати серверний обробник події при натисканні мишкою. EventReceiver
– може мати методи обробники події SubmitDataRequest
– компонент приймає дані з форми.обработчікі подіїБільшість призначених для користувача методів сторінки (в яких реалізується бізнес логіка сторінки) як правило є обработчиками подій. Наприклад клік по посиланню, відправка форми, навігація по сторінці і т.д.
Для призначення обробника компоненту ініціатору вказується об'єкт-одержувач
(зазвичай $this
- об'єкт класу сторінки) і ім'я методу-обробника в текстовому вигляді.
Метод-обробник містить параметр $sender
– посилання на об'єкт джерело (одній і тійж
події може бути призначено декількох компонентів) і, при необхідності, додаткові
параметри.
В адресному рядку фреймворк формує номер сторінки і ієрархію компонентів в
якої знаходиться джерело. При обробці запиту бекенд компоненти, які є контейнерами,
передаватимуть виклик компоненту, ID
який наступний в ієрархії, аж до
останнього - ініціатора події (тобто по фронтенду якого наприклад кликнули мишкою).
Механізм подій позбавляє розробника від турбот щодо функціонування сторінки, розборі запиту і формування відповіді клієнтові. Розробник працює з методами подій аналогічно додатків типу Delphi. або WinForms.
Дозволяє зв'язати змінну або властивість класу з цими компонента для того щоб працювати не з компонентами безпосередньо, а зі змінними, або полями бізнес-об'єктів.
Наприклад, при Біндінг компонентаLabel
з полем сторінки $msg
у функціях
бізнес логіки досить привласнити значення полю і текст буде виведений на
сторінку компонентом Label
. Якщо, наприклад, яка-небудь змінна прив'язана
до компоненту TextInput
при введенні даних з поля форми значення поля автоматично
присвоїти змінну. Біндінг задається посиланням і ім'ям - прив'язувати властивості.
<php
use \Zippy\PropertyBinding as Bind;
class Example2 extends \Zippy\Html\WebPage {
public $msg, $text;
public function __construct($params = null) {
$this->add(new Label('outputtext', new Bind($this, 'msg')));
$form = $this->add(new Form('form1'));
$form->onSubmit($this, 'OnSubmit');
$form->add(new TextInput('inputtext', new Bind($this, 'text')));
}
public function OnSubmit($sender) {
$this->msg = $this->text;
}
}
Основне призначення компонента DataView
висновок табличних даних.
Приклад на основі демо додатки
<table >
<tr><th>ПІБ</th><th>Вік</th><th> </th></tr>
<tr zippy="list"><td><span zippy="fio"></span></td>
<td><span zippy="age"></span></td>
<td><a zippy="edit">Редагувати></a> </td>
</tr>
</table>
public function __construct()
{
$this->add(new DataView('list',new DataSource(),$this,'listOnRow'))->Reload();
}
public function listOnRow($row){
//отримуємо об'єкт даних пов'язаний з рядком
$item = $row->getDataItem();
//створюємо компоненти в рядку
$row->add(new Label('fio',$item->fio));
$row->add(new Label('age',$item->age));
$row->add(new ClickLink('edit'))->onClick($this,'editOnClick');
}
//обробник редагування
public function editOnClick($sender){
//отримуємо об'єкт даних пов'язаний з рядком
$item = $sender->getOwner()->getDataItem();
//заповнюємо форму редагування і т.д.
}
Для ініціалізації виведення в необхідне джерело даних, що повертає масив об'єктів класів реалізують інтерфейс
DataItem
, або розширює клас
Entity
і
обробник в якому будуть створюватися компоненти виведення.
Paginator
, або
Pager
.
<div zippy="pag></div>
$this->add(new DataView('list',new DataSource(),$this,'listOnRow'));
//додаємо пагінатор для виведення
$this->add(new Paginator("pag",$this->list));
//встановлюємо кількість рядків на сторінці
$this->list->setPageSize(25));
$this->list->Reload();
DataView може використовувати для виведення і інші блокові елементи, наприклад якщо треба вивести список товарів, або галерею малюнків.
Для прикладу вище (бекенд той же)
<div class="row">
<div class="col-md-4" zippy="list">
<span zippy="fio"></span>
<span zippy="age"></span>
</div>
</div>
Компонент DataTable
призначений для роботи з тегом <table>. Компонент сам заголовки і пагінацію (якщо вказано), але виводить дані тільки в вигляді рядків.
Компонент найчастіше використовується для виведення різного роду репортів і інших даних, які не потребують бекенд компонентів.
При створенні компонента потрібно створити екземпляри стовпців із значеннями необхідних параметрів.
Для кастомізації виведення передбачено обробник setCellDrawEvent
рендеринга осередка, яким передається ім'я стовпця і ідентифікатор запису.
Також можна встановити обробник setCellClickEvent
кліка по осередку
<table zippy="report></div>
//виводимо таблицю з заголовком і пагінатором
$this->add(new \Zippy\Html\DataList\DataTable("report", new DataSource(), true, true));
//створюємо стовпці із зазначенням сортування
$this->report->addColumn(new Column('fio', 'ПІБ', true ));
$this->report->addColumn(new Column('age', 'Вік', true ));
Джерело даних - проміжний компонент, уніфікує передачу даних від різних джерел компонентів
DataView
і DataTable
.
Джерело даних повинен реалізувати інтерфейс DataSource
. Методи інтерфейсу вказують реалізацію джерелом
умов вибірки, сортування та пагінацію.
Існує кілька видів джерел.
ArrayDataSource
ArrayDataSource застосовується в разі використання масивів як набору даних. якщо масив
може зміняться в процесі роботи, слід передавати масив не безпосередньо, а використовувати Біндінг (див. демо додаток).
EntityDataSource
EntityDataSource застосовується для роботи з Entity
. Джерела передається як параметр ім'я класу суті успадкованої від Entity.
Джерело користувача
Для складних вибірок, розробник може створити свій клас джерела даних
і якщо потрібно зв'язати його з компонентами сторінки (наприклад фільтрацією).
class DocDataSource implements \Zippy\Interfaces\DataSource
{
private function getWhere()
{
//повертає умова для SQL запиту
return $where;
}
public function getItemCount()
{
//кількість для пагінатора
return Document::findCnt($this->getWhere());
}
public function getItems($start, $count, $sortfield = null, $asc = null)
{
//вибирає дані
$docs = Document::find($this->getWhere(), "document_date desc,document_id desc", $count, $start);
return $docs;
}
public function getItem($id)
{
}
}
використовується як звичайне джерело
$this->add(new DataView('list',new DocDataSource(),$this,'listOnRow'))->Reload();
Спадкування сторінок призначене для вирішення проблеми "однаковості" сторінок. Якщо необхідно мати на сайті меню, логотип та інші незмінні від сторінки до сторінки частини, потрібно розмістити їх в базовій сторінці, а змінюваний контент - винести в дочірні. На рівні класів дочірня сторінка просто успадковується від базової наслідуючи всі її компоненти і обробники, на рівні розмітки - вміст тега BODY дочірньої сторінки вкладається всередину базової замість тега <childpage/>.
Якщо в шаблоні дочірньої сторінки в <head> є метатеги <title>,<description> и <keyword>, при рендерингу дочірньої сторінки ці теги будуть перенесені з заміною в базовий шаблон.
Дочірні сторінки мають доступ до всіх компонентів оголошеним у батьківській і
може ними керувати. Наприклад підсвічувати поточний пункт меню.
як приклад - сторінка Base в демо додатку від якої успадковуються інші
Фрагмент сторінки - це самостійний блок, який додається в сторінку як звичайний компонент,
але при цьому має свій шаблон (завантажується аналогічно шаблоном сторінки). Використовується, якщо на
деяких сторінках необхідно мати один і той же блок даних. Наприклад: форма пошуку, блок
виведення реклами і т.д. Фрагмент може містити будь-які інші компоненти і обробники подій
як звичайна сторінка. У розмітку сторінки компонент зазвичай додається за допомогою тега DIV.
Створюється клас фрагмента успадкуванням від класу PageFragment
який в свою чергу спадкує
від HtmlContainer
.
Призначений для користувача компонент дозволяє програмно сформувати довільний вміст для тега
(Як правило DIV). Для створення призначеного для користувача компонента (по суті призначеного для користувача тега) потрібно
створити клас спадкоємець від CustomComponent
і перевантажити абстрактний метод getContent()
.
Цей метод повинен повернути HTML код, який буде записаний в тег в шаблоні сторінки, призначений
для виведення компонента.
Оскільки фреймворк автоматично забезпечує збереження стану сторінки, використання AJAX
в Zippy
менш затребуване в порівнянні з іншими рішеннями. Проте ряд компонентів можуть використовувати асинхронну обробку подій.
Як правило використання AJAX
не потребує будь то особливого кодування і настройки.
Наприклад, для AJAX
обробника onClick()
при натисканні на посилання для компонента ClickLink
потрібно тільки
вказати третій параметр як true. Для відправки форми через AJAX
використовується компонент AjaxSubmitLink
. Обробники події і бізнес логіка сторінки виконуються аналогічно звичайному синхронного.
Також багато компонентів мають можливість оновлюючи на сторінці після AJAX
виклику.
Оскільки звичайний рендеринг всієї сторінки в цьому випадку не виконується,
необхідно вказати оновлювані елементи в обробнику подій (метод сторінки updateAjax()
).
Для цих компонентів (що реалізують інтерфейс AjaxRender
)
формується клієнтський скрипт, який оновлює їх після AJAX
відповіді.
$this->add(new ClickLink('time'))->onClick($this,'OnClick',true);
$this->add(new Label('msg'));
// ...
public function OnClick($sender) {
$this->msg->setText('Я оновлений через AJAX');
//вказуємо оновлювані компоненти
$this->updateAjax('msg');
}
Перемикання змінюваних дизайнів здійснюється шляхом простого перемикання шляху до
файлів в методі getTemplate()
додатка. Наприклад, файли шаблонів сторінки можна
розташувати в різних папках.
Роутінг здійснюється перевантаженням методу Route () додатки (див. Вище приклад для WebApplication).
Функція приймає параметром URI і завантажує сторінку відповідну викликом.
Якщо присутні параметри, вони йдуть через прямий слеш і передаються конструктору сторінки.
Наприклад, для /user/2
конструктор сторінки буде public function __construct($id)
.
Оскільки вміст сторінок вже серіалізуются і зберігається з об'єкті сесії а об'єкт сесії в навантаженому додатках зазвичай закешируваний, то кешування сторінок не вимагає спеціального рішення.
Застосування допоміжного шаблонізатора (використовується Mustache)
не зовсім узгоджується з компонентної архітектурою фреймворка. Але, як показала практика, іноді використання компонентів тільки для виведення
текстів і управління видимістю елементів сторінки виходить кілька громіздким, оскільки дані операції фактично не вимагають
бекенд об'єктів. У цих випадках можна використовувати більш традиційні шаблонизатори.
Дані для шаблонізатора присвоюються масиву _tvars
, члену класа WebPage
.
<label data-label="paynotes" for="paynotes" > Коментар до оплати</label>
<input class="form-control" type="text" zippy="paynotes" >
Якщо поле введення paynotes буде приховано функцією setVisible(false)
лейбл сховається разом з ним.
<a zippy="deleteitem">Видалити ітем </a>
<script>
function check_deleteitem() {
return confirm("Видалити ітем?")
}
</script>
Якщо функція поверне false серверний обробник викликаний не буде.
Бібліотека являє собою набір компонентів побудованих на розширенні
стандартних компонентів фреймворка. Бібліотека не входить в ядро фреймворка і
розташовується в окремому просторі імен ZCL
.
Бібліотека складається з наступних компонентів:
Компонент являє собою реалізацію серверної частини для jquery.ganttview.
Компонент реалізує функціональність найпростішої капчи повністю інкапсуліруя генерацію коду, малюнка, формування посилання на малюнок і, якщо заданий відповідний параметр, асинхронне оновлення капчі по кліку на малюнку.
Для реалізації власного алгоритму досить внаслдувати від компонента і перевизначити метод
OnCode
для генерації коду і / або метод OnImage
для генерації зображення.
Опис методів на сторінці API.
<img>
.
Кілька компонентів для роботи з базами даних. Компоненти базуються на бібліотеці ADODB,
що дозволяє писати код, захищений від sql-ін'єкцій і переносимо між різними типами БД.
(На даний момент основні компоненти роботи з БД виділені в окремий
проект ZDB)
TreeEntity
- клас-спадкоємець Entity
, призначений для роботи з ієрархічно
організованими сутностями. На додаток до функціонала батьківського класу має можливість маніпулювати дочірніми елементами
(Пошук по дереву, видалення, переміщення гілок), будувати дерево для компонента Tree
на основі набору даних з БД. Дані повинні бути організовані
відповідно до алгоритму матеріалізованого шляху.
EntityDataSource
- універсальне джерело даних який реалізує інтерфейс DataSource
,
дозволяє зв'язати сторінкові компоненти табличного і облікового виведення з БД. В параметрах класу задаються ім'я класу-сутності (Entity) і при необхідності
умова для вибірки. Це дозволяє розробнику уникнути створення спеціалізованого джерела для простих лінійних вибірок.
Деякі компоненти, що базуються на Twitter Bootstrap.