Klávesové zkratky na tomto webu - rozšířené Na obsah stránky

Translate to English… Ins Deutsche übersetzen…

Nette\Web\Html - pomocník PHP programátora

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

→ Download: Nette\Web\Html­.zip (revize 101) licence, překlad

Upozornění: Knihovna Nette\Web\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\Web\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\Web\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\Web\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\Web\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\Web\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\Web\Html používá pro generování kódu. Takže tak.

Komentáře RSS 2.0 komentářů » přidat

avatar

#1 Sitnarf frantisek.sabovcik@tiscali.cz nový

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

Posláno 20. 12. 2006 v 7.06 | Odpovědět

#2 ivan_d nový

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

Posláno 20. 12. 2006 v 7.18 | Odpovědět
Na komentář reagoval [10] ivan_d
avatar

#3 zirafka http://zirafka.cz nový

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

ne fakt, vypada to dost dobre!

Posláno 20. 12. 2006 v 7.40 | Odpovědět
Na komentář reagoval [11] David Grudl [48] Roj
avatar

#4 Peter p360t Kováč http://www.fotopriestor.sk nový

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

Posláno 20. 12. 2006 v 7.49 | Odpovědět
Na komentář reagoval [6] afu [11] David Grudl [50] miso

#5 piler nový

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

Posláno 20. 12. 2006 v 8.15 | Odpovědět
Na komentář reagoval [7] ivan_d [11] David Grudl
avatar

#6 afu v.brazda@sh.cvut.cz nový

#4 Peter p360t Kováč: 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.

Posláno 20. 12. 2006 v 8.18 | Odpovědět
Na komentář reagoval [9] piler

#7 ivan_d nový

#5 piler: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?

Posláno 20. 12. 2006 v 8.21 | Odpovědět
Na komentář reagoval [8] piler

#8 piler nový

#7 ivan_d: 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…

Posláno 20. 12. 2006 v 8.32 | Odpovědět
Na komentář reagoval [10] ivan_d

#9 piler nový

#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…

Posláno 20. 12. 2006 v 8.35 | Odpovědět

#10 ivan_d nový

#8 piler: 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?

Posláno 20. 12. 2006 v 8.43 | Odpovědět
avatar

#11 David Grudl http://davidgrudl.com nový

#4 Peter p360t Kováč: 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 piler: 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 zirafka: 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.

Posláno 20. 12. 2006 v 8.49 | Odpovědět

#12 piler nový

#11 David Grudl: 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..

Posláno 20. 12. 2006 v 9.01 | Odpovědět
Na komentář reagoval [13] David Grudl [16] error414
avatar

#13 David Grudl http://davidgrudl.com nový

#12 piler: 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.

Posláno 20. 12. 2006 v 9.12 | Odpovědět
Na komentář reagoval [14] ivan_d

#14 ivan_d nový

#13 David Grudl: 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.

Posláno 20. 12. 2006 v 9.23 | Odpovědět
avatar

#15 Štěpán Svoboda http://develo.styled.cz nový

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?

Posláno 20. 12. 2006 v 9.30 | Odpovědět
Na komentář reagoval [16] error414 [19] LokoN

#16 error414 http://www.error414.com nový

#15 Štěpán Svoboda:

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

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

#12 piler:
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.

Posláno 20. 12. 2006 v 10.47 | Odpovědět
avatar

#17 tark http://fotoblog.blacksuns.net nový

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

Posláno 20. 12. 2006 v 10.56 | Odpovědět
Na komentář reagoval [18] error414 [30] David Grudl

#18 error414 http://www.error414.com nový

#17 tark: trochu namohy hosi

Posláno 20. 12. 2006 v 10.58 | Odpovědět
Na komentář reagoval [26] tark

#19 LokoN nový

#15 Štěpán Svoboda: Javascriptové události navěšuj javascriptem a je to.

Posláno 20. 12. 2006 v 11.01 | Odpovědět
avatar

#20 johno http://johno.jsmf.net/ nový

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.
Posláno 20. 12. 2006 v 11.35 | Odpovědět
Na komentář reagoval [30] David Grudl [45] llook

#21 koolazz@koolazz.com nový

zlaté xml a xslt :)

Posláno 20. 12. 2006 ve 12.19 | Odpovědět
avatar

#22 Radek Hulán http://hulan.cz/ nový

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š? ;-)

Posláno 20. 12. 2006 ve 12.26 | Odpovědět
Na komentář reagoval [47] Keff
avatar

#23 afu v.brazda@sh.cvut.cz nový

#11 David Grudl: >>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 :)

Posláno 20. 12. 2006 ve 12.48 | Odpovědět
Na komentář reagoval [24] Thomas [25] johno
avatar

#24 Thomas th@atlas.cz nový

#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 :-)

Posláno 20. 12. 2006 ve 12.54 | Odpovědět
Na komentář reagoval [25] johno
avatar

#25 johno http://johno.jsmf.net/ nový

#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.

Posláno 20. 12. 2006 ve 13.05 | Odpovědět
avatar

#26 tark http://fotoblog.blacksuns.net nový

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

Posláno 20. 12. 2006 ve 13.09 | Odpovědět

#27 Arthur Dent nový

[0] 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 :)

Posláno 20. 12. 2006 ve 13.12 | Odpovědět
avatar

#28 johno http://johno.jsmf.net/ nový

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

Posláno 20. 12. 2006 ve 13.22 | Odpovědět
Na komentář reagoval [29] Arthur Dent

#29 Arthur Dent nový

#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).

Posláno 20. 12. 2006 ve 13.31 | Odpovědět
avatar

#30 David Grudl http://davidgrudl.com nový

[10087] 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 tark: 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 Arthur Dent: 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“ :-)

Posláno 20. 12. 2006 ve 14.00 | Odpovědět
avatar

#31 Radek Hulán http://hulan.cz/ nový

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

Posláno 20. 12. 2006 ve 14.09 | Odpovědět
Na komentář reagoval [33] David Grudl
avatar

#32 sway http://sway.treska.net nový

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

Posláno 20. 12. 2006 ve 14.13 | Odpovědět
avatar

#33 David Grudl http://davidgrudl.com nový

#31 Radek Hulán: 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 :-)

Posláno 20. 12. 2006 ve 14.19 | Odpovědět
Na komentář reagoval [34] johno
avatar

#34 johno http://johno.jsmf.net/ nový

#30 David Grudl: 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 David Grudl: Ja budem komentovať NForms až v tom buducom článku, dobre?

Posláno 20. 12. 2006 ve 14.37 | Odpovědět
Na komentář reagoval [35] David Grudl
avatar

#35 David Grudl http://davidgrudl.com nový

#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]
Posláno 20. 12. 2006 ve 14.44 | Odpovědět

#36 Arthur Dent nový

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

Posláno 20. 12. 2006 ve 14.52 | Odpovědět
avatar

#37 Marek aceg@seznam.cz nový

#27 Arthur Dent: [10101] 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é …

Posláno 20. 12. 2006 v 15.06 | Odpovědět
Na komentář reagoval [39] Arthur Dent
avatar

#38 numero http://www.numero.name nový

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

Posláno 20. 12. 2006 v 16.02 | Odpovědět

#39 Arthur Dent nový

#37 Marek: „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!

Posláno 20. 12. 2006 v 16.32 | Odpovědět

#40 finc http://finc.ic.cz nový

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.

Posláno 20. 12. 2006 v 16.32 | Odpovědět
avatar

#41 Havran http://www.fem.uniag.sk/havran/ nový

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

Posláno 20. 12. 2006 ve 20.14 | Odpovědět
avatar

#42 zirafka http://zirafka.cz nový

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

Posláno 20. 12. 2006 ve 20.31 | Odpovědět

#43 noname http://kapler.cz nový

Mně se to také celkem líbí, možná bych jen ještě uvítal nějakou jednoduchou možnost pro „internaciona­lizaci“, 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í/zo­brazení)
  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í.

Posláno 20. 12. 2006 ve 20.33 | Odpovědět
avatar

#44 jonge jonge@seznam.cz nový

#11 David Grudl: 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á…

Posláno 20. 12. 2006 ve 20.50 | Odpovědět
Na komentář reagoval [45] llook
avatar

#45 llook http://llook.wz.cz/weblog/ nový

#11 David Grudl: #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)…

Posláno 20. 12. 2006 ve 20.54 | Odpovědět
Na komentář reagoval [46] FOUS

#46 FOUS nový

#45 llook: 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.

Posláno 20. 12. 2006 ve 21.53 | Odpovědět

#47 Keff http://www.tomaskafka.com nový

#22 Radek Hulán: 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ě :)))

Posláno 21. 12. 2006 v 1.58 | Odpovědět
avatar

#48 Roj http://roj.bloguje.cz nový

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

Posláno 21. 12. 2006 ve 2.31 | Odpovědět
Na komentář reagoval [49] zirafka [51] David Grudl
avatar

#49 zirafka http://zirafka.cz nový

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

Posláno 21. 12. 2006 ve 3.19 | Odpovědět
Na komentář reagoval [51] David Grudl [52] Roj

#50 miso http://www.create.sk nový

#4 Peter p360t Kováč: co to ma spolocne so Smarty? podla mna nic

Posláno 21. 12. 2006 v 10.45 | Odpovědět
avatar

#51 David Grudl http://davidgrudl.com nový

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

#49 zirafka: 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ž.

Posláno 21. 12. 2006 v 11.36 | Odpovědět
Na komentář reagoval [52] Roj
avatar

#52 Roj http://roj.bloguje.cz nový

#51 David Grudl: jasne, nic nebylo a nikdo nikde nebyl

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

Posláno 21. 12. 2006 ve 21.51 | Odpovědět
avatar

#53 tark http://fotoblog.blacksuns.net nový

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

Posláno 25. 12. 2006 ve 13.43 | Odpovědět
avatar

#54 Pavel Gloss http://www.x-name.wz.cz nový

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?ka­tegorie={$kate­gorie->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 ?

Posláno 29. 12. 2006 v 17.32 | Odpovědět
Na komentář reagoval [55] David Grudl
avatar

#55 David Grudl http://davidgrudl.com nový

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

Posláno 29. 12. 2006 v 18.15 | Odpovědět
avatar

#56 Dundee http://blog.milde.cz nový

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…

Posláno 5. 1. 2007 v 0.09 | Odpovědět
Na komentář reagoval [57] tark
avatar

#57 tark http://fotoblog.blacksuns.net nový

#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

Posláno 5. 1. 2007 v 15.14 | Odpovědět
avatar

#58 Lukáš lhr@seznam.cz nový

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?

Posláno 7. 1. 2007 ve 14.03 | Odpovědět
avatar

#59 Veena stv@seznam.cz nový

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ý.

Posláno 8. 5. 2007 v 10.57 | Odpovědět
Na komentář reagoval [60] David Grudl
avatar

#60 David Grudl http://davidgrudl.com nový

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 Veena: 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

Posláno 9. 5. 2007 ve 4.19 | Odpovědět
Na komentář reagoval [70] David Grudl

#61 JK nový

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?

Posláno 25. 6. 2007 v 8.22 | Odpovědět
Na komentář reagoval [62] David Grudl
avatar

#62 David Grudl http://davidgrudl.com nový

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

Posláno 25. 6. 2007 ve 13.49 | Odpovědět

#63 Jakub http://www.clickmedia.cz nový

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

Posláno 1. 9. 2007 v 1.35 | Odpovědět
avatar

#64 Onecar http://jednoauto.com/blog nový

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

Posláno 3. 9. 2007 v 19.34 | Odpovědět
avatar

#65 Honza M. http://texyla.jaknato.com/ nový

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> :-(

Posláno 25. 9. 2007 ve 21.42 | Odpovědět
avatar

#66 Honza M. http://texyla.jaknato.com/ nový

už jsem to možná naštudoval

Posláno 25. 9. 2007 ve 21.48 | Odpovědět
avatar

#67 Honza M. http://texyla.jaknato.com/ nový

$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.

Posláno 25. 9. 2007 ve 21.55 | Odpovědět
avatar

#68 Honza M. http://texyla.jaknato.com/ nový

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

Posláno 26. 9. 2007 v 9.57 | Odpovědět
avatar

#69 Honza M. http://texyla.jaknato.com/ nový

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(Objec­t(NHtml)) #1 .............­...index.php(28): NHtml->add(Object(NHtml)) #2 {main} thrown in .............­...NHtml.php on line 110

Posláno 2. 10. 2007 ve 22.40 | Odpovědět
Na komentář reagoval [70] David Grudl
avatar

#70 David Grudl http://davidgrudl.com nový

#69 Honza 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í?

Posláno 9. 10. 2007 v 17.34 | Odpovědět
Na komentář reagoval [71] David Grudl
avatar

#71 David Grudl http://davidgrudl.com nový

#70 David Grudl: 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.

Posláno 9. 10. 2007 v 19.10 | Odpovědět
Na komentář reagoval [72] Indi

#72 Indi nový

#71 David Grudl: Prima. Takhle je to nej.

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

Posláno 10. 10. 2007 v 8.13 | Odpovědět
avatar

#73 Honza M. http://texyla.jaknato.com/ nový

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.

Posláno 13. 10. 2007 v 8.34 | Odpovědět
Na komentář reagoval [74] David Grudl
avatar

#74 David Grudl http://davidgrudl.com nový

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

Posláno 13. 10. 2007 ve 13.53 | Odpovědět
Na komentář reagoval [75] Honza M.
avatar

#75 Honza M. http://texyla.jaknato.com/ nový

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

Posláno 13. 10. 2007 v 19.17 | Odpovědět
Na komentář reagoval [78] David Grudl
avatar

#76 Honza M. http://texyla.jaknato.com/ nový

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í;-)

Posláno 13. 10. 2007 v 19.41 | Odpovědět
Na komentář reagoval [78] David Grudl
avatar

#77 Honza M. http://texyla.jaknato.com/ nový

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
Posláno 13. 10. 2007 ve 22.38 | Odpovědět
avatar

#78 David Grudl http://davidgrudl.com nový

#76 Honza M.: V takovém případě ho musíš odeslat přes form.submit.clic­k(). 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 Honza M.: u metody add() je to zbytečné, metoda create() by to mít mohla, přidal jsem.

Posláno 14. 10. 2007 v 0.09 | Odpovědět
Na komentář reagoval [79] Honza M.
avatar

#79 Honza M. http://texyla.jaknato.com/ nový

#78 David Grudl: 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.

Posláno 14. 10. 2007 v 11.14 | Odpovědět
Na komentář reagoval [80] David Grudl
avatar

#80 David Grudl http://davidgrudl.com nový

#79 Honza 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(...);
Posláno 14. 10. 2007 v 18.07 | Odpovědět
avatar

#81 David Grudl http://davidgrudl.com nový

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.

Posláno 25. 10. 2007 v 8.41 | Odpovědět

#82 yed_ nový

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>
Posláno 29. 10. 2007 ve 12.46 | Odpovědět
Na komentář reagoval [83] veena [84] David Grudl

#83 veena nový

#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?

Posláno 29. 10. 2007 ve 14.34 | Odpovědět
Na komentář reagoval [85] yed_
avatar

#84 David Grudl http://davidgrudl.com nový

#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

Posláno 29. 10. 2007 v 15.38 | Odpovědět

#85 yed_ nový

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

Posláno 29. 10. 2007 v 17.18 | Odpovědět
Na komentář reagoval [86] veena

#86 veena nový

#85 yed_:

<input name="nemovitost[garden][ab][cd]" ...
Posláno 29. 10. 2007 v 19.07 | Odpovědět
Na komentář reagoval [87] yed_

#87 yed_ nový

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

Posláno 30. 10. 2007 v 9.21 | Odpovědět

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

Výtah na začátek článku na první komentář

Názory čtenářů v diskusích nejsou názory provozovatele webu, a ten za jejich obsah neodpovídá.

phpFashion © 2004, 2010 David Grudlo webu

Pokud není uvedeno jinak, podléhá obsah těchto stránek licenci Creative Commons BY-NC-ND Creative Commons License BY-NC-ND

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