PHP фреймворк Zippy


Що таке Zippy?

   Zippy – компонентний, подієво - орієнтований фреймворк на PHP, призначений для швидкої розробки сайтів. Zippy легкий для вивчення, забезпечує повне                         відділення дизайну від логіки, а також                         відділення бізнес-логіки від функцій                         забезпечення життєвого циклу і                         стану елементів сторінки.

Головні особливості

  • Невеликий розмір.
  • Повний відділення дизайну від бізнес-логіки.
  • Використання простору імен для поділу класів і модулів.
  • Компонентна, легко розширюється структура.
  • Інтуїтивно зрозуміла архітектура фреймворка і компонентів (особливо для розробників мають досвід з RAD середовищами типу Delphi, ASP.NET).
  • Автоматичне збереження стану сторінки при перезавантаженні (включаючи дерева).
  • Прозора, яка не потребує додаткового кодування, підтримка Ajax.
  • Російська документація.
  • Бібліотека компонентів ZCL.

   Головна ідея - надати розробнику необхідний набір компонентів, який дозволить                          зосередитися на розробці бізнес-логіки сайту.
   Розробнику немає необхідності працювати з запитами, роутерами,                         чисельнними 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("");

  Зв'язок між класом сторінки і відповідним HTML файлом шаблону задається розробником сайту,                     що дозволяє уникнути жорсткої структури каталогів, а також легко реалізувати змінюваний дизайн                     і / або локалізацію. Життєвий цикл сторінки і навігація між сторінками забезпечується класом WebApplication в залежності від аналізу запитів браузера до сервера.

Життєвий цикл сторінки

При першому відкритті сторінки додаток створює екземпляр класу сторінки. У конструкторі                         сторінки створюються екземпляри всіх компонентів сторінки, виконується Біндінг і призначення обробників                         подій. Потім екземпляр класу сторінки серіалізуются з усім вмістом і записується в сесійне                         сховище. Після цього додаток завантажує HTML шаблон з місця на диску, зазначеного розробником в функції getTemplate, парсить його і викликає метод візуалізації класу сторінки. клас сторінки                         рендерить всі дочірні компоненти. Компонент змінює відповідний йому (пов'язаний через атрибут zippy) HTML тег коректуючи його зміст і / або атрибути. Після рендеринга сторінки додаток відправляє                         змінений HTML код браузеру.

При запиті зі сторінки (наприклад клік по посиланню) додаток десеріалізує екземпляр класу сторінки з сесії і                         знаходить компонент ініціатор запиту (посилання, кнопка і т.д.). Компонент активізує пов'язаний з ним                         призначену для користувача функцію - обробник подій яким зазвичай є метод класу сторінки,                         оскільки це дозволяє мати доступ до всіх компонентів сторінки і таким чином реалізувати всю бізнес                         логіку пов'язану з поведінкою сторінки, обміном даних і т.д. Потім екземпляр сторінки, разом з екземплярами всіх компонентів                         (Зберігають поточний стан даних) зберігається в сесійне сховище, виконується рендеринг і                         відправка відповіді в браузер. Сесійне сховище зберігає історію зміни сторінок що дозволяє                         віддавати сторінку з відповідним "історичним" станом при навігації браузера                         кнопками "вперед" / "назад".

diagram

Основні компоненти

WebApplication

Клас додатки. Виконує розбір 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

створюємо екземпляр програми з параметром класу головної сторінки сайту WebPage. У конструкторі створюються всі компоненти сторінки. Ієрархія компонентів повинна строго                         відповідати вкладеності тегів з атрибутом zippy в шаблоні. Як правило, в класі                         сторінки створюються функції обробників подій, а також реалізується логіка роботи                         сторінки. Примірники компонентів сторінки створюються один раз при першому зверненні до                         сторінки. Відстежувати життєвий цикл сторінки можна перевизначивши методи                          beforeRequestHandle () , afterRequestHandle () та ін.                         
Принцип роботи класу сторінки наподобі класу бекенда в ASP WebForms, або                         десктопних Delphi / WinForms - екземпляр класу сторінки (форми) містить інші елементи як контейнер,                         управляє їх життєвим циклом, обробники                         подій елементів є методами класу сторінки.

HtmlComponent

Базовий клас для всіх компонентів. Кожен компонент має унікальний в межах сторінки номер                         елемента (поле id) , відповідного аттрибута zippy з відповідного тега HTML шаблону. Кожен компонент розширює базовий клас повинен реалізувати метод RenderImpl() який відповідає                         за рендеринг (промальовування) компонента на сторінці шляхом зміни HTML тега пов'язаного з даними                         компонентом. Властивість attributes дозволяє управляти атрибутами HTML тега. Вміст тега задається                         класами нащадками HtmlComponent в залежності від його типу.

HtmlContainer

Базовий клас контейнера для компонентів. Контейнерами є: клас сторінки, класу 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();

Діаграма ієрархії основних компонентів

diagram

Label

LabelВиведення текстових даних на сторінці. Як правило відображається з                         допомогою тега SPAN, але можна використовувати TD, DIV та інші які можуть мати                         текстове вміст всередині тега.

Panel

Panel використовується як контейнер коли треба тимчасово приховати групу елементів.                          Наприклад при редагуванні рядки таблиці приховати таблицю і показати форму редагування.                          Оскільки робота відбувається в межах тієї ж сторінки, зберігаються всі сортування фільтрація і пагінація таблиці.                          Як правило компонент відображається за допомогою тега div, або іншого блочного елемента.

Фреймворк містить кілька різновидів компонентів для HTML посилань.                         Всі вони прив'язуються до Тегу <a> шаблону. Найбільш використовувані:

  • ClickLink - служить для виклику обробника події в класі Сторінки без можливості                              зробити закладку в браузері (оскільки це не має сенсу - посилання не веде на будь-якій                              ресурс, а просто викликає обробник.)
      
      
            public function __construct($params = null) {
                    
                $this->add(new ClickLink('onmsg'))->onClick( $this, 'OnClick');
            }
            // Оброблювач  
            public function OnClick($sender) {
                     
            }
    }
                
  • BookmarkableLink - використовується для зовнішнього переходу, або ЧПУ з можливістю створити закладку. Для вказівки адреси сторінки вказується ім'я класу сторінки з прямими слешом
    /?p=Pages/Page1
    Можуть бути вказані один або кілька (через прямий слеш) параметрів
    /?p=Pages/Page1&arg=1
  • 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

Основне призначення компонента 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 і обробник в якому будуть створюватися компоненти виведення.
Рядок даних - звичайний контейнер, який базується на тезі <tr>. Додавати можна будь-які компоненти (крім вкладених DataView). DataView сам розмножить компоненти даних для кожного рядка
При необхідності можна додати пагінатор 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

Компонент 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

Оскільки фреймворк автоматично забезпечує збереження стану сторінки, використання 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() додатка. Наприклад, файли шаблонів сторінки можна                         розташувати в різних папках.

ЧПУ (SEF) і роутінг

Роутінг здійснюється перевантаженням методу Route () додатки (див. Вище приклад для WebApplication).                         Функція приймає параметром URI і завантажує сторінку відповідну викликом. Якщо присутні параметри, вони йдуть через прямий слеш і передаються конструктору сторінки. Наприклад, для /user/2 конструктор сторінки буде public function __construct($id).

Кешування

Оскільки вміст сторінок вже серіалізуются і зберігається з об'єкті сесії а об'єкт сесії в навантаженому                         додатках зазвичай закешируваний, то кешування сторінок не вимагає спеціального рішення.

Допоміжний шаблонизатор

Застосування допоміжного шаблонізатора (використовується Mustache) не зовсім узгоджується з компонентної архітектурою фреймворка. Але, як показала практика, іноді використання компонентів тільки для виведення                         текстів і управління видимістю елементів сторінки виходить кілька громіздким, оскільки дані операції фактично не вимагають                         бекенд об'єктів. У цих випадках можна використовувати більш традиційні шаблонизатори. Дані для шаблонізатора присвоюються масиву _tvars, члену класа WebPage.

Поради та рішення типових задач

Приховування пов'язаних елементів.

Якщо потрібно приховати наприклад лейбл разом з елементом введення,                         можна використовувати атрибут "data-label" наприклад

                        <label data-label="paynotes" for="paynotes" > Коментар до оплати</label>
                       <input class="form-control" type="text" zippy="paynotes" >
               
                         
Якщо поле введення paynotes буде приховано функцією setVisible(false) лейбл сховається разом з ним.

Перехід по якорям.

Для переходу в певне місце сторінки після обробітку події                          можна використовувати метод goAnkor () класу сторінки. Параметром є id елемента,                          або атрибут zippy (атрибути id і name створюються в такому випадку автоматично)

Перехоплення подій яваскрипта на елементах з серверним обробником.

Коли елемент має серверний обробник зазвичай на подію onclick фреймворк вішає відповідний клієнтський обробник.                          Припустимо потрібно виконати код на клієнті до того як спрацює серверний обробник. Наприклад спросіть користувача підтвердження дії. Наприклад є посилання <a zippy="deleteitem">Видалити ітем </a>
для перехоплення потрібно написати функцію з визначеним ім'ям починається з check_

                      <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 компоненти

Деякі компоненти, що базуються на Twitter Bootstrap.