Na navigaci | Klávesové zkratky

Translate to English… Ins Deutsche übersetzen…

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 10 lety
  2. ivan_d #2

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

    před 10 lety | reagoval [10] ivan_d
  3. zirafka http://zirafka.cz #3

    avatar

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

    ne fakt, vypada to dost dobre!

    před 10 lety | reagoval [11] David Grudl [48] Roj
  4. Peter p360t Kováč http://www.fotopriestor.sk #4

    avatar

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

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

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

    před 10 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 10 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 10 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 10 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 10 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 10 lety
  11. David Grudl http://davidgrudl.com #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 10 lety | reagoval [13] David Grudl [16] error414
  13. David Grudl http://davidgrudl.com #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 10 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 10 lety
  15. Štěpán Svoboda http://develo.styled.cz #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 10 lety | reagoval [16] error414 [19] LokoN
  16. error414 http://www.error414.com #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 10 lety
  17. tark http://fotoblog.blacksuns.net #17

    avatar

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

    před 10 lety | reagoval [18] error414 [30] David Grudl
  18. error414 http://www.error414.com #18

    #17 tarku, trochu namohy hosi

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

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

    před 10 lety
  20. johno http://johno.jsmf.net/ #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 10 lety | reagoval [30] David Grudl [45] llook
  21. koolazz@koolazz.com #21

    zlaté xml a xslt :)

    před 10 lety
  22. Radek Hulán http://hulan.cz/ #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 10 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 10 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 10 lety | reagoval [25] johno
  25. johno http://johno.jsmf.net/ #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 10 lety
  26. tark http://fotoblog.blacksuns.net #26

    avatar

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

    před 10 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 http://johno.jsmf.net/ #28

    avatar

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

    před 10 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 10 lety
  30. David Grudl http://davidgrudl.com #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 http://hulan.cz/ #31

    avatar

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

    před 10 lety | reagoval [33] David Grudl
  32. sway http://sway.treska.net #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 10 lety
  33. David Grudl http://davidgrudl.com #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 10 lety | reagoval [34] johno
  34. johno http://johno.jsmf.net/ #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 10 lety | reagoval [35] David Grudl [35] David Grudl
  35. David Grudl http://davidgrudl.com #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 10 lety
  36. Arthur Dent #36

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

    před 10 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 …

    http://radekhulan.cz/…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 10 lety | reagoval [39] Arthur Dent
  38. numero http://www.numero.name #38

    avatar

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

    před 10 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 10 lety
  40. finc http://finc.ic.cz #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 10 lety
  41. Havran http://www.fem.uniag.sk/havran/ #41

    avatar

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

    před 10 lety
  42. zirafka http://zirafka.cz #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 10 lety
  43. noname http://kapler.cz #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 10 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 10 lety | reagoval [45] llook
  45. llook http://llook.wz.cz/weblog/ #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 10 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 10 lety
  47. Keff http://www.tomaskafka.com #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 10 lety
  48. Roj http://roj.bloguje.cz #48

    avatar

    #3 zirafko, #11 David Grudl Safra safra, nejak nevim, co googlit. Zavolejte :-)

    před 10 lety | reagoval [49] zirafka [51] David Grudl
  49. zirafka http://zirafka.cz #49

    avatar

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

    před 10 lety | reagoval [51] David Grudl [52] Roj
  50. miso http://www.create.sk #50

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

    před 10 lety
  51. David Grudl http://davidgrudl.com #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 10 lety | reagoval [52] Roj
  52. Roj http://roj.bloguje.cz #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 10 lety
  53. tark http://fotoblog.blacksuns.net #53

    avatar

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

    před 10 lety
  54. Pavel Gloss http://www.x-name.wz.cz #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 10 lety | reagoval [55] David Grudl
  55. David Grudl http://davidgrudl.com #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 10 lety
  56. Dundee http://blog.milde.cz #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 10 lety | reagoval [57] tark
  57. tark http://fotoblog.blacksuns.net #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 10 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 10 lety
  59. Veena #59

    avatar

    Html bez html.
    Opravdovej DOM… aneb simpledom.
    http://slapstick.php5.cz/…pouziti.phps
    http://slapstick.php5.cz/…ledom1.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 10 lety | reagoval [60] David Grudl
  60. David Grudl http://davidgrudl.com #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 10 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 9 lety | reagoval [62] David Grudl
  62. David Grudl http://davidgrudl.com #62

    avatar

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

    před 9 lety
  63. Jakub http://www.clickmedia.cz #63

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

    před 9 lety
  64. Onecar http://jednoauto.com/blog #64

    avatar

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

    před 9 lety
  65. Honza M. http://texyla.jaknato.com/ #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 9 lety
  66. Honza M. http://texyla.jaknato.com/ #66

    avatar

    už jsem to možná naštudoval

    před 9 lety
  67. Honza M. http://texyla.jaknato.com/ #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 9 lety
  68. Honza M. http://texyla.jaknato.com/ #68

    avatar

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

    před 9 lety
  69. Honza M. http://texyla.jaknato.com/ #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 9 lety | reagoval [70] David Grudl
  70. David Grudl http://davidgrudl.com #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 9 lety | reagoval [71] David Grudl
  71. David Grudl http://davidgrudl.com #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 9 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 9 lety
  73. Honza M. http://texyla.jaknato.com/ #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 9 lety | reagoval [74] David Grudl
  74. David Grudl http://davidgrudl.com #74

    avatar

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

    před 9 lety | reagoval [75] Honza M.
  75. Honza M. http://texyla.jaknato.com/ #75

    avatar

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

    před 9 lety | reagoval [78] David Grudl
  76. Honza M. http://texyla.jaknato.com/ #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 9 lety | reagoval [78] David Grudl
  77. Honza M. http://texyla.jaknato.com/ #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 9 lety
  78. David Grudl http://davidgrudl.com #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 9 lety | reagoval [79] Honza M.
  79. Honza M. http://texyla.jaknato.com/ #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 9 lety | reagoval [80] David Grudl
  80. David Grudl http://davidgrudl.com #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 9 lety
  81. David Grudl http://davidgrudl.com #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 9 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 9 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 9 lety | reagoval [85] yed_
  84. David Grudl http://davidgrudl.com #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 9 lety
  85. yed_ #85

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

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

    #85 yed_,

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

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

    před 9 lety

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