Na navigaci | Klávesové zkratky

Nette\Utils\Html – pomocník PHP kodéra

Malá knihovna pro generování (X)HTML kódu v PHP.

Download

Upozornění: Knihovna Nette\Utils\Html se neustále vyvíjí. Aktuální informace najdete na webu Nette Framework. Popis v tomto článku postupně aktualizuji, takže některé komentáře pod ním mohou být již nesouvisející.

Způsobů, jak v PHP vygenerovat kód stránky, je celá řada. Od obyčejného volání příkazu echo, přes použití šablon, až po funkce DOM. Hledání nejlepší metody vede k paradoxu. Čím je programátor zkušenější, tím více tíhne k čistějším řešením, ideálně na bázi XML DOM. Tím však začne narážet na nové překážky a omezení a více času tráví jejich řešením a obcházením. Díky čemuž více tíhne k pragmatickým řešením, jako je třeba volání echo.

Ale posuzování vhodnosti jednotlivých způsobů není předmětem článku.

Seznamte se s Nette\Utils\Html (dříve NHtml)

Generování HTML značek „na koleně“ vede k nepřehlednému kódu a tím i k větší náchylnosti k chybám. Vezměme si jednoduchý příklad:

echo '<select name="person"',
	($required ? ' class="required"' : ''), '>';
$res = dibi::query('SELECT * FROM [persons] WHERE [group]=%s', $group);
while ($rec = $res->fetch())
	echo '<option value="', $rec['id'], '"',
		($active == $rec['id'] ? ' selected="selected"' : ''),
		'>', htmlSpecialChars($rec['name']),
		'</option>';

echo '</select>';

Nic moc, že? Zápis lze značně zpřehlednit za použití Nette\Utils\Html pomocníka. Jde o malou knihovničku, která má za úkol objektově zapouzdřit HTML elementy a především nabídnout programátorovi intuitivní a šikovné rozhraní.

Nejprve malá ochutnávka:

// vytvoříme element
$el = Html::el('img');
// včetně jmenného prostoru $el = Nette\Utils\Html::el('img');

// nastavíme atributy
$el->src = 'image.gif';
$el->alt = $text;

// a vypíšeme ho
echo $el; // <img src="image.gif" alt="..." />

// Html::$xhtml = false; vypne XHTML režim

Atributy lze nastavovat i voláním přetížených metod, například $el->src('image.gif'). Zde lze s výhodou využít řetězovitého volání (fluent interfaces):

$params['id'] = 10;
echo Html::el('a')->href('http://www.dgx.cz', $params)->setText('Klikněte');
// vypíše <a href="http://www.dgx.cz?id=10">Klikněte</a>

echo Html::el('img')->src($url)->alt($alt);

echo Html::el('input')->type($secret ? 'password' : 'text');

Atributem však nemusí být jen řetězec:

$el = Html::el('input')->type('checkbox');
$el->checked = true;  // <input type="checkbox" checked="checked" />
$el->checked = false; // <input type="checkbox" />

// atribut zrušíme hodnotou null
$el->type = null;	// <input />

// lze použít dokonce pole
$el->class[] = $active ? 'active' : null; // null se ignoruje
$el->class[] = 'top';

$el->style['color'] = 'green';
$el->style['display'] = 'block';

echo $el;
// <input class="active top" style="color: green; display: block" />

Někdy dávám přednost samostatnému vypsání počáteční a koncové značky namísto celého elementu:

$el = Html::el('div');
echo $el->startTag();
...
... nyní vypisujeme obsah
...
echo $el->endTag();

// nebo obsah rovnou nastavíme elementu
$el->setText('Barnes & Noble');
echo $el; // <div>Barnes &amp; Noble</div>

// volitelným parametrem je možné indikovat HTML kód
$el->setText('Barnes &amp; Noble', true);
echo $el; // <div>Barnes &amp; Noble</div>

Děti a vnoučata

Rodina je základ HTML státu a proto i každý uzel Nette\Utils\Html může mít své potomky:

$el = Html::el();
// (všimněte si, $el je nyní "kontejner", tj. bez názvu elementu)

// a vytvoříme potomka, element strong
$strong = $el->create('strong');
$strong->setText('La Trine');
// nebo lze psát rovnou:
// $el->create('strong', 'La Trine');

// lze přidávat existující uzly Html
$br = Html::el('br');
$el->add($br);

echo $el; //  <strong>La Trine</strong><br />

// uzel může být i textový
$el->add('Yes!'); // obdoba setText

// k potomkům lze přistupovat přímo přes ArrayAccess
$el[] = 'Hello!';

if ($el->count()) ...

A zpět k příkladu

Nakonec přepíši úvodní příklad do přehlednější formy pomocí Nette\Utils\Html:

$el = Html::el('select')->name('person')->class($required ? 'required' : null)

$res = dibi::query('SELECT * FROM [persons] WHERE [group]=%s', $group);
while ($rec = $res->fetch())
	$el->create('option')
		->value($rec['id'])
		->selected($active == $rec['id'])
		->setText($rec['name']);

echo $el;

poznámka: Html uvádím jako předskokana knihovny Nette\Forms, která slouží ke snadné tvorbě a obsluze webových formulářů. A právě Nette\Utils\Html používá pro generování kódu. Takže tak.

Komentáře

  1. Sitnarf #1

    avatar

    Hezké, asi vylepším svoje prasácké programování.

    před 17 lety
  2. ivan_d #2

    Mám podobnou tendenci – nemíchat php a html. Mám opačnou tendenci – vynechat php.

    před 17 lety | reagoval [10] ivan_d
  3. zirafka #3

    avatar

    cekala jsem dneska spis spot o googleni, ale tohle je taky dobry (-;

    ne fakt, vypada to dost dobre!

    před 17 lety | reagoval [11] David Grudl [48] Roj
  4. Peter p360t Kováč #4

    avatar

    a myslíš, že by sa to dalo použiť ako plnohodnotná náhrada Smarty a pod.?

    před 17 lety | reagoval [6] afu [11] David Grudl [50] miso
  5. piler #5

    pekne, pekne…ale co oddelenie aplikacnej logiky od prezentacnej?

    před 17 lety | reagoval [7] ivan_d [11] David Grudl
  6. afu #6

    avatar

    #4 Petere p360te Kováči, smarty je hodně pokročilý šablonovací systém, nhtml bych s nimi moc nerovnával, natož mluvil o plnohodnotné náhradě. třebaže je nhtml počin zajímavý, já osobně pro něj v současnosti využití nemám.

    před 17 lety | reagoval [9] piler
  7. ivan_d #7

    #5 pilere, Reálná aplikace je něco jiného než ukázka knihovny. Navíc nikde ani v příkladech nevidím zřejmé míchání aplikační logiky a prezentační – prezentace přece musí od někud číst, ne?

    před 17 lety | reagoval [8] piler
  8. piler #8

    #7 ivan_de, priklad to je a to ci sa to odniekadial cita, este neznamena ze si oddelil prezentacnu logiku o aplikacnej. Ked pracuju viaceri na jednom projekte, tak by mali byt tieto casti oddelene..PHP by malo citat HTML sablony…a nie generovat HTML…

    před 17 lety | reagoval [10] ivan_d
  9. piler #9

    #6 afu, ja som si tiez zacal tvorit formularovy framework a miesal som html z php, tak som sa rozhodol ze to prerobim cez sablony, pretoze je to balast kodu, ktory nie je mozne modifikovat, bez zasahu do PHP a to uz nie je dobre. Inak smarty vyuzivam ako main system pre svoje projekty a som velmi spokojny, aj ked uz tam je to oddelenie logiky na vazkach…

    před 17 lety
  10. ivan_d #10

    #8 pilere, PHP by malo citat HTML sablony…a nie generovat HTML…
    By mělo? To přece záleží na více faktorech – velikost a účel projektu, pravidla daného týmu nebo jednotlivce… Osobně taky upřednostňuji (pseudo)html #2 ivan_d, ale není to absolutní, jediný a hlavně VŽDY správný postup. Nebo se mýlím?

    před 17 lety
  11. David Grudl #11

    avatar

    #4 Petere p360te Kováči, používám to ve spojení se šablonovacím systémem, lze si tak připravit HTML elementy, které v šabloně umístím (zjednodušeně řečeno). Tedy jde o součást jiného šablonovacího systému. Nicméně, za plnohodnotnou náhradu Smarty v 99 % případů považuju třeba tohle, zkrátka je věc názoru :)

    #5 pilere, chceš tím říct, že jsem měl v příkladech umístit $res = dibi::query(...) do odděleného „chlívečku“? No, to by hodně pomohlo srozumitelnosti…

    #3 zirafko, Já to nemůžu Rojovi udělat. Sice je fakt, že už nikdy to nebude jako dřív, ale fakt ho tím nechci zatěžovat.

  12. piler #12

    #11 Davide Grudle, vies co som chcel asi povedat tym oddelenim aplikacnej a prezentacnej logiky…

    proste moj nazor je taky, ze html sablony by mali byt osobitne subory, ktore PHP nacita, preparsuje zastupne znacky a vypluje na screen…

    To mi pride velmi prehladne, pretoze aj clovek neznaly PHP, vie tieto sablony modifikovat..

    Co sa tyka NHtml, syntax je super, pripomina mi to jednu triedu na generovanie xml dokumentov, ale v jednoduchosti je krasa, nie? ?

    Je to urcite prehladnejsie ako ten 1. priklad, ale som proste zvyknuty uz na nieco ine..

    před 17 lety | reagoval [13] David Grudl [16] error414
  13. David Grudl #13

    avatar

    #12 pilere, no já právě nerozumím, co jsi tím chtěl říct. To, co vidíš v příkladech, je čistě prezentační logika, a řekněme že dibi::query je napovážovou. Ale šablony jsou něco docela jiného. Ano, mohu používat šablony, rád je používám, ale pak je prezentační logikou i celý šablonovací systém. V případě Smarty jde třeba o několik set kilobajtů PHP kódu. A šablona je jen součástí, konfigurákem, pro určitý typ prezentační logiky.

    před 17 lety | reagoval [14] ivan_d
  14. ivan_d #14

    #13 Davide Grudle, Zcela souhlasím. A nemyslím si že je dibi::query na pováženou. Pokud má mezivrstva význam, pak má být, pokud POUZE komplikuje kód, tak je mezivrstva ke škodě.

    Myslím, že všechny MVC a spol. vznikali kvůli tomu, aby pomohli (urychlit vývoj, udržovat aplikaci atd.). Pokud dělají opačné věci, něco tam nehraje.

    před 17 lety
  15. Štěpán Svoboda #15

    avatar

    Vypadá to velice užitečně :) Sám používám Smarty na většinu projektů (těch větších (tj. jeden)) na „mini-aplikace“ nepoužívám žádné šablony neb je to kontraproduktivní. A právě při použití původního přístupu tj.:

    if ($jelen == true) {
    
    echo "<p>Jelonovi pivo nelej</p>";
    
    }

    …mi tohle přijde jako super pomocník… Jsem zvědav na NForms – btw imho je název NForms velice obyčejný :)

    PS: Chtěl jsem se optat na něco také:

    $el = NHtml::el('img');
    $el->src = 'image.gif';
    $el->alt = $text;
    $el->onclick = 'vyprsknout_smichy';

    A jak by to bylo pokud chci použít funkci s parametrem?

    před 17 lety | reagoval [16] error414 [19] LokoN
  16. error414 #16

    #15 Štěpáne Svobodo,

    $el->onclick = 'vyprsknout_smichy(\'parametr\')';

    strilim od boku, mozna na to ma specialni ficuru. Ale v jednoduchosti je sila ne?

    #12 pilere,
    PHP samo je sablonovaci system, s jednoduchym sriptovanim
    PHP plnohodnotny scriptovaci jazyk.

    Zalezi na uhlu pohledu. Kazdy at si pouziva to PHP co zrovna potrebuje.

    před 17 lety
  17. tark #17

    avatar

    A neslo by to uz vypustit cele? Clovek se vzdycky dovi neco… ;) BTW, jaka je licence?

    před 17 lety | reagoval [18] error414 [30] David Grudl
  18. error414 #18

    #17 tarku, trochu namohy hosi

    před 17 lety | reagoval [26] tark
  19. LokoN #19

    #15 Štěpáne Svobodo, Javascriptové události navěšuj javascriptem a je to.

    před 17 lety
  20. johno #20

    avatar

    DGX: Mne sa to páči. K zdrojáku snáď len malé výhrady.

    1. Zoznam empty elementov by som dal do public static $emptyTags alebo aspoň vyňal do metódy.
    2. htmlspecialchars() default charset zo zásady na UTF-8.
    před 17 lety | reagoval [30] David Grudl [45] llook
  21. koolazz@koolazz.com #21

    zlaté xml a xslt :)

    před 17 lety
  22. Radek Hulán #22

    avatar

    Pěkně napsané a moc užitečné ?

    PS: také máš takový pocit, že po pár „flame“ článcích by mělo přijít něco užitečného, a proto jej publikuješ? ?

    před 17 lety | reagoval [47] Keff
  23. afu #23

    avatar

    #11 Davide Grudle, >>Nicméně, za plnohodnotnou náhradu Smarty v 99 % případů považuju třeba tohle, zkrátka je věc názoru :)

    šimpanz má s člověkem společných 99% genů, takže je vlastně taky jeho plnohodnotnou náhražkou :)

    před 17 lety | reagoval [24] Thomas [25] johno
  24. Thomas #24

    avatar

    #23 afu, Proč ne ? záleží na úhlu pohledu, navíc je otázkou zda působení člověka na této planetě lze nazvat jakkoliv prospěšným (jako je to v případě Smarty v PHP) a tedy zda je vůbec nutné pro něco tak zbytného hledat plnohodnotnou náhradu, kdyby se to náhle rozhodlo vypařit ?. Vždyť i do společného přírodního rozpočtu zvaného „potravní řetězec“ už člověk nepřizpívá a jen z něj těží, tak komu by vlatně takový leecher chyběl ?

    před 17 lety | reagoval [25] johno
  25. johno #25

    avatar

    #23 afu, #24 Thomas Myslím, že flame PHP vs Smarty tu už zopár krát bol. Tak to urýchlime, hej? Každý nech si používa to, čo mu vyhovuje.

    před 17 lety
  26. tark #26

    avatar

    #18 error414, Sorry, website Nette is under construction :P

    před 17 lety
  27. Arthur Dent #27

    [smazáno] Mám něco podobného ve svém FW, inspirováno nedávnou debatou o formulářích. Jen tam nes*ru objekty, ale nechávám to v poli. FW se pak postará o vytvoření formuláře, o správné naAJAXování, o vhodné umístění polí Description či Example a o vložení kódu na kontrolu hodnot. Stejný popis struktury používá druhá funkce na vyzvednutí hodnot z POSTu, takže mi stačí popsat jednou definicí formulář a druhou přiřadit jeho políčka k datovým zdrojům, o zbytek se postará framework. A kdyby se chtěl někdo inspirovat, tak ochutnávka:

    $form_author=array(
     'name'=>'author',
     'title'=>'O autorovi',
     'fields'=>array(
          'name'=>array(
              'type'=>'text',
              'label'=>'Jméno',
              'required'=>'nonempty',
              'description'=>'Zadejte jméno'
              ),
          'mail'=>array(
              'type'=>'text',
              'required'=>'mail',
              'label'=>'E-mail',
              'description'=>'Zadejte e-mail',
              'example'=>'vase-jmeno@domena.cz'
              ),
          'heslo1'=>array(
              'type'=>'text',
              'label'=>'Heslo',
              'pattern'=>'^\S{5,}',
              'description'=>'Zadejte heslo,
                               minimálně 5 znaků'
              ),
          'heslo2'=>array(
              'type'=>'text',
              'label'=>'Heslo znovu',
              'pattern'=>'=heslo1',
              'description'=>'Zadejte totéž heslo ještě jednou'
              )
          ), //fields
    
      'actions'=>array(
          'submit'=>array(
              'type'=>'ajaxsubmit',
              'method'=>'update',
              'imgalt'=>'Opravit',
              'img'=>'./pics/ok.gif',
              'description'=>'Kliknutím potvrdíte změny.',
              'check'=>'1'
              )
          )
      );

    Programátoři pochopí a mohou se inspirovat, ostatním je to na pendrek, i kdybych to vysvětlil :)

  28. johno #28

    avatar

    #27 Arthure Dente, Ty vole Arthure, ty už reaguješ na ten článok o NForms?

    před 17 lety | reagoval [29] Arthur Dent
  29. Arthur Dent #29

    #28 johno, Inspiraci se meze nekladou :) Kdo chce NForms, použije NForms, kdo chce něco na Míru, udělá si svoje a může se inspirovat (já kód z mnohokrát opakovaných důvodů zveřejňovat nebudu, takže je to opravdu jen pro inspiraci).

    před 17 lety
  30. David Grudl #30

    avatar
    [smazáno] tato třída je na mně hodně atypická. Používají se nedefinované proměnné (obvykle na to mívám zavěšený hnusný fatal error) a z technických důvodů i podtržítka. Abych mohl v metodě startTag() odlišit private od public. Jen proto.

    Čisté řešení by bylo přes overloading, ale to je mrcha, velké nedochůdče PHP. S přístupem k proměnným jakožto polím by bylo hodně komplikací.

    #17 tarku, zatím na to nemám sílu ani chuť. Obojí postupně sbírám ?

    #20 johno, áá, tak jsi byl s vysvětlením rychlejší ;) ale ještě k tomu charset: vůbec mi nedochází, co změna této hodnoty ovlivní, nasměruj mě prosím.

    #27 Arthure Dente, u NForms vypadá konfigurace asi takto:

    $form = new NForm;
    $form->addText('name', 'Jméno:');
    $form->addPassword('password', 'Heslo:', 20, 10);
    $form->addSubmit('submit', 'Odeslat');
    $form->addRule('name', 'filled', 'Zadejte prosm Vaše jméno');
    
    // a pak
    if ($form->isSubmitted()) {
       ...
    }

    Zajímavé jsou zejména ty validační pravidla, která pracují jak na straně serveru, tak i na straně klienta vygenerují příslušný javascript. Podobně jako u NHtml, jde o malinkou knihovnu, prostě „malej ale šikovnej“ ?

  31. Radek Hulán #31

    avatar

    #30 Davide Grudle, zajímavé, je tam podporován i fieldset, popřípadě table pro formátování?

    před 17 lety | reagoval [33] David Grudl
  32. sway #32

    avatar

    Hmm, to vypada moc sikovne:) Uz se tesim na NForms…ikdyz timhle bych se mohl taky nekde v nejakem projektu inspirovat, ne-li to pouzit:) Diky, dgx

    před 17 lety
  33. David Grudl #33

    avatar

    #31 Radku Huláne, formátování lze propojit s libovolnou šablonou, zkrátka jsem chtěl odbourat všechna omezení, aby výsledný kód byl přesně podle potřeb, a ne určený knihovnou.

    Ale to už fakt komentujeme příští článek ?

    před 17 lety | reagoval [34] johno
  34. johno #34

    avatar

    #30 Davide Grudle, Niekde som čítal, že to bez toho parametra môže domrviť niektoré UTF-8 znaky. Odporúčali to tam proste explicitne uviesť. Nejako hlbšie som to neskúmal.

    #33 Davide Grudle, Ja budem komentovať NForms až v tom buducom článku, dobre?

    před 17 lety | reagoval [35] David Grudl [35] David Grudl
  35. David Grudl #35

    avatar

    #34 johno, htmlSpecialChars je záměna čtyř (pěti) znaků v rozsahu ASCII za jiné znaky v rozsahu ASCII. Tady nemá jak vzniknout problém, až už je kódování jakékoliv jednobajtové nebo UTF-8. Problém by byl až s UTF-16 & spol., což zase na webu „nelze“ používat, že.

    #34 johno, ad komentování: jo, to bude nejlepší ?

    poznámka: v komentářích lze používat:

    htmlSpecialChars:[php]
    "la trine":[google]
    před 17 lety
  36. Arthur Dent #36

    K #30 David Grudl – kdo uhodne, proč jsem zvolil pole a nikoli objekt, dostane bod. :)

    před 17 lety
  37. Marek #37

    avatar

    #27 Arthure Dente, [smazáno] pardon, tady jsme si asi nerozuměli … já boha hulána neurážím, račte si prosím přečíst jeho desatero kterak díky tupému davu získat navštěvovaný blog . pouze jsem vypíchl hlavní body z tohoto desatera …

    https://web.archive.org/…ovany-weblog

    pozastavil jsem se pouze nad tím, s jakou samozřejmostí podobnou bezpáteřní náturu očekává ten člověk i u ostatních blogerů, to je celé …

    před 17 lety | reagoval [39] Arthur Dent
  38. numero #38

    avatar

    Velice dobré. Proč to nazýváš nhtml, proč ne dgxhtml? Teď budu muset svoje knihovny přejmenovat na num_jmeno :)

    před 17 lety
  39. Arthur Dent #39

    #37 Marku, „také máš takový pocit, že po pár „flame“ článcích by mělo přijít něco užitečného, a proto jej publikuješ?“ je očekávání bezpáteřní nátury? Svatá prostoto!

    před 17 lety
  40. finc #40

    Pěkné, něco podobného řeším také. Sám jsem si napsal několik tříd na generování HTML. Sice může spoustu lidí namítat, že je to míchání aplikační a prezentační logiky, ale pokud člověk dělá např. intranetový systém, grafik či html kodér zde nemají místo.
    Navíc, takovéto uspořádání je extrémně rychlé při programování. Psát znovu a znovu html kod je podlě mě větší prasárna (alespoň v zájmu intranetového systému).
    Jinak, mám definované i vlastní třídy pro vytváření tabulek:

    1. data tabulky ⇒ model tabulky
    2. vlastnosti tabulky

    Díky tomu jsem schopný dané objekty odeslat buď do html, pdf či xls.

    před 17 lety
  41. Havran #41

    avatar

    #27 Arthure Dente, Niečo podobné má v sebe aj (WEB)CMS DRUPAL – viď Forms API Quickstart Guide

    před 17 lety
  42. zirafka #42

    avatar

    #11 Davide Grudle, Jeste ze Roj ty Tvoje clanky o PHP necte. Myslim, ze by z tech narazek byl zbytecne vystresovany.

    před 17 lety
  43. noname #43

    Mně se to také celkem líbí, možná bych jen ještě uvítal nějakou jednoduchou možnost pro „internacionalizaci“, tj. aby to umělo všechny vkládané statické texty vytáhnout a nějak přes asi gettext (ngettext) umožnit překlad, aniž bych musel každý text uzavírat do nějaké _() funkce. Nebo jak vy řešíte multijazyčnost vašich aplikací?

    Potom by bylo úžasné, kdybys udělal nějaký balíček dibi a nforms (s nhtml) a s pár typickými příklady (nějakou mikroaplikačkou) – třeba primitivní CMS:

    1. php stránka pro registraci (bude tu krásně vidět form s povinnýma položkama a testováním správnosti všeho možného)
    2. php stránka pro zobrazení uživatelů (práce s tabulkama)
    3. php stránka pro změnu parametrů uživatelů (update, práce se session – jen někdo s určitými právy může měnit atd.)
    4. php stránka pro přidání článku (příklad pro integraci texy)
    5. stránka pro zobrazení homepage s články (listování/zobrazení)
    6. stránka pro zobrazení jednoho článku (práce s rewrite pro hezké url).

    BTW mírně offtopic – vidím, že přiřazujete násobné CLASS – znáte nějaký fígl, jak přinutit IE6, aby je podporoval? Když napíšu div class=„abc cde“, tak IE6 si z toho vezme tuším jen tu první.

    před 17 lety
  44. jonge #44

    avatar

    #11 Davide Grudle, Hm zvláštní… já mám taky svůj vlastní šablonovací systém a ten kód je až podezřele podobný tomu mému :) ono se to asi ani nijak jinak udělat nedá…

    před 17 lety | reagoval [45] llook
  45. llook #45

    avatar

    #11 Davide Grudle, #44 jonge Podobný šablonovací systém také občas používám. Inspiroval jsem se prozměnu jinde. Mimochodem, neměli byste zapomínat ošetřit tohle:

    $template->assign("this", "něco co v \$this nechceme");

    Také jsem si myslíval, že v šablonách nikdy nevyužiju nic, co neumí samotné Smarty, z toho mě vyvedla až zkušenost (zkuste si vypsat vnořená pole jako vnořené UL seznamy; lze to, ale v PHP mnohem přehledněji).

    Bohužel, šablonovací schopnosti PHP se nijak nerozvíjejí, něco jako tag libs by se občas hodilo.

    #20 johno, Znaky mrví htmlentities a lze se s tím setkat na mnoha a mnoha zahraničních webech. Špatné užití této funkce doporučuje i David Sklar (autor knihy PHP – moduly, rozšíření a akcelerátory)…

    před 17 lety | reagoval [46] FOUS
  46. FOUS #46

    #45 llooku, Tesat do kamene: In short, the point of template engines should be to separate your business logic from your presentation logic, not separate your PHP code from your HTML code.

    před 17 lety
  47. Keff #47

    #22 Radku Huláne, To je hezká zásada, kdyby po každých pár flame článcích vzniknul jeden malý ale užitečný framework, hned by bylo krásně na světě :)))

    před 17 lety
  48. Roj #48

    avatar

    #3 zirafko, #11 David Grudl Safra safra, nejak nevim, co googlit. Zavolejte ?

    před 17 lety | reagoval [49] zirafka [51] David Grudl
  49. zirafka #49

    avatar

    #48 Roji, Obavam se, ze to ani nechces vedet! My jsme to taky nikdy vedet nechteli… (-;

    před 17 lety | reagoval [51] David Grudl [52] Roj
  50. miso #50

    #4 Petere p360te Kováči, co to ma spolocne so Smarty? podla mna nic

    před 17 lety
  51. David Grudl #51

    avatar

    #48 Roji, Roji, v pohodě, vůbec o nic nejde

    #49 zirafko, já se s tím ještě dodneska nevyrovnal ☹ Ani nevím, jak se teď k němu chovat… Ale neřešme to už.

    před 17 lety | reagoval [52] Roj
  52. Roj #52

    avatar

    #51 Davide Grudle, jasne, nic nebylo a nikdo nikde nebyl

    #49 zirafko, vsak on ve skutecnosti pozna, ze dokaze odpoustet. Vic, nez si kdy myslel.

    před 17 lety
  53. tark #53

    avatar

    Kdy se chystáš vydat NForms? Trošku by se mi hodila… ?

    před 17 lety
  54. Pavel Gloss #54

    avatar

    Velmi dobrá pomůcka, kterou začínám prakticky používat. Jenom mi nešlo volat u objektu elementu settery
    př.: $menulink->href(„index.php?kategorie={$kategorie->getID()}“);
    kvůli přistupování k privátní metodě.
    Fatal error: Call to private method NHtml::__call() from context

    Tak jsem změnil hlavičku funkce na public
    public function __call($m, $args)
    a funguje. Používám PHP5…mohlo to být tím ?

    před 17 lety | reagoval [55] David Grudl
  55. David Grudl #55

    avatar

    #54 Pavle Glossi, ano, to je dobrá připomínka, v PHP < 5.1 je nutné deklarovat funkci __call jako public. Opravil jsem to.

    před 17 lety
  56. Dundee #56

    avatar

    Zajímavé a dost jednoduché (kód třídy na 220 řádků).
    Pokud ale nejsem úplně mimo, tak tahle třída funguje jen na PHP 5, což bych viděl jako velkou nevýhodu. Jak ale říkám, třída a vůbec princip fungování je dost jednodychý, takže není problém třídu přepsat a nebo napsat rovnou celou po svém…

    před 17 lety | reagoval [57] tark
  57. tark #57

    avatar

    #56 Dundee, PHP5 není nevýhoda,nové projekty NEMÁ SMYSL kódovat pro čtyřku… Nevidím důvod, pětka už je dost rozšířená… A já kóduju ještě jen pro PostgreSQL :D

    před 17 lety
  58. Lukáš #58

    avatar

    Je to perfektní, strašně se mi líbí malá jednoduchá řešení, ze kterých se dá stavět. Moc se těším na Nette. Na jaře si chci napsat svůj srdeční projekt a rád bych použil Nette. Má smysl čekat?

    před 17 lety
  59. Veena #59

    avatar

    Html bez html.
    Opravdovej DOM… aneb simpledom.
    #stary-odkaz-#stary-odkaz-http://slapstick.php5.cz/simpledom/pouziti.phps
    #stary-odkaz-#stary-odkaz-http://slapstick.php5.cz/simpledom/simpledom1.0.tgz

    Třídy mají implementovány metody nezbytné k základnímu chodu. Další metody zřejmě přibudou, až to pořádně otestuju ve vývoji. Možná se změní i implementace stávajících metod.

    Za každý návrh ke zlepšení nebo za doplnění knihovny budu vděčný.

    před 17 lety | reagoval [60] David Grudl
  60. David Grudl #60

    avatar

    Poznámka pro uživatele NHtml: knihovna se neustále mírně vyvíjí, v poslední revizi jsem metodu setContent přejmenoval na výstižnější setText.

    #59 Veeno, pěkné! Líbí se mi volání $xyz = $el->add('xyz'), podobnou techniku jsem přidal do NHtml.

    Doplněno 9. 10. 2007: metoda add přejmenována na create

    před 17 lety | reagoval [70] David Grudl
  61. JK #61

    Mám otázku k licenci. Je/bude kompatibilní k GPL? Řekněme že vytvořím www stránky, které NHtml použijí pro generování částí xhtml (ale zdroják samotné třídy jsem nezměnil) – musím potom dát někam ke stažení zdroják toho webu?

    před 17 lety | reagoval [62] David Grudl
  62. David Grudl #62

    avatar

    #61 JKu, NHtml (a také dibi) jsou šířeny pod licencí ve stylu BSD, která je kompatibilní s GPL.

    před 17 lety
  63. Jakub #63

    Toto rozhodně vyzkouším. A tuším, že mi to bude nápomocno dosti ?

    před 17 lety
  64. Onecar #64

    avatar

    Dejve, to je žrádlo. Mňam.

    před 17 lety
  65. Honza M. #65

    avatar

    Tak mi napadlo, jestli jde do elementu přidat jako dalšího potomka / potomky nějaké html. Třeba výcuc z databáze.

    $el = NHtml::el('div');
    $el->add('h1')->setText('hlavička');
    $el->add($vycuc_z_databaze_text_clanku, true);

    Ono to přidá <výcuc z db></výcuc z db> ☹

    před 17 lety
  66. Honza M. #66

    avatar

    už jsem to možná naštudoval

    před 17 lety
  67. Honza M. #67

    avatar
    $el->add('')->setText($vycuc_z_databaze_text_clanku, true);

    Se už asi smí. Ale zrušil bych ty uvozovky u add. Bez nich to hlásí chybu.

    před 17 lety
  68. Honza M. #68

    avatar

    Přidělal bych $el->addText();. Jenže to už má NForms. Zapeklitá situace…

    před 17 lety
  69. Honza M. #69

    avatar

    To vkládání existujících elementů mi nefunguje.

    Fatal error: Uncaught exception ‚NHtmlException‘ with message ‚Name must be string or null‘ in .........NHtml.php:110 Stack trace: #0 .........NHtml.php(226): NHtml->setName(Object(NHtml)) #1 ................index.php(28): NHtml->add(Object(NHtml)) #2 {main} thrown in ................NHtml.php on line 110

    před 17 lety | reagoval [70] David Grudl
  70. David Grudl #70

    avatar

    #69 Honzo M., no, cca tady #60 David Grudl jsem trošku zmršil API. Totiž, co všechno je možné vložit?

    1. existující uzel NHtml
    2. textový uzel
    3. vytvořit nový uzel NHtml a vložit jej

    Vkládání řeší metody add(...) a addChild(...), jenže takovéto pojmenování je napytel, není zřejmé, co která dělá. Jak z toho ven? No addChild bych bez náhrady zrušil. Je potřeba rozlišit textový uzel a jméno nového elementu.

    Jedna z možností je: (zápis v pseudophp, čísla odpovídají prvnímu seznamu)

    1. $el->add(NHtml $child)
    2. $el->add(string $text)
    3. $el->addNew(string $name [, $content]) (nebo create?)

    Samozřejmě jde o BC break, kdy metodu add by bylo potřeba přejmenovat na addNew/create. Nebo:

    1. $el->add(NHtml $child)
    2. $el->addText(string $text)
    3. $el->add(string $name [, $content])

    Napadá vás jiné řešení?

    před 17 lety | reagoval [71] David Grudl
  71. David Grudl #71

    avatar

    #70 Davide Grudle, a ještě jedna věc. Metoda, která přidává existující NHtml (č. 1), by měla vracet sama sebe ve stylu fluent interfaces, zatímco metoda přidávající nový element (č. 3) by měla vracet tento. Takže tím pádem se nemůžou jmenovat stejně a název musí tento rozdíl vystihovat. BC se holt nevyhnu.

    Takže počínaje revizí 87 zde budou metody:

    • $el->add(NHtml $child | string $text) vrací sebe
    • $el->create(string $name [, $content]) vrací nový element

    Ve svých kódech si přejmenujte add(create( a addChild(add(. Sorráč. Text článku upravím. Obdobná změna se bude týkat i TexyHtml.

    před 17 lety | reagoval [72] Indi
  72. Indi #72

    #71 Davide Grudle, Prima. Takhle je to nej.

    btw. co to phpfashion.com? ? ty ses tajnůstkář

    před 17 lety
  73. Honza M. #73

    avatar

    Tak, ještě mám dva zvídavé dotazy ?

    NHtml: lze zadat najednou více atributů? Představoval bych si to třeba jako v jQuery:

    $img = nhtml::el('img')->attr(array(
        'src' => 'adresa.gif',
        'width' => 16,
        'height' => 16,
        'alt' => 'ikonka',
        'class' => array('prvni', 'druha')
    ));

    NForms: Mohla by mít textarea nějaké defaultní rozměry? Pro svoje účely administračního rozhraní si je stejně nastavuji javascriptem, tak mi přišlo zbytečné tam klepat nějaká čísla, která na výsledek nemají vliv.

    před 17 lety | reagoval [74] David Grudl
  74. David Grudl #74

    avatar

    #73 Honzo M., pole atributů uveď jako druhý parametr metody el()

    před 17 lety | reagoval [75] Honza M.
  75. Honza M. #75

    avatar

    #74 Davide Grudle, oki. Bylo by skvělé, kdyby toto uměly i metody add a create.

    před 17 lety | reagoval [78] David Grudl
  76. Honza M. #76

    avatar

    Ještě jsem vymyslel, že metoda addSubmit u NForms by mohla uznat null jako první parametr. Normálně totiž používám submity bez name.

    Jo a jen tak pro zajímavost, pokud má submit name „submit“, tak nejde formulář odeslat javascriptem.

    To abych nebyl málo aktivní… ?

    před 17 lety | reagoval [78] David Grudl
  77. Honza M. #77

    avatar

    NForms:

    1. bylo by fajn validační pravidlo pro url
    2. bugreport: pravidlo REGEXP v JS jen vyhodí chybu. Chybí tam buď /lomítka/ nebo nějaký new Regexp
    před 17 lety
  78. David Grudl #78

    avatar

    #76 Honzo M., V takovém případě ho musíš odeslat přes form.submit.click(). Jinak u NForms musí mít každý prvek nějaké unikátní jméno, s tím počítají další části systému. Validační pravidlo pro URL by se hodilo, přidal jsem ho jako NForm::URL. No a regexp je nutné zadat ve tvaru /.../ig, s jiným formátem si JavaScript nerozumí.

    #75 Honzo M., u metody add() je to zbytečné, metoda create() by to mít mohla, přidal jsem.

    před 17 lety | reagoval [79] Honza M.
  79. Honza M. #79

    avatar

    #78 Davide Grudle, Co když chci, aby mail nebo url bylo nepovinné? Když políčko nevyplním, hlásí to chybu.

    Podle mě je lepší i pro povinný mail mít dvě validační pravidla. Jedno by ohlásilo nevyplněný mail a druhé špatně vyplněný.

    Mám takový podezřelý pocit, že tomu tak bývalo.

    před 17 lety | reagoval [80] David Grudl
  80. David Grudl #80

    avatar

    #79 Honzo M.,

    // email je povinný
    $form->addRule('email', NForm::FILLED, 'Zadejte email');
    // a musí být platný
    $form->addRule('email', NForm::EMAIL, 'Zadaný email není platný');

    nebo

    // pokud je email zadaný, pak zkontroluj platnost
    $form->addCondition('email', NForm::FILLED)->
       addRule('email', NForm::EMAIL, 'Zadaný email není platný');

    nebo

    // pokud je email NEzadaný, musí být zadané tel. číslo
    $form->addCondition('email', ~NForm::FILLED)->
       addRule('phone', NForm::FILLED, 'Zadejte email nebo telefon');

    atd. Podmínky a pravidla lze libovolně kombinovat:

    // pokud pro údaj platí toto
    $cond = $form->addCondition(...);
    
    // pak musí platit i toto
    $cond->addRule(...);
    $cond->addRule(...);
    
    // a pokud navíc platí toto
    $cond2 = $cond->addCondition(...);
    
    // tak ještě musí platit toto
    $cond2->addRule(...);
    před 17 lety
  81. David Grudl #81

    avatar

    V NHtml stromu je nyní možné se pohybovat i nahoru – přidal jsem funkci NHtml::getParent().

    Vyžadovalo to ovšem zrušit public přístup k poli NHtml::$children a pole zapouzdřit. Aby změna byla co nejmenší, implementoval jsem interface ArrayAccess, takže k potomkům se přistupuje stále přes pole, jen se vynechá ->children:

    $el = NHtml::el('div');
    $el[ 0] = NHtml::el('p'); // namísto $el->children[ 0] ...
    unset($el[ 1]);
    ...atd..

    Navíc pole potomků se chová jako skutečné pole a nikoliv hash.

    před 16 lety
  82. yed_ #82

    Jen taková drobnost, kterou mám ve své třídě pro formuláře. Pokud vytvořím obsáhlejší formulář, mohu záhy zjistit, že zpracovávat každou položku zvlášť by bylo pracné, tak je zaobalím do pole, které lze snadno zpracovat v cyklu. Příklad

    $form = new Form('form_id', Array('action' => $app->path('modul','akce')));
    $form->InputsArray('nemovitost'); //toto je pro zabaleni inputu do pole
    
    $input = new FormInput('garden',Array('type' => 'checkbox', 'value' => 1));
    $input->setLabel('estate.garden');
    
    $form->addInput($input);

    Bez použití InputsArray():

    <div class="formItem">
    <label for="garden">Zahrada</label>
    <input name="garden" id="garden" type="checkbox" value="1" class="checkbox" />
    </div>

    S použitím InputsArray():

    <div class="formItem">
    <label for="nemovitost_garden">Zahrada</label>
    <input name="nemovitost[garden]" id="nemovitost_garden" type="checkbox" value="1" class="checkbox" />
    </div>
    před 16 lety | reagoval [83] veena [84] David Grudl
  83. veena #83

    #82 yed_,
    jop, to by mě zajímalo, jestli máš array safe validaci vstupních parametrů i při hlouběji zanořených polích.

    Pokud ano, nechtěl bys to zveřejnit?

    před 16 lety | reagoval [85] yed_
  84. David Grudl #84

    avatar

    #82 yed_, ano, to je dobrá poznámka. V případě NForm je iterování nad formulářem nebo jeho částí možné už z principu komponent. Brzo dodám nějaký příklad

    před 16 lety
  85. yed_ #85

    #83 veeno, při hlouběji zanořených polích kde?

    před 16 lety | reagoval [86] veena
  86. veena #86

    #85 yed_,

    <input name="nemovitost[garden][ab][cd]" ...
    před 16 lety | reagoval [87] yed_
  87. yed_ #87

    #86 veeno, Zadny pokrocily zpusob, ktery bych stal za to uverejnit, nepouzivam.

    před 16 lety

Tento článek byl uzavřen. Už není možné k němu přidávat komentáře.


phpFashion © 2004, 2024 David Grudl | o blogu

Ukázky zdrojových kódů smíte používat s uvedením autora a URL tohoto webu bez dalších omezení.