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

Vytváření elementů v jQuery

S pomocí jQuery lze vytvořit HTML element docela jednoduše:

var $el = $('<a href="http://phpfashion.com">blogísek</a>');

Do proměnné $el se přiřadí objekt jQuery obalující vytvořený HTML element (proto jsem použil dolar v názvu proměnné), k nativnímu DOM objektu se dostanete přes $el[0].

Co ale v případě, že potřebujeme jako hodnoty použít proměnné? Přímočaré řešení by vypadalo takto:

// špatně: riziko XSS
var url = 'http://phpfashion.com';
var title = 'blogísek';
var $el = $('<a href="' + url + '">' + title + '</a>');

Jenže, jak uvádí komentář v kódu, koledujeme si tímto o průšvih jménem Cross-site scripting (XSS). Stačí, aby například proměnná url obsahovala uvozovky a výsledek bude nezamýšlený. Proto je nutné proměnné escapovat, tj. nahradit znaky mající speciální význam za HTML entity. Na to si můžeme napsat funkci escapeHtml:

// správné, ale ne příliš přehledné
var escapeHtml = function(s) {
    return s.replace('&', '&amp;').replace('"', '&quot;')
        .replace("'", '&#039;').replace('<', '&lt;');
};

var $el = $('<a href="' + escapeHtml(url) + '">' + escapeHtml(title) + '</a>');

Skládání řetězců postrádá onu lehkost a srozumitelnost první ukázky, nemluvě o riziku, že escapeHtml zapomeneme zavolat. Naštěstí jQuery od verze 1.4 nabízí elegantní řešení: proměnné uvedeme ve druhém parametru (viz dokumentace)

// dokonalé
var $el = $('<a>', {
    href: url,
    text: title
});

Příjemné je, že takto lze kromě HTML atributů definovat i kaskádové styly a události:

// <a style="color: red;" onclick="..." href="http://phpfashion.com">blogísek</a>
var $el = $('<a>', {
    href: url,
    text: title,
    click: function(e) {
        alert(this.href);
    },
    css: {
        color: 'red'
    }
});

Dokonce dovnitř můžeme vložit další element:

// <a href="http://phpfashion.com"><img alt="Logo" src="images/logo.gif"></a>
var $el = $('<a>', {
    href: url,
    html: $('<img>', {
        src: 'images/logo.gif',
        alt: 'Logo'
    })
});

Fajnové, že?

p.s. pokud se chcete o jQuery dozvědět víc, přijďte na školení jQuery a AJAX.

clock 24. 1. 2011 pencil JavaScript comments Komentáře: 6


Školení jQuery a AJAX startuje!

„Ty bys měl školit Nette,“ řekl mi Vašek WebExpo Stoupa a já se pak přes půl roku rozhoupával, než v listopadu 2008 uskutečnil první školení Vývoj webových aplikací v Nette Framework. Od té doby prošlo kurzem asi 300 kolegů programátorů.

„Ty bys měl školit jQuery,“ řeklo mi pár účastníků školení Nette a já se pak přes půl roku rozhoupával, než vypsal první školení jQuery a AJAX, na které vás tímto zvu. (Než jsem se rozhoupal k napsání tohoto článku, kurz je z poloviny naplněn. Málo houpu.)

Co vám kurz dá? Vím, že to zní jako otřepaná fráze, ale rád bych ukázal, že oživování webové stránky pomocí JavaScriptu může být skutečně zábavné. Seznámím vás s nejpopulárnějším JavaScriptovým frameworkem jQuery na praktických příkladech. Přitom budeme dbát na čistý návrh a znovupoužitelnost, protože ve chvíli, kdy programátor zabředne do bastlení, je se zábavou smyčec. Nebo šmitec. Celým kurzem se potáhne ústřední motiv user experience, tj. vysvětlíme si a ukážeme, kterou cestou se vydat, aby výsledek byl pro uživatele co nejintuitivnější. Protože o nic jiného vlastně nejde.

Bylo by fajn, kdybyste na školení vyrazili se základní znalostí JavaScriptu (stačí rozumět tomuto článku bez kapitol Properties a Dědičnost). Pokud zatím neznáte jQuery a rádi byste to napravili, jsem vám k službám!

clock 13. 1. 2011 pencil JavaScript comments Komentáře: 5


Recenze knihy 1001 tipů a triků pro PHP

Když jsem se dozvěděl, že Jakub Vrána píše knížku 1001 tipů a triků o PHP, samozřejmě mě napadlo pár trapných fórků („1001 vtipů o PHP“, „to jich bude devět?“ nebo „č. 1: znáte Ruby?“) ale pak jsem si uvědomil, jak je to vlastně šíleně velké číslo. Schválně, zkuste vymyslet a napsat padesátku. Dáte to? Já leda s odřenýma játrama. No a pak další. A další. A další! Uff. Když pak Jakub hlásil, že se blíží do třetiny, vzpomněl jsem si na Marvinovo „Nejhorší bylo těch prvních deset miliónů.“

Humor mi došel ve chvíli, kdy mě Jakub požádal, jestli bych mu udělal korekturu. Co si budeme povídat, když váš kamarád napíše knihu, tak ji od něj dostanete, někam ji důmyslně založíte a až se setkáte, tak mu řeknete, že jste ji samozřejmě četli a jako že to fakt bylo dobrý a poplácáte ho po rameni nebo tam někde. Alespoň tak velí bonton. Ovšem když máte dělat korekturu, ocitáte se vstříc hrozbě, že ji doopravdy budete muset přečíst! Že bych mu ji po týdnu vrátil netknutou a bez jediného škrtu („čéče, sem to fakt čet a žádnou vyloženě jako chybu sem tam nenašel…“), o tom jsem vůbec neuvažoval, by mi to nezbaštil. Pustil jsem se do čtení a zjistil, že to je hodně dobrý materiál.

Byť školy nemám a z odborné literatury jsem přečetl jen Pixyho, Kruga a Koska, cítím se v PHP poměrně zdatný. Co mi může kniha od Jakuba dát? Ejhle, může. Jakub totiž na vydavatele ušil pěknou kulišárnu, ta kniha je o PHP spíš mimochodem. Je to prostě hromada zajímavých tipů a nápadů pro všechny, kdo se zabývají webovými aplikacemi. Navíc originálních tipů, nejde totiž o tištěnou verzi Jakubova blogu. V žádném případě nečekejte referenční příručku PHP nebo nudnou přehlídku funkcí, kdepak. Najdete tu tipy počínaje návodem, jak skrýt emailovou adresu před roboty, přes generování sitemap až po pádné argumenty, zda mít doménu s www. nebo bez.

U toho bych se zastavil. Ač s Jakubem máme na mnohé věci odlišné názory, s ním je radost nesouhlasit. On má totiž svůj postoj vždycky podpořený jasnou argumentací. U něj neexistuje „to se dělá tak, protože to tak dělá každý“ nebo „protože tak to dělá Nielsen|Zeldman|Ler­dorf|Torvalds|(do­plň si svou kapacitu)“, ale protože nad tím přemýšlel a došel k nějakému závěru. A to se jako červená niť táhne celou knihou. Takže ačkoliv bych mohl s něčím nesouhlasit, stěží bych v ní hledal chybu. Takovou preciznost jsem zažil snad jen u knih Douglase Crockforda.

Ale ať jen nechválím – kniha je sbírkou nápadů, které jsou sice tematicky uspořádané, ale chybí mi tam průvodní slovo, co by z toho dělalo souvislé čtivo. Chybí mi tam Miloš Frýba. A na můj vkus obsahuje příliš málo humoru a nadsázky :-)

Každopádně knihu vřele doporučuji každému PHPčkaři, své si v ní najdou jak začátečníci, tak matadoři. Za cenu jednoho bifteku není nad čím váhat. A neříkám to proto, že je v ní zmíněné Nette :-) V knihkupectvích by měla být od pondělí, nicméně dokud Jakub nabízí možnost nechat si ji za stejnou cenu poslat s jeho podpisem, tak knihkupectví nemají šanci.

clock 8. 1. 2011 pencil PHP comments Komentáře: 7


Jak se píše generátor API dokumentace?

Dlouhá léta mi ze zdrojáků generoval API dokumentace phpDocumentor. Vývoj tohoto nástroje ustrnul a PHP 5.3 je mu cizí, zejména chybí podpora jmenných prostorů. Začal jsem hledat alternativu. Bohužel žádná sláva.

On ani samotný phpDocumentor nebyl žádný zázrak. Dodáván se sadou šablon, jedna hnusnější než druhá, vedle toho i taková Lupa.cz vypadá jako fešanda. Chápu, „programátoři sobě“, oželel bych nějaké eye-candy, ale šablony jsou tak zoufale nepřehledné a odpudivé, že si neumím představit takovou dokumentaci používat dobrovolně. Užitná hodnota nulová. A nabídka alternativních šablon není.

Vyzkoušel jsem phpDoctor, doxygen a PHP_UML, u kterého jsem nakonec zůstal. Jeho standardně vygenerovaná dokumentace asi nejvíc odpovídala tomu, co jsem hledal (ukázka). Jenže aplikace je taková PEARovská, hned v úvodu člověka přivítá Notice: Undefined variable: errorLevel, musel jsem se hrabat ve zdrojácích a opravit několik bugů, strávil moře času úpravou XSL šablon. Ještě štěstí, že PHP_UML generuje dokumentaci neskutečně rychleji než phpDocumentor, takže jsem viděl výsledek každého zásahu takřka ihned a ne až po dlouhých minutách. Stále tomu ale chyběly dost podstatné věci, a tehdy mě napadlo…

…že si prostě napíšu vlastní generátor. Za čas, co jsem investoval do úprav, jsem ho mohl mít hotový několikrát. Ach ta narušená schopnost používat cizí knihovny.

Pokusím se vysvětlit postup, jak jsem Apigen psal. Dopředu prozradím, že se vešel do pouhých 150 řádků (!) kódu + šablony.

Jak na to

Nejprve: zdrojový kód lze analyzovat buď vlastním parserem, nebo využít reflection. Jedním z hlavních požadavků bylo, že generátor bude umět plnohodnotně pracovat s interními třídami PHP (třeba takto). Což mi jinde citelně chybělo. Jelikož interní třídy žádný zdrojový kód nemají, zvolil jsem reflexi. To znamená, že všechny třídy, pro které chci generovat dokumentaci, musím načíst. Projít adresářovou strukturu třeba Finderem a postupně volat require pro každý soubor nejde – mezi třídami jsou závislosti a je nutné je načítat v pořadí: rozhraní, rodiče, potomci. Nelehký úkol, ale vyřešil jej RobotLoader:

$robot = new Nette\Loaders\RobotLoader;
$robot->addDirectory($dir); // adresář, který chceme dokumentovat
$robot->register(); // zapne autoloading

// getIndexedClasses vrací seznam nalezených tříd a souborů
foreach ($robot->getIndexedClasses() as $file) {
        require_once $file;
}
$robot->unregister();

Když nyní načtu třídu, která má vazbu na dosud nenačtenou třídu nebo rozhraní, přijde ke slovu RobotLoader a situaci vyřeší. Takže to bychom měli. Paráda.

Když operuješ sám sebe

Avšak objevil se tu oříšek. Jak generovat API dokumentaci pro knihovnu, kterou pro generování API dokumentace používám? Slepice a vejce hadr. Řešení vidím dvě: buď použít jako vstup přímo tu kopii Nette, kterou používá generátor, nebo vytvořit alternativní vesmír, kde se Nette nejmenuje Nette. Druhý způsob se mi zdá rozumnější, nakonec ho používám pro generování distribučních balíčků Nette. Jde o to, že generátor používá knihovnu NetteX, která se liší jen v tom, že sídlí v „oiksovaném“ jmenném prostoru.

Ano, anotace

Aby byl model plnohodnotný, potřeboval jsem přihlížet k anotacím. Například vynechat všechny elementy s anotací @internal, určovat vrácené hodnoty metod dle anotace @return atd. Tady jsem opět využil skutečnosti, že Nette Framework podporuje anotace a pro reflektování použil Nette\Reflection.

$class = new Nette\Reflection\ClassReflection($name);
if ($class->hasAnnotation('internal')) {
        ...
}

Třídy z Nette\Reflection podporují tzv. properties, tudíž se příjemněji používají v šablonách, kde místo

$tmp = $method->getAnnotations();
foreach ($tmp['params'] as $value) ...

mohu psát stručnější

foreach ($method->annotations['params'] as $value) ...

Nakonec jsem pro reflexi tříd použil vlastního potomka Nette\Reflection\ClassReflection s přidanou funkcionalitou. Přičemž Nette automaticky zajišťuje, aby metody jako getDeclaredClass() opět vracely instanci mé třídy. Svěží :-)

Ša-la-la-blo-ny

Při generování HTML souborů jsem naplno využil sílu šablonovacího jazyka Latte. Ten lze používat nejen ve spojitosti s MVC aplikacemi, ale naprosto kdekoliv. Využil jsem oddělený layout, dědičnost bloků i tzv. n:attributy. Výsledkem jsou skutečně dobře čitelné šablony. Příklad:

{* $implementers je pole objektů ClassReflection *}
<div n:if="$implementers">
        <h4>Direct Known Implementers</h4>
        {foreach $implementers as $item}
                <a href="{$item|classLink}">{$item->name}</a>{sep}, {/sep}
        {/foreach}
</div>

Uvedený <div> se vykreslí pouze v případě, že pole $implementers je neprázdné. Jednotlivé položky vykreslí jako odkazy oddělené čárkou. A makro {sep}...{/sep} zajistí, aby se čárka (tj. separátor) neobjevila za poslední položkou. Živé to můžete vidět třeba tady.

Jiným příkladem je šablona, která vygeneruje v JavaScriptu seznam všech tříd pro potřeby našeptávače (výsledek):

// $classes je opět pole objektů ClassReflection

{contentType javascript}

var classes = {$classes|values|map:'return $value->name;'};

Pro generování obarvených zdrojových kódů jsem použil skvělou knihovnu FSHL, kde stačilo doplnit seznam klíčových slov PHP 5.3. Obsah doc-bloků jsem zkusil formátovat pomocí Texy ve spojení s FSHL a výsledek se mi zdá dostačující.

Světlo světla spatřil Apigen

Naprogramovat celý generátor trvalo pár hodin, což je řádově méně, než bych strávil úpravou existujících knihoven. Výsledkem totiž bylo, jak jsem zmínil, pouhých 150 řádků kódu. Ač jsem ho nijak rychlostně neoptimalizoval, dokumentaci k Nette vygeneruje za cca 11s, zatímco phpDocumentor se s tím trápí přes dvě minuty. Ani jsem nečekal, že se Nette Framework tak výborně hodí na tak netypický úkol.

Mnohem víc času jsem pak strávil vylaďováním šablon, připojil jsem jQuery a hrál si s tříděním metod a dalšíma opičkama. Generátor jsem opatřil rozhraním pro ovládání z příkazové řádky, přidal další fíčůrky a dopsal komentáře, takže v tuto chvíli je těch řádků určitě alespoň jednou tolik :-)

Jestli chcete, tak si Apigen můžete stáhnout.

Tentokrát bez jakékoliv technické podpory. Určitě neumí spoustu věcí, které by se vám tuze hodily a bez nich to nemá smysl a ostatní generátory je mají a vůbec, tak si je prosím doprogramujte.

clock 7. 10. 2010 pencil PHP comments Komentáře: 14


Kde je Nette Framework 1?

Jak jste mohli zaregistrovat, něco se událo v číslování verzí Nette Framework. Ještě před týdnem se mohutně pracovalo na verzi 1.0, nicméně na WebExpu jsem představil verzi 2. Co se děje?

Žádné obavy, stalo se jen to, že verze doposud označovaná jako 1.0 se přejmenovala na 2.0. Povýšení přitom nemá žádný vliv na vývoj. Beta verze zahrnující všechny chystané novinky i stabilní verze vyjdou letos. Jen prostě nikdy nebude existovat verze Nette Framework 1.0.

Vynechání čísla verze není nic neobvyklého, například po Microsoft Windows 3.1 následoval skok na číslo 95, později ještě větší skok na 2000, aby se poté odečtením hodnoty 1993 vše vrátilo do jednociferných kolejí s Windows 7. Přičemž verze 4, 5 nebo 6 nás asi teprve čekají ;-)

Nette Framework 2 přichází s celou řadou novinek, s nimiž vás brzy seznámím prostřednictvím seriálu na serveru Zdroják nebo na školení.

clock 29. 9. 2010 pencil Nette comments Komentáře: 10


phpFashion © 2004, 2012 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í.