Šablonovací systém PHP_JUI - Úvod

PHP Ostatní Šablonovací systém PHP_JUI - Úvod

Zdravím,

jednoho dlouhého dne jsem se asi doopravdy nudil a proto jsem začal přemýšlet o vlastním šablonovacím systému pro PHP. Jako asi každý programátor v PHP jednou dojdete k okamžiku, kdy se vám doopravdy nelíbi nepřehledná kombinace PHP a HTML kódu. Jak by řekl můj učitel algoritmizace: "Je to prasácké!". A jelikož jsem zrovna v té chvíli zjistil, že mám JSON radši než XML, rozhodl jsem se, že bude JSON "based" (jen tak mimochodem, pokud někdo napíše XmlSerializer a hodí ho do parseru místo JsonSerializeru, není problém ani s XMLkem).

Došel jsem až tak daleko, že při použití tohoto systému nenapíšete ani kousek HTML kódu! Jediné, co budete psát, jsou JSON definice (říkám jim prostě JUI - ano JSON (based) User Intarface). Toto je takový vzor:

{
        "com": "Nazev_komponenty",
        "param1": "hodnota",
        "param2": [
                "polozka 1",
                 "polozka 2"
        ],
        "param3": {
                "asociativni": "pole"
        },
        "param4": {
                "com": "Dalsi_componenta"
        }
}

Pokaždé musí byt nadefinovano o jakou komponentu se jedná (klíč "com") a poté následují volitelné parametry, které mohou obsahovat - text, číslo, pole, componentu, objekt.

Instalace a zprovoznení JUI

Jelikož JUI používá namespace a callbacky, je potřeba mít PHP minimálně ve verzi 5.3.

Na konci článku najdete odkaz na repozitář JUI, stáhněte zdrojové kódy. Po té můžete udělat dvě věci: 1) zkopírovat rozbalené zdrojáky někam do htdocs a spustit. 2) nebo si do svého projektu nakopírujte složku JUI a Resources (obě složky do stejného adresáře), to jsou jedinné povinné složky. JUI nemá definovanou povinnou složku se šablonami, ani jejich příponu (alespoň ne v této verzi), proto umístění šablon a jejich přípona (já používám .json) je čistě ve vaší režii. A stačí jen upravit soubor index.php, nebo si napsat svůj, tak aby zpracoval jaký sobor chcete. Nyní Vám ukáži, jak JUI "rozběhnout".

Vytvoříme si první HTML stránku. A uložíme ji jako "Views/index.json".

{
    "com" : "Page",
    "title": "My first JUI page!",
    "meta" : [
        {"http-equiv" : "Content-Type", "content" : "text/html; charset=UTF-8"}
    ],
    "content": {
        "com": "H1",
        "content": "Hello world!"
    }
}

Váš index.php bude vypadat takto:

<?php
//Includujeme soubor ze slozky JUI/Jui.php
require_once "./JUI/Jui.php";

//vytvoříme instanci parseru
$parser = new JUI\Engine\Parser();

//přidáme do něj JsonSerializer (ten se v souboru JUI/Jui.php vkládá i do Resources)
$parser->setSerializer(new JUI\Engine\JsonSerializer());

//a zparsujeme náš vytvořený soubor. Vrátí komponentu Page
$index = $parser->parse(file_get_contents("Views/index.json"));

//nyní vše vyrenderujeme
echo $index->render();
?>

Stejný kód je i v souboru index.php ve stáhnutých zdrojácích. Používám autoloader, pokud chcete používat svůj, stačí zeditovat sobubor JUI/Jui.php a zakomentovat vkládání autoloaderu, myslím, že to tam určitě najdete:)

JUI bude chvíli kouzlit a máme tu HTML:

<html>
        <head>
                <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                <title>My first JUI page!</title>
        </head>
        <body>
                <h1>Hello world!</h1>
        </body>
</html>

Vlastnosti

Nyní by bylo dobré zmínit některé vlastnosti (přednosti?) JUI:

  • Jednoduché na naučení i vytváření vlastních komponent
  • Podporuje data modely, zatím mám implementovaný Json data model a PDO data model (takže přístup do databáze přímo z Json zápisu, stačí jen nadefinovat query, a v resources mít komponentu, která bude reprezentovat připojení do databáze a implementované interface JUI\Components\I­Connection a vracet instanci třídy PDO, ale o tom až jidny:)
  • Jak už bylo výše zmíněno, máme i Resources, takové registry, které jsou přístupné každé komponentě
  • Data binding
  • Converters (každý Binding může mít svého "konvertera", který upraví data před tím, než je předá kompontě. Dále je podpora konverterů v komponentě Text)
  • Je ho možné vytvářet pomocí JSON zápisů(definic..) či přímo v PHP kódu
  • Podpora Parital šablon
  • Container template - obaluje komponentu
  • Content template - obaluje data (například šablona pro položku v ListBoxu, naimplementován jen v ListBoxu, jinde zatím není potřeba)
  • Existují komponenty, které zastupují každý HTML tag. Plus specializované jako třeba ListBox, který podporuje data modely, a provádí autobinding dat do šablony atp.:)
  • Pokud Vám to trochu připomíná xaml, něco na tom bude :D

Doufám, že jsem Vás alespoň trochu navnadil a budete mít zájem pokračovat ve čtení tohoto článku:)

Ukázka použití JUI

Řekl bych, že je na čase ukázat složitější příklad. Ukáži Vám jak vypsat seznam jmen uživatelů z databáze, bez jediného řáku PHP kódu!

Nejprve je nutné mít nadefinované připojení do databáze v Resources:

//resources mají speciální syntaxi
{
        "dbPripojeni": {
                "type": "com",
                "val": {
                        "com": "PdoConnection",
                        "host": "localhost",
                        "user": "root",
                        "pass": "root",
                        "dbname": "test",
                        "dbtype": "mysql"
                }
        }
}

Nyní máme nadefinováno připojení do databáze pomocí komponenty PdoConnection. A teď se vrhene na vytvoření šablony pro seznam uživatelů:

(soubor: listBox.json)

{
        "com": "Ul", //tag <ul>
        "content": {
                "com": "Binding",
                "key": "containerContent" //sem se nabindují vyrenderované položky
        }
}

Nadefinujeme šablonu, která se použije na každou položku z ListBoxu:

(soubor: item.json)

{
        "com": "Li", //tag <li>
        "content": {
                "com": "Binding",
                "key": "user_name"
        }
}

Spojíme všechny části dohromady:

{
        "com": "ListBox",
        "dataModel": {
                "com": "PdoDataModel",
                "connection": "dbPripojeni",
                "query": "SELECT * FROM users"
        },
        "containerTemplate": {
                "com": "Partial",
                "file": "listBox.json"
        },
        "contentTemplate": {
                "com": "Partial",
                "file": "item.json"
        }
}

Pokud máte v databázi pod klíčem "user_name" jméno uživatele výstup by měl být podobný tomuto:

<ul>
        <li>Pepa</li>
        <li>Jirina</li>
        .
        .
        .
</ul>

Ještě něco k parametrům containerTemplate a contentTemplate. Nemusejí to být Partial componenty. Je možno do nich zapsat šablonu přímo, ale pokud si dáte šablony zvlášť do souborů, budete je moct používat na více místech a to je k nezaplacení, teda pokud nemáte radši copy-paste metodu :D

Možná se Vám tento zápis může zdát zdlouhavý, ale vyhnuli jste se tomuto:

<?php
$db = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

$prepared = $db->prepare("SELECT * FROM users");
$prepared->execute();

echo "<li>";
forach($row as $db->fetchAll()){
        echo "<ul>" . $row["user_name"] . "</ul>";
}
echo "</li>";
?>

Výhody:

  • Nekombinujete PHP a HTML
  • Máte znovupoužitelné šablony
  • Větší přehlednost
  • Jednoduchá změna vzhledu
  • Můžete jednoduše změnit umístění dat (změnou data modelu), bez zasahování do kódu!

Myslím si, že jako úvod do PHP_JUI tento článek stačí. Byl bych rád, kdybyste mi napsali do komentářů, zda-li máte zájem o další díly.

Zde je odkaz na JUI repozitář: PHP_JUI - Repozitář + wiki


 

  Aktivity (1)

Článek pro vás napsal jakub.kuritka
Avatar
...

Jak se ti líbí článek?
Celkem (4 hlasů) :
4.754.754.754.754.75


 



 

 

Komentáře

Avatar
samo007
Redaktor
Avatar
samo007:

Pekné, len neviem ako to všeobecne funguje. Akú koncovku majú súbory obsahovať a kde tie súbory mám umiestniť? Netreba k tomu niečo inštalovať?

Jednoducho mi tam chýba úvod o týchto veciach

 
Odpovědět 7.10.2012 15:26
Avatar
Kit
Redaktor
Avatar
Kit:

Zajímavé. Něco podobného jsem kdysi vyrobil ve formátu YAML. JSON má však výhodu v tom, že je přímo podporován v PHP. Není tedy nutné přidávat další parser.

Asi bych do JSON nedával "meta http-equiv" a podobné fráze, ale dal bych to přímo do PHP_JUI. Frameworky se dělají proto, aby nás osvobodily od rutinních záležitostí a zrovna tohle mezi ně patří. Podobně dávám do svého frameworku "natvrdo" odkaz na "style.css", protože jiný soubor s CSS nepoužívám.

Pokud bys zvládl udělat konvertor JSON - DOM, tak by se ta šablona dala udělat ve standardním šablonovacím systému XSLT, který je součástí PHP.

Odpovědět 7.10.2012 16:29
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
Kit
Redaktor
Avatar
Odpovídá na Kit
Kit:

Pro ilustraci uvádím text, který po zpracování YAML -> JSON vytvoří stejný výsledek, jako ve tvém příkladu. Můžeš si to ověřit třeba na
http://yaml-online-parser.appspot.com/

com: listbox
dataModel:
   com: PdoDataModel
   connection: dbPripojeni
   query: SELECT * FROM users
containerTemplate:
   com: Partial
   file: listBox.json
contentTemplate:
   com: Partial
   file: item.json
Odpovědět 7.10.2012 17:27
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
jakub.kuritka
Redaktor
Avatar
Odpovídá na Kit
jakub.kuritka:

Zdravím,

PHP_JUI není framework, je to jen šablonovací systém a proto tam nechci dávat nic natvrdo. Je to psáno tak, aby se to dalo použít snad kdekoliv. Teda doufám:) Není problém dědit od komponenty Page, přidat si tam své věci, třeba aby byl "style.css" automaticky vkládán. Tohle už je na uživateli. Chci aby to bylo co nejvíce "generické".

 
Odpovědět 8.10.2012 8:35
Avatar
jakub.kuritka
Redaktor
Avatar
Odpovídá na samo007
jakub.kuritka:

Na to jsem úplně zapomněl, už je to doplněno do článku a po schválení by se to mělo zobrazit (sekce Instalace a zprovoznění JUI)

 
Odpovědět 8.10.2012 8:36
Avatar
Kit
Redaktor
Avatar
Odpovídá na jakub.kuritka
Kit:

Je to framework. To mi nevymluvíš. Potřebuješ to udělat tak, abys tomu tvému šablonovacímu systému dodával jen skutečná data a nemusel se zabývat metadaty. Pokud to chceš dělat obecně, tak ti to nebude sloužit dobře.

Samotná myšlenka použití JSON je správná. Formát XML by byl obecnější a YAML stručnější.

Odpovědět 8.10.2012 10:00
Vlastnosti objektů by neměly být veřejné. A to ani prostřednictvím getterů/setterů.
Avatar
jakub.kuritka
Redaktor
Avatar
jakub.kuritka:

Přidal jsem podporu Yaml zápisu, během dneska se to projeví v repozitáři a přemýšlím, že bych JSON nahradil YAMLem, ten zápis je přehlednější a kratší.

 
Odpovědět 8.10.2012 10:09
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 7 zpráv z 7.