Posts Tagged ‘programavimas’

Robotžmogiams: OO pokalbis

Wednesday, February 4th, 2009

R: Gal turėčiau pervardint Blogą į BlogoKonteinerį dėl darnos? Nes kas yra blogas? Tai tik Įrašų kolekcija. Nėra tokio dalyko kaip Blogas.
A: Man taip neatrodo. Pagal tokį susitarimą galėtum sakyt kad nėra Žmogaus. Nėra HumaniškosiosBūtybės. Yra tik ŽmogausKonteineris, turintis mėsą ir sielą.
R: …o mes esam objektai. Tikriausiai tu tai klasė, paveldintiŽmogausKonteinerio. :D
A: Ką!? O kas tuomet mano objektai? Mano įvaizdžiai?
R: Tu singltonas :cool:

Neseniai girdėjau kažką sakant, kad aš kvaištelėjęs.

Robotžmogiams: „Svetainė atnaujinama, prašome užsukti vėliau…“

Friday, December 26th, 2008

Nuolat vystomuose interneto projektuose karts nuo karto daromi atnaujinimai. Tai failų struktūra pakeičiama, tai duomenų bazės schemoje sukuriama kokia nauja lentelė, tai masiškai keičiami duomenys bazėje. Paprastesniu atveju atnaujinami HTML šablonai ir stilius. Dažniausiai sudėtingesnis atnaujinimas vyksta pusvalandį ar net valandą ir jį vykdant vietoj standartinės svetainės turi būti rodomas puslapis „Svetainė atnaujinama“, kad naudotojai nematytų brokuoto vaizdo bei kad nesugadintų duomenų įrašinėdami ką į duomenų bazę keitimų proceso eigoje.

Atnaujinama

Gera praktika Apache tarnybinės stoties naudotojams yra tokiems atvejams turėti porą Apache nustatymų failų, kurie būtų pakaitom aktyvuojami, priklausomai, ar svetainė pasiekiama visiems, ar yra atnaujinimo stadijoje. Kažkada Tomas mestelėjo idėją, kad atnaujinimo atvejams konfigūraciją galima nusistatyti taip, kad kiti matytų puslapį „Svetainė atnaujinama“, o pats – galėtum naršyt visą turinį ir testuot, ar viskas veikia teisingai. Taip vienąkart ir pasireguliavau.

Apache leidžia nurodyti tarnybinės stoties konfigūraciją katalogo lygyje, naudojant .htaccess failus. Aš svarbiems projektams šakniniame (angl. root) svetainės kataloge turiu failus .htaccess_live ir .htaccess_under_construction su skirtingais nustatymais. Prireikus pakeisti būseną, konfigūraciją perkopijuoju į .htaccess failiuką:

cp .htaccess_under_construction .htaccess

ar

cp .htaccess_live .htaccess

Apache konfigūracijos failiuko .htaccess_live turinys yra maždaug toks:

# index.html ir index.php – standartiniai katalogą atvaizduojantys failai
DirectoryIndex index.html index.php
<ifmodule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    # Jei puslapis pasiektas example.com adresu, nukreipiam užklausą į www.example.com
    RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
    RewriteRule ^(.*)$ http://www.example.com$1 [R=301,L]
</ifmodule>

Tuo tarpu .htaccess_under_construction turinys toks:

# index.html ir index.php – standartiniai katalogą atvaizduojantys failai
DirectoryIndex index.html index.php
<ifmodule mod_rewrite.c>
    RewriteEngine on
    RewriteBase /
    # Jei puslapis pasiektas example.com adresu, nukreipiam užklausą į www.example.com
    RewriteCond %{HTTP_HOST} ^example\.com$ [NC]
    RewriteRule ^(.*)$ http://www.example.com$1 [R=301,L]

    # jei lankytojo IP adresas nėra 1.2.3.4 ir užklausiamas ne media katalogas,
    # tuomet nukreipk užklausą į failą temporarily-offline.html
    RewriteCond %{REMOTE_HOST} !^1\.2\.3\.4
    RewriteCond %{REQUEST_URI} !/temporary-offline\.html$
    RewriteCond %{REQUEST_URI} !^/media
    RewriteRule .* /temporary-offline.html [R=302,L]
</ifmodule>

Šiose konfigūracijose naudojamas mod_rewrite modulis. RewriteCond nurodo sąlygas, kuriomis turi būti vykdomas užklausos nukreipimas per RewriteRule. Parametrai laužtiniuose skliaustuose reiškia štai ką:

  • NC (no case) – nekreipti dėmesio, ar naudojamos didžiosios, ar mažosios raidės.
  • R=301 – užklausą nukreipti su kodu 301 „Pastovus nukreipimas“.
  • R=302 – užklausą nukreipti su kodu 302 „Laikinai perkelta“.
  • L (last rule) – paskutinė taisyklė, tad nebekreipti dėmesio į toliau einančias taisykles.

Savo IP adresą galima sužinoti vienoj iš daugelio What’s My IP tarnybų.

Kaip techniškai nustatyti laikinąjį vaizdelį „Svetainė atnaujinama“ dabar jau aišku. Kitas dalykas, kuris mano manymu yra ganėtinai svarbus, yra rodyti tinkamą laikinąjį puslapį. Man asmeniškai patinka tokie klaidų ir sisteminių pranešimų puslapiai, kurie vaizdžiai ir netechniškai man parodo, kame problema, kaip pavyzdžiui twitter.com, arba tokie, kurie papildomai pateikia kokį filmuką arba ką nors interaktyvaus, kad užimtų mane, kol vyksta atnaujinimo darbai.

Robotžmogiams: stulpelių aukščių sulyginimas CSS pagalba

Friday, December 19th, 2008

Dar nuo tų laikų, kai svetainių išdėstymui tapo nerekomenduotina naudoti lenteles, karts nuo karto susidurdavau su tokia bėda: „Kaip nustatyti keliems varijuojančio turinio stulpeliams vienodą aukštį?“ Internete būdavo siūlymų stulpelių konteineriui naudoti vertikaliai ištęstą foninį paveikslėlį su stulpelių spalvom arba papildomą Javascriptą, kuris suranda aukščiausią stulpelį ir likusiems nurodo tokį patį aukštį. Tačiau šie variantai buvo pernelyg riboti ir gremėzdiški (palikim Javascript rimtesniems funkcionalumams nei išvaizdos tvarkymas). Vos prieš kelias dienas kolega, dirbantis su HTML šablonais, man parodė geresnį Alex Robinson sprendimą.

Šiame tekste mano terminologija tokia: konteineris yra HTML elementas, kurio vaikai bus vadinami stulpeliais, kai šie vizualiai išdėstyti horizontaliai vienas šalia kito. Standartiniai konteinerių ir stulpelių pavyzdžiai galėtų būti tokie:

  • Horizontaliai į kokias tris dalis perskelto paties puslapio išdėstymas. Trys div elementai apgaubti ketvirtuoju div.
  • Horizontaliai atvaizduotas navigacinis meniu. Elementas ul su vaikučiais li.
  • Tiesiog į tinklelį (angl. grid) įpaišytos galerijos nuotraukos. Elemente div, atstojančiame eilutę, surikiuoti div elementai – nuotraukų konteineriukai su aprašymais ir nuorodom.

Visais šiais atvejais stulpeliais vadinami elementai CSS pagalba vizualiai išdėliojami horizontaliai: jiems priskiriami pločiai ir tada jie float: left ar float: right pagalba sustumiami į kurį kraštą. Apie stulpelinius išdėstymus daugiau nesiplėtosiu. Pereikime prie problemos ir sprendimo.

Atrodytų, kad skirtingų stulpelių aukščius būtų galima pagal aukščiausiąjį suvienodint per CSS parametrą height, bet reikia atsižvelgti, kad svetainės lankytojas naršyklėje gali kaitalioti tekstų aukščius View → Text Size nustatymuose. Be to statiškų svetainių laikai jau seniai praėję ir daugiausiai šiais laikais dirbame su kintančiu naudotojo generuojamu turiniu. Taigi standartiškai stulpelis turės aukštį, kuris bus kintamas, priklausomai nuo jo turinio kiekio.

Stulpelių aukščių sulyginimas

Alex Robinson siūlomas sprendimas yra visiems šiems stulpeliams nurodyti nepadoriai didelę apatinę vidinę paraštę padding-bottom ir tuomet iškart išminusuot susidariusį atstumą neigiama apatine išorine parašte margin-bottom. Primiršusiems CSS dėžės modelį, primenu, kad HTML elemento fonas background, kurį tikriausiai norėsit nustatyti, yra paties turinio ir jo vidinių paraščių padding dalis. Stulpelių konteineriui nurodžius slėpti perpildymą overflow: hidden, turėsim vizualiai vienodo aukščio elementus. Be galo dideliu paraštės dydžiu turėtų būti pasirinktas toks aukštis, kurio niekada neviršys vieno stulpelio sugeneruotas turinys. Taigi jei kalba eina apie 1-3 teksto eilučių meniu punktus, tuomet užtektų ir kokių 100px.

#blokas_A, #blokas_B, #blokas_C {
	padding-bottom: 32767px;
	margin-bottom: -32767px;
	}
#konteineris {
	overflow: hidden;
	}

Apie įvairias šio triuko išimtis skirtingose naršyklėse skaityk Position Is Everything. Yra ten ir kitų įdomių sprendimų, į kuriuos pats žadu prie progos pasigilinti (bet jau apie tai atskiro įrašo tikrai nerašysiu :D ). Apie kintamus aukščius turėtų suprasti ir į tai atsižvelgti ne tik šablonų maketuotojai, bet ir interneto dizaineriai. Bet čia jau visai kita tema.. O dabar einu gamint kūčiukų.

Žiniatinklio taikomųjų programų savybės

Monday, November 17th, 2008

Maždaug prieš dešimtmetį, kai Internet Explorer buvo absoliutus nugalėtojas naršyklių karuose, atrodė kieta gamint interneto projektus, kurie iššoka naujuose languose, paslepia adreso laukelį, užgroja mėgstamą muziką fone ar pakeičia slankiųjų juostų spalvą. Tuomet tų galimybių nebuvo tiek daug, ir knietėdavo išbandyt visas gėlytes ir drugelius, o tada kitiems parodyt. Paskui keitėsi laikai ir vertybės. Atsirado interneto technologijų standartai, pridygo naujų naršyklių, telefonai ir kiti prietaisai išmoko visokių pribumbasų, ir štai žiniatinklis tapo socialiniu reiškiniu, daugelio gyvenimo būdu ar bent pagalbininku. Įvairios taikomosios programos, kurias anksčiau reikėdavo diegti į kompiuterį, persikėlė į nutolusius serverius. Ir dabar jos dažnai išnaudoja pilną globalaus tinklo potencialą.

Žiniatinklio taikomųjų programų logotipai

Bendram supratimui, žiniatinklio taikomosios programos tai tokios programos, kuriomis naudojamės per naršyklę, pavyzdžiui žiniatinklio el. paštas, elektroninės parduotuvės, mainai, vikiai ar naršykliniai žaidimai. Neseniai Robert O’Callahan iš Mozillos rašė apie geras praktikas, kuriant žiniatinklio taikomąsias programas, nežiūrint į pasirinktas technologijas.

Protingas URL adresavimas. Programos URL turi būti suorganizuoti taip, kad juos būtų galima išnaudot, išsisaugant žymę del.icio.us ar siunčiant nuorodą draugui. Pavyzdžiui, aš žinau, kad įvedęs http://www.frype.lt/blogs/ ir prisijungęs, pateksiu tiesiai į frype draugų internetinių dienoraščių skiltį. Ir tuo dažnai naudojuosi.

Smėlio dėžės. Naujiems sistemų naudotojams turėtų būti sukurtos demonstracinės versijos, kitaip vadinamos smėlio dėžėmis, kur jie galėtų nesugadindami svarbių duomenų, išbandyt, kaip viskas veikia. Pavyzdžiui, SEB bankas turi demonstracinę versiją internetinės bankininkystės naudotojams, o PayPal – internetiniams verslininkiukams.

Naršyklinės programos turi būti naudojamos naršyklės kontekste. Programoje turi veikti mygtukai „atgal“ ir „į priekį“, „puslapio perkrovimas“ bei „krovimosi sustabdymas“, būsenos juosta, naršymo istorija ir t.t. Kontekstinio meniu blokavimas ar priverstinis programos atidarymas naujam lange nuo kopijavimo tikrai neapsaugo ir jokios naudos nesuteikia.

Programos turi turėt tokią vidinę struktūrą, kuri leistų naudot naršyklės savybes ir pagalbinius naršyklės įrankius. Naudotojai turi turėti galimybę manipuliuoti turinį ar išdėstymą savo patogumui: didinti tekstą, ieškoti puslapyje, pritaikyti savo stilių, ar pagerinti naudojamumą savais skriptais per Greasemonekey ar panašų įskiepį arba per bukmarkletus. Taikomosios programos turinys turi būti indeksuotinas paieškos sistemose. Žiūrint iš saugumo pusės, bet kokią programos logiką naršyklėje reikia pertikrint serveryje.

Tiesa, dauguma šių savybių tinka ne tik žiniatinklio taikomosioms programoms, bet ir socialiniams tinklams bei paprastoms informacinėms svetainėms. Žėsim, kaip viskas išsivystys ateity, bet bent kol kas kryptis aiški – internetas skatina kūrybingumą ir atvirumą. Ir man tai patinka.

Žaismingų svetainių pasiekiamumas: slapukai

Thursday, February 28th, 2008

Tavo interneto projektas spurda visokiais specialiaisiais efektais kaip kad google žemėlapiai, dinaminiai meniu ar automatinis įvedamo teksto siūlymas? Tada neišvengiamai vardan didesnio pasiekiamumo teks naudot įvairias alternatyvas lankytojams, naršantiems be Javascript. Tai reiškia, kad pilnavertiškai dinamišku atveju vienus objektus reiks slėpt, kitus – rodyt. Ir apskritai, Javascript’u varomose svetainėse dažnai tenka manipuliuot elementų slapstymusi. Šįkart mestelsiu keletą idėjų šitų slėpynių tema.

Gudrybė Nr.1. Pirmiausia reikia nuspręsti, kurie elementai ir efektai veiks tik tam tikrose naršyklėse. Pavyzdžiui, mandrą google žemėlapį rodysim ten, kur jis palaikomas. Kitiems tuo tarpu alternatyviai rodysim paprastą žemėlapio paveikslėlį. Kad susišnekėtume, pavadinkim tą spec. efektais praturtintą puslapį dinaminiu, o alternatyviąją versiją – statišku puslapiu. Statiško puslapio pranešimams apie pageidautinas naršykles ir jų nustatymus bei kitiems statiškiems elementams, kurie nebereikalingi dinaminėje versijoje, pridėkime CSS klasę to_hide. O tiems, kurie turi būti nematomi statiškoje versijoje, bet kurie draskysis puslapyje vos tik pajutę Javascript, pridėkime CSS klasę to_show. Šios klasės nurodo, ką reiks daryt skirptui dinaminiame puslapyje. Tuo tarpu CSS turi būti nurodyta:

.to_show {
    display: none;
}

Turbūt jau spėji, kad ruošiuosi pakeist elementų su CSS klasėmis .to_hide ir .to_show matomumą, puslapiui pasikrovus? Spėjimas beveik teisingas. Šitą pakeitimą reikia daryti ne puslapiui pasikrovus, o dar jam kraunantis. Antraip pasikrovimo pradžioje dinaminis puslapis sekundėlei mirktelės su statiniu turiniu, o tik paskui pasikeis. Puslapiui kraunantis, dar nėra aišku, kurie elementai turės tas klases, o kurie ne. Bet tai mums nesvarbu. Keisim aprašus CSS klasėms tiesiogiai. Pasinaudokim funkcija dyn_css_rule, kuri prideda CSS taisykles dinamiškai prie pirmojo pakrauto kaskadinių stilių failo. N.B. Kaskadiniai stiliai dokumento apraše turi būti nurodyti prieš visus Javascript.

function dyn_css_rule(sSelector, sCssText) {
    var oCss = document.styleSheets[0];
    if (oCss.insertRule) {
        oCss.insertRule(
            sSelector + " {" + sCssText + "}",
            oCss.cssRules.length
        );
    } else if (oCss.addRule) {
        oCss.addRule(sSelector, sCssText);
    }
    return sSelector + "{" + sCssText + "}";
};
dyn_css_rule("to_show", "display:block");
dyn_css_rule("to_hide", "display:none");

Taigi šiuo atveju, jei Javascript yra įjungtas, objektai su atitinkamom klasėm bus suformuoti kaip matomi ar nematomi dar puslapiui besikraunant.

Gudrybė Nr.2. Šitas triukas tai paprastas. Elementams, kurie turi būti slapstomi dinamiško puslapio naudojimo eigoje, pridėjinėsim CSS klasę hidden. Pavyzdžiui, navigacijos meniu antras lygmuo turi būti rodomas tik užvedus pele virš pirmojo lygmens nuorodos. Štai ekspromtu rašau pavyzdį mėgstamos karkasinės sistemos jQuery sintakse:

HTML:
<ul class="dyn_menu">
    <li>
        <a href="">Lietuva</a>
        <ul class="to_hide">
            <li><a href="">Vilnius</a></li>
            <li><a href="">Kaunas</a></li>
            <li><a href="">Klaipėda</a></li>
        </ul>
    </li>
    <li>
        <a href="">Deutschland</a>
        <ul class="to_hide">
            <li><a href="">Berlin</a></li>
            <li><a href="">Hamburg</a></li>
            <li><a href="">München</a></li>
        </ul>
    </li>
</ul>

CSS (žinoma, iš atskiro failo):
.hidden {
    display: none;
}

Javascript (iš atskiro failo):
$(document).ready(function() {
    $("ul.dyn_menu li").mouseover(function() {
        $(this).children("ul").removeClass("hidden to_hide");
    }).mouseout(function() {
        $(this).children("ul").addClass("hidden");
    });
});

Šitam pavyzdy, lankytojai statiškuose puslapiuose matys pilną navigaciją – valstybes su miestais, – o tuo tarpu dinamiškuose miestai standartiškai bus paslėpti. Užvedus pele virš „Lietuvos“, galvas iškiš mūsų sostinė, laikinoji sostinė ir uostamiestis. Pervedus pelę virš „Deutschland“, Lietuvos miestai iškeliaus išgert arbatos, vietą užleisdami didžiausiems Vokietijos miestams.

Gudrybė Nr.3. Jeigu dinaminiame puslapyje reikia vieno jungiklio aktyvavimu kaitalioti daugybės išsimėčiusių elementų matomumą, tuomet naudoti CSS klasę hidden nėra efektyvu. Vietoj to visiems išsimėčiusiems slapukams suteiksim CSS klasę hidable, kuri pati savaime neturės jokių stiliaus taisyklių. O tik kombinuojant kartu su kita klase collapse ji taps nematoma. Štai pavyzdėlis, kuriame priklausomai nuo žymimojo langelio būsenos, bus rodomi arba slepiami neprivalomi formos laukai.

HTML:
<form action="" method="post" id="game_options">
    <div class="to_show">
        <label for="hide_optional">Slėpti neprivalomus laukus</label>
        <input type="checkbox" id="hide_optional" />
    </div>
    <div>
        <label for="nickname">Žaidėjo vardas</label>
        <input type="text" id="nickname" name="nickname" />
    </div>
    <div class="hidable">
        <label for="avatar">Avataro URI</label>
        <input type="text" id="avatar" name="avatar" />
    </div>
    <div>
        <label for="level">Sunkumo lygis</label>
        <select id="level" name="level">
            <option value="easy">Lengvas</option>
            <option value="medium">Vidutinis</option>
            <option value="hard">Sunkus</option>
        </select>
    </div>
    <div class="hidable">
        <label for="skill">Super galia</label>
        <select id="skill" name="skill">
            <option value="flying">Skraidymas</option>
            <option value="invisibility">Nematomumas</option>
            <option value="digging">Rausimasis</option>
        </select>
    </div>
    <div><input type="submit" /></div>
</form>

CSS (iš atskiro failo):
.collapsed .hidable {
    display: none;
}

Javascript (iš atskiro failo):
$(document).ready(function() {
    $("#hide_optional").click(function() {
        if ($(this).attr("checked")) {
            $("#game_options").addClass("collapsed");
        } else {
            $("#game_options").removeClass("collapsed");
        }
    });
});

Pasikrovus statiškam puslapiui, pamatytume formą su visais įvesties laukais, išskyrus žymimąjį langelį, skirtą paslėpti neprivalomus laukus. Dinamiškame puslapyje šypsotųsi visi laukai tol, kol neužbrėžtume varnelės žymimajam langely. Varnelė paslėptų avataro ir super galios įvesties laukus.

Na ką gi. Susidomėjai, kaip matau? ;) Tai nebesislapstom, puolam prie darbo ir keliam interneto kokybę.

Patarimai apie Javascript valdiklių pasiekiamumą

Monday, January 14th, 2008

Praturtintas GUI yra vienas iš šiuolaikiško žiniatinklio reikalavimų. Svetainių išvaizda ir valdymas artėja prie diegiamų taikomųjų programų išvaizdos ir valdymo. Valdikliai (angl. widgets) tampa vis intuityvesni. Bet interneto kūrėjai bei internetinių projektų užsakovai niekuomet neturėtų pamiršti pasiekiamumo ir semantikos. Žiniatinklis pirmiausia yra informacija, o tik tada įspūdis.

Kliento pusės technologijų sluoksniai: Javascript ir CSS virš XHTML.

Technologijos turėtų pasitarnauti realiam Pasauliui, o ne atvirkščiai. Todėl tau, kaip turinio savininkui, turėtų būti įdomu platinti informaciją visais įmanomais būdais. Turinys turi būti pasiekiamas tiek standartinėse moderniose naršyklėse, tiek naršyklėse su atjungtu Javaskriptu, skaitytuvuose balsu ar mažaekraniuose prietaisuose, kaip kad PDA ar mobiliuosiuose telefonuose. Atvaizdavimas (CSS) ir specialieji efektai (Javascript) turėtų papildyti bazinį turinį (XHTML). Šios dalys turėtų būti atskirtos skirtinguose failuose ir nemaišomos. Geros praktikos taisyklė sako, kad atjungus stilių, paveikslėlius, Javaskriptą ar viską kartu, lankytojui turėtų būti įmanoma vis vien skaityti turinį ir naršyti svetainėje. Įsivaizduok situaciją, kad atvažiuoji į koncertą svetimam mieste ir tau reikia susižinoti, kokie autobusai važiuoja koncertų salės link. Kągi. Per mobilų atsidarai vietinę viešojo transporto svetainę ir susižinai kelionės maršrutą. Tačiau, jei svetainė tavo mobiliaku nepasiekiama vien dėl privalomų specifinių Javaskriptinių valdiklių, tuomet tu greičiausiai pavėluosi į koncertą ir visa tavo diena bus sugadinta.

Semantinio žiniatinklio koncepcija apibrėžia taisykles informaciniams duomenims, kurios leidžia atvaizduoti, filtruoti ir redaguoti duomenis naudojant skirtingas technologijas. Vietoj nepatikimo teksto karpymo kad gautum specifinę puslapio informaciją, turėtų būti įmanoma išanalizuoti turinį, naudojant DOM, ir gauti viso puslapio struktūrą. Tai naudinga ne tik paieškos varikliams, ber ir trečių šalių žiniatinklio ir diegiamoms taikomosioms programoms, kurios išnaudotų tavo turinį skirtinguose taikomųjų programų hibriduose (angl. mashup). Pavyzdžiui, jei turi paprastą informacinę svetainę apie savo restoraną su jo adresu ir tikriausiai gražiu dinaminiu žemėlapiuku, tuomet kita kompanija gali turėti paieškos serverį, kuris renka informaciją apie įvairius restoranus, viešbučius ir parkus bei parodo juos visus viename žemėlapyje su kiekvienos vietos reitingais, komentarais ir rekomendacijomis. Jei tavo svetainės turinys nėra semantinis, tu vargiai gausi papildomo dėmesio iš trečių šalių projektų.

Koks bebūtų svetainės verslo modelis, jei kompanija yra orientuota į ateitį, struktūrinis svetainės turinys privalo būti atskirtas nuo atvaizdavimo ir logikos. Be to, turinys turi būti pasiekiamas ir naršytinas be Javaskripto ir CSS. Visi praturtinantys GUI efektai turėtų būti pridedami papildomai Javaskriptu, kai jis aktyvuotas. Pamiršk visas pamokėles ir pavyzdžius, kuriančius dinaminį turinį su document.write ar pridedančius įvykių apdorojimą HTML elementams tiesiai žymėse. Javaskriptas privalo būti pakrautas iš atskirų failų ir jis turėtų įtakot turinį, naudojant DOM, pasikrovus puslapiui. Ši koncepcija vadinama neįkyriuoju Javascript. Skirtingų sluoksnių atskyrimas taip pat reiškia greitesnį krovimąsi, kadangi Javascript ir CSS failai dažniausiai būna parsiunčiami vienąkart, o paskui tik pakraunami iš naršyklės sparčiosios atmintinės.

NEA:


XHTML:
<a href="http://aaiddennium.com/blog/"
onclick="window.open(this.href,'','width=800,height=600');return false">
Mano blogas
<script type="text/javascript">
/* <![CDATA[ */
document.write("(atsidaro naujam lange)");
/* ]]> */
</script>
</a>

VA TAIP:


XHTML:
<a href="http://aaiddennium.com/blog/" class="new_window">
Mano blogas
</a>

Javascript (įtrauktas iš atskiro failo):
window.onload = function() {
    var aElems = document.getElementsByTagName("a");
    for (i=0, iLen=aElems.length; i<iLen; i++) {
        var oEl = aElems[i];
        if (oEl.className.match(/\bnew_window\b/)) {
            var oT = document.createTextNode("(atsidaro naujam lange)");
            oEl.appendChild(oT);
            oEl.onclick = function(e) {
                if (!e) var e = window.event;
                var oLink = e.target || e.srcElement;
                window.open(oLink.href, "", "width=800,height=600");
                e.cancelBubble = true;
                e.returnValue = false;
                if (e.stopPropagation) e.stopPropagation();
                if (e.preventDefault) e.preventDefault();
            };
        }
    }
}

Žvelgiant toliau, galima sukurti pilnai funkcionuojančią svetainę be specialiųjų efektų, o paskui pridėti Javascript, kuris pakeistų visas standartines nuorodas į Ajax’inius turinio kroviklius. Šią koncepciją Jeremy Keithin savo knygoje Bulletproof Ajax pavadino Hijax. Kaip bebūtų, Hijax būdas turi ir savo trūkumų. Pavyzdžiui, kraunant duomenis per Ajax, standartinis naršyklės Atgal/Pirmyn funkcionalumas nebetenka prasmės. O be to gana brangu dublikuot visus funkcionalumus, kuriant vieną serverio pusei ir kitą kliento pusei.

Aš sakyčiau, kad daugumoj atvejų svetainėje turėtų būti naudojama įprasta navigacija, O Javascript turėtų būti pridėtas tik specifiniams valdikliams ar specifiniams puslapiams. Javascript gali perrašyt standartines funkcijas. Pavyzdžiui, išorinės nuorodos gali būti atidarinėjamos Javaskriptu iššokančiuose languose, arba kai kurie maži formuliarai gali būti atidaromi naujuose Ajax’iniuose dialogo languose. Originali nuoroda, paversta Ajax’inio funkcionalumo jungikliu, kai kuriais atvejais gali būti nukreipta į naują puslapį, aiškinantį, kaip aktyvuoti Javascript ar kur gauti modernią naršyklę. Arba tai gali būti lokali nuoroda į to paties puslapio vietą (#) su tam tikra informacija.

Kiekvienas puslapis turėtų pateikti informaciją, kad svetaine patogiausia naudotis ją lankant moderniom naršyklėm su aktyvuotu Javascript. Ši žinutė gali būti paslėpta dinamiškai Javaskriptu, pasikrovus puslapiui, arba dar geriau – ji galėtų būti įrašyta į <noscript> bloką kuris rodomas, kai Javaskriptas neveikia. Jei pasirinkai paslėpti žinutę Javaskriptu vos tik puslapiui pasikrovus, tau gali nepatikti vaizdo mirgtelėjimas: žinutė pasirodys ir po to dings. Kad išvengtum to mirgtelėjimo, display:none stilių priskirk ne elementui, kuriame yra žinutė, pagal id po puslapio pasikrovimo, o papildomai dinamiškai pridėtai CSS taisyklei su to id selektoriumi dar puslapiui kraunantis. HTML dokumento HEAD dalis įvykdoma visuomet prieš parodant BODY.

NEA:

window.onload = function() {
    document.getElementById("warning_js").style.display = "none";
}

VA TAIP:

function dyn_css_rule(sSelector, sCssText) {
    var oCss = document.styleSheets[0];
    if (oCss.insertRule) {
        oCss.insertRule(
            sSelector + " {" + sCssText + "}",
            oCss.cssRules.length
        );
    } else if (oCss.addRule) {
        oCss.addRule(sSelector, sCssText);
    }
    return sSelector + "{" + sCssText + "}";
};
dyn_css_rule("#warning_js", "display:none");

Be viso to, niekada nereikėtų dinamiškai modifikuot HTML elementų stiliaus tiesiogiai. CSS yra atvaizdavimo sluoksnio atsakomybė, o ne logikos sluoksnio. Javascript turėtų manipuliuot semantiškais klasių vardais. Tuomet atvaizdavimo sluoksnis nuspręs, ką daryt tarkim su nesvarbiais elementais: tiesiog paslėpti, pridėt jiems permatomumą, sumažinti šriftus, ar perkelti į kitą poziciją.

NEA:

function toggle_visibility(sId, bVisible) {
    document.getElementById(sId).style.display = bVisible? "block": "none";
}

VA TAIP:

function toggle_visibility(sId, bVisible) {
    var oEl = document.getElementById(sId);
    var sClasses = oEl.className.replace(/\s*hidden\s*/g, " ");
    if (bVisible) {
        sClasses = sClasses + " hidden";
    }
    oEl.className = sClasses;
}

Net jei tu profesionalus Javaskripto koderis, vietoj gryno Javascript naudinga naudoti Javascript karkasines sistemas. Tavo rašomas kodas bus švaresnis, kadangi patys nuobodžiausi baziniai darbai jau įgyvendinti karkasinėje sistemoje. Kai tik įprasi prie sistemos, projektų vystymas pagreitės. O produktas bus patikimesnis, kadangi karkasinės sistemos kodą jau pratestavo skirtingose naršyklėse didelės bendruomenės. Tavo pasirinkta karkasinė sistema turėtų palaikyti neįkyriojo Javascript metodą ir griežtąjį XHTML. Aš asmeniškai mėgstu jQuery, bet tu gali pasirinkti bet kurią kitą karkasinę sistemą, kuri tau atrodo lengvai išmokstama.

NEA:

var aElems = document.getElementsByTagName("div");
for (i=0, iLen=aElems.length; i<iLen; i++) {
    var oEl = aElems[i];
    if (oEl.className.match(/\bspecial\b/)) {
        oEl.onclick = special_function;
    }
}

VA TAIP:

$("div.special").click(special_function);

Dirbdamas su Ajax turėtum suprasti, kad interneto greitis nėra vienodas visiems lankytojams. Taigi net jei kokių JSONu formatuotų duomenų pakrovimas tau tetrunka sekundę, kitam naudotojui su lėėėėėtu internetu ta pati užklausa gali trukti net 15 sekundžių. Todėl svetainė turėtų rodyti skirtingus identifikatorius skirtingoms būsenoms: „pradinė būsena“, „kraunama“, „rezultatas“ ir „klaida“. Priešingu atveju lankytojas gali kelis kartus spaudinėt tą patį valdiklį, stengdamasis jį paveikti. O tai gali sąlygoti atsitiktinius duomenų dublikatus bei pasimetimą. Kartais taip pat gali būti naudinga rodyti mygtuką dabartinės užklausos atšaukimui.

Gali atrodyti keista, kad neparodžiau kaip pasidaryti nei vieno pilnaverčio valdiklio, kaip kad reitingai, automatinis atsakymų parinkimas ar koks kalendorius. Bet šito rašinio tikslas buvo supažindinimas su kokybiškesniu kliento pusės programavimu. Visa kita priklauso nuo tavo kūrybingumo ir verslo reikalavimų. Patirtis ateina besipraktikuojant.

Papildomi skaitinukai:

Valdyk savo kodą su Subversion

Saturday, October 6th, 2007

Neįsivaizduoju profesionalaus IT projektų vystymo be kodo kontrolės priemonių. Nesvarbu, ar dirbi prie mažo asmeninio projektėlio, ar didelės komercinės taikomosios programos, kodo kontrolė yra tai, kas tau padės suvaldyti krūvas nuolat besikeičiančio kodo tarp daugelio kūrėjų. Tai yra, taip sakant, ATŠAUKTI funkcionalumas programavimo procese.

Kaip suvaldyti projektą tarp daugelio kūrėjų?
Kodo kontrolė turi talpyklę (angl. repository), kur laikomi kuriami failai ir kūrimo proceso duomenys. Kiekvienas kūrėjas dirba su tos talpyklės kopija. Standartiškai darbas kontroliuojant kodą vyksta taip:

  1. Pasigriebi failus iš talpyklės į savo vietinę kopiją. Šis procesas vadinamas “check-out” (pirmą kartą) arba “update” (kitus kartus).
  2. Redaguoji failus.
  3. Pasitikrini statusą, kokius failus pakeitei. Jei buvo sukurta naujų failų, juos gali pridėti į kodo kontrolę arba įrašyti į ignoruojamų failų sąrašą, kad statuso raporte jie daugiau nebepasirodytų.
  4. Tuomet tu patvirtini pasikeitimus ir jie iš tavo kopijos nusiunčiami į talpyklę. Šis procesas vadinamas “commit” arba “check-in”.

Sulig kiekvienu patvirtinimu, kodo kontrolė sukuria naujas redaguotų failų versijas. Pakeitimų patvirtinimas sugeneruoja naują reviziją (angl. revision) su automatiškai didėjančiu numeriu. Jei padarai klaidą, tu visada gali sugrįžti (angl. rollback) į buvusią kūrimo būseną pagal revizijos numerį arba datą, kada patvirtinimas buvo padarytas. Su kiekvienu patvirtinimu tu gali (ir turėtum) parašyti komentarus, kas buvo pakeista tai revizijai, tam kad vėliau būtų kur kas lengviau surasti reviziją į kurią galėtum sugrįžti. Taip pat kodo kontrolė dažniausiai leidžia pažiūrėti to paties failo pakeitimus tarp dviejų revizijų.

Talpyklė gali būti sukonfigūruota arba tame pačiame kompiuteryje arba nutolusiame serveryje. Failai gali būti kontroliuojami tiek vienam žmogui, tiek dideliam kūrėjų tinklui.

Kai pora kūrėjų modifikuoja tą patį failą, kodo kontrolė bando apjungti (angl. merge) pakeitimus faile. Jei tai nėra akivaizdu, parodomas konfliktas ir kūrėjai turi jį išspręsti savo galva. Kodo kontrolė nepriima jokių konfliktų į talpyklę. Jie turi būti ištaisyti lokaliose kopijose prieš galimybę patvirtinti pakeitimus.

Kai projektas kuriamas daugelio žmonių, yra galimybė patikrinti, kas padarė kokius pakeitimus. Taip pat yra kitų kodo kontrolės funkcionalumų, kaip kad visų failų dabartinėje revizijoje žymėjimas (angl. tagging) tam tikra simbolių eilute (pvz., laidos numeriu); skirtingų to paties projekto atšakų (angl. branch) kūrimas, arba dviejų skirtingų atšakų apjungimas (angl. merging) į vieną.

Tarp galybės kodo kontrolės sistemų aš mėgstu Subversion (SVN), kadangi ji pilnai atidirbta, patogi, stabili, o taip pat – nemokama.

Studijoje, kur dirbu, SVN naudojam CreativeCityBerlin ir kitiems projektams su Django. Talpyklė yra apsaugotam ir kiekvieno naudotojo autentikacijos prašančiame serveryje. Naudojam įvairius SVN klientus skirtingoms platformoms. Aš dažniausiai dirbu su standartiniu komandinės eilutės SVN klientu mano kūrimo aplinkoj (ant Mac OS X) ir viešame serveryje (ant Linux), kuriame laikomos svetainės. Kai kurie iš mūsų naudoja ZigVersion SVN klientą Mac’ui. Kai kurie – TortoiseSVN Windows’ams.
Daugelis, naudojantys SVN

Kaip mažą žingsnelį tolimesnio Halmos žaidimo ir kitų projektų kūrimo link, susidiegiau TortoiseSVN ir savo asmeniniame laptope. Nesu vienintelis asmuo, kuris gali patvirtinti, kad TortoiseSVN yra pats patogiausias SVN klientas žemėje šiuo metu.

Jis yra pilnai integruotas į Windows Explorer ir yra labai intuityvus. Visos kodo kontrolės funkcijos yra pasiekiamos per dešiniojo mygtuko meniu. Failų statusai yra pažymėti specialiais indikatoriais, prikabintais prie failų piktogramų (ikonėlių).

Tortoise SVN

Įdiegęs TortoiseSVN savo kompiuteryje, susikūriau talpyklę savo Halmos žaidimui lokaliai. O taip pat prasitestavimui susikūriau viešą talpyklę Google kode savo Klãvos projektui.

Jei dar nepradėjai naudoti jokio kodo kontrolės įrankio, primygtinai siūlau tai padaryt kuo anksčiau. Versijų kontrolę taip pat sėkmingai gali naudoti ne tik IT kūrėjai, bet ir rašytojai, skaitmeninio meno atstovai ar kompozitoriai.

Paprasta JavaScript’o konsolė

Tuesday, October 2nd, 2007

Ko pasigendu debugindamas JavaScript skirtingose naršyklėse – tai paprasta į FireBug panaši JavaScript’o konsolė, kur galėtum vykdyti komandas tiesiogiai bet kuriam atverstam puslapiui ir iškart gauti rezultatus.

JavaScript'o konsolė

Pavyzdžiui:
>>> document.body.innerHTML
"<div class=\"navi\">..."
parodys sugeneruotą atverto puslapio HTML kuris gali skirtis nuo puslapio išeities tekstų, nes koks JavaScript’as jau gali būti juos modifikavęs.
O
>>> document.cookie="testinis_kukis=testine_reiksme"
nustatys dokumentui testinį sausainėlį.

Kaip ypač paprastą alternatyvą JavaScript’o konsolei, parašiau Bukmarkletą/Feivletą, kuris vykdo įvestą JavaScript’o komandą ir parodo rezultatą: Paprasta JavaScript’o konsolė. Diegimas paprastas – tiesiog pridėk nuorodą prie savo Bookmarks/Favorites.

Jei turi šiek tiek laiko, nori pasipraktikuoti JavaScript’ą ir padaryti Pasaulį geresne vieta gyventi, turiu užduotį būtent tau! Sukurk atvirojo kodo visose moderniose naršyklėse veikiančią JavaScript’o konsolę, kuri galėtų būti įterpta į bet kurį puslapį feivleto/bukmarkleto pagalba. Arba sukurk feivletą/bukmarkletą, kuris pakrauna ir įterpia egzistuojančią Ext Debug Console į bet kurį žiniatinklio puslapį.
Pagalbai, kaip pakrauti JavaScript failą iš bukmarkleto/feivleto, pasinaudok pasiekiamais spausdiniais, kuriuos sukūriau anksčiau. Konsolė turėtų visus rezultatus parodyti skaitomo formato. Visi objektai turėtų pasakyti, kokius jie turi atributus, visos kolekcijos ir masyvai turėtų išdėstyti savo turinį [narys1,narys2,narys3] formate.

Tavo kodas bus peržiūrėtas ir įvertintas. Pasiūlysiu patobulinimų. Tada paimsiu interviu ir išdidžiai pabloginsiu. :D

ATNAUJINTA! Čia mano paties anksčiau tau iškeltos užduoties sprendimas: Pakrauk Firebug Lite. Veikia moderniose naršyklėse, kuriose nėra įdiegtas Firebug.

Pitonas: kepam kiaušinienę be keptuvės

Monday, September 10th, 2007

Dauguma trečių šalių Python programavimo kalbos modulių sudiegiami iš modulio išeities tekstų katalogo konsolėje vykdant:
python setup.py install
Tačiau Python programavimo kalba pradedant nuo 2.3 versijos turi ir kitokį modulio pernešimo formatą nei išeities tekstų katalogas. Išdidžiai pristatau – Pitono kiaušinis.

Pitono kiaušiniai

Pitono kiaušinis (Egg) – tai specialiai naudojimui paruoštas zip archyvas, analogija Javos stiklainiams (Jar) arba Rubio brangakmeniams (Gem). Nors kiaušiniai laikomi nulinės instaliacijos platinimo formatu, tačiau jųjų diegimui rekomenduojama susidiegti PEAK Setup Tools su easy_install moduliu. Tada kiekvieną kiaušinį diegt konsolėje vykdant:
easy_install kelias/iki/naujas_modulis-1.0-py2.4.egg.
Windows sistemoje galima dar pakoreguot registrą, kad kiaušiniai diegtųsi dukart spustelėjus ant jų.

Tačiau yra galimybė Pitono kiaušinį susidiegt ir be tų papildomų pastangų. Greičiausia tai padaryt, tiesiog nukeliant parsisiųstą *.egg failiuką į python site-packages katalogą ir failo pavadinime nutrinant versijos numerius, pvz. pervardinant naujas_modulis-1.0-py2.4.egg į naujas_modulis.egg. Blogybė ta, kad praradę tuos skaičiukus, vėliau galim nebežinot, ar turim šviežiausią versiją. Taigi mano rekomenduojamas kiaušinio diegimas būtų toks:

  1. Nukopijuoti modulį į site-packages katalogą. Taigi pavyzdžiui tame kataloge turėsim:
    naujas_modulis-1.0-py2.4.egg
  2. Tame pačiame kataloge sukurti tekstinį failą tokiu pat pavadinimu tik be skaičiukų ir plėtiniu .pth. Šiame faile įrašyti kiaušinio vardą (reliatyvų kelią iki kiaušinio failo pradedant nuo esamo katalogo). Pavyzdžiui:
    naujas_modulis.pth, kurio turinys:
    naujas_modulis-1.0-py2.4.egg

Kaip patikrinti, kad modulis įdiegtas ir veikia? Pasileidžiam Python komandinę eilutę ir vykdom:
>>> import naujas_modulis
Jei tyliai ir ramiai siūloma vesti kitą komandą ir nerodomi jokie klaidų pranešimai, tuomet diegimas pavykęs.

Sukurt kiaušinį be Setup Tools per keliolika minučių nepavyko. Tai tarkim, kiaušinių kūrimui, mielas programeri, tuos papildomus įrankius jau susidiek.

Tai tiek trumpai apie kiaušinukus.
Birutė, sakė, kiaušinius labai mėgsta. :)

Robotžmogiams: dekoratoriai programavime

Monday, June 25th, 2007

Jau turbūt kokį pusmetį programuodamas šen bei ten panaudoju Python’o dekoratorius. Tai apgaubiančios funkcijos, kurios modifikuoja kitų funkcijų ar metodų rezultatus. Vos prieš keletą dienų, aprimus darbinei įtampai, žvilgtelėjau į dekoratorių vidų ir pasiaiškinau, kaip jie veikia.

Python’e dekoratoriai naudojami taip:

from kokia.nors.biblioteka import is_sparciosios_atmintines

def gauk_atsakyma(argumentas1, argumentas2):
    # kažkokie skaičiavimai
    return atsakymas
gauk_atsakyma = is_sparciosios_atmintines(gauk_atsakyma)

arba taip:

from kokia.nors.biblioteka import is_sparciosios_atmintines

@is_sparciosios_atmintines
def gauk_atsakyma(argumentas1, argumentas2):
    # kažkokie skaičiavimai
    return atsakymas

Kaip tikriausiai susipratai, čia is_sparciosios_atmintines yra funkcijos gauk_atsakyma dekoratorius.

Nors tokio tipo dekoratorius yra Python’o išmislas, pati dekoratoriaus koncepcija turėtų veikti daugumoj interpretuojamų kalbų (PHP, Java, ActionScript ar kt.).

Dekoratoriaus vidurius pailiustruosiu JavaScript’u.

function dekoruok(dekoruojamaFunkcija) {
    function apgaubk() {
        // surenkam visus parėjusius argumentus į vieną masyvą
        var argumentai = [];
        for (i=0, len=arguments.length; i<len; i++)
            argumentai.push(arguments[i]);
        // -- čia galima modifikuoti argumentus --
        rezultatas = dekoruojamaFunkcija.apply(this, argumentai);
        // -- čia galima modifikuoti rezultatą --
        return rezultatas
    }
    return apgaubk;
}

function daryk_ka_nors(a, b, c) {
    // ...
}
daryk_ka_nors = dekoruok(daryk_ka_nors);

Viskas vyksta taip: dekoratorius priima dekoruojamąją funkciją kaip argumentą ir grąžina naują funkciją, kurioje pasirinktinai apdoroja dekoruojamosios argumentus, iškviečia pačią dekoruojamąją funkciją (nebūtinai vienąkart), pasirinktinai apdoroja jos rezultatą ir galiausiai jį grąžina.

Ilgai negalvojus, į smegeninę atėjo mintis, kur dekoratorių panaudot JavaScript programavime praktiškai. Tarkim, žiniatinklio programoje (angl. web application) būtų daugybė nuorodų, virš kurių spustelėjus, turi būti įvykdyti tam tikri skaičiavimai ar AJAX užklausos pagal verslo reikalavimus. Be kita ko, kiekvienai nuorodai turi būti atjungtas standartinis nuorodos veikimas – siuntimas į puslapį su funkcijai alternatyvia informacija ar forma, per kurią skaičiavimas ar belekas galėtų būti įvykdytas ir be JavaScript pagalbos. Taigi minėtas standartinis nuorodos veikimas gali būti atjungtas kiekvieną verslo logikos funkciją apgaubiant dekoratoriumi.

function cancelEvent(decoratedFunction) {
    /**
    Dekoratorius, atšaukiantis standartinį įvykio veikimą bei
    visų tėvinių elementų įvykių apdorojimą
    */
    function wrap() {
        var args = [];
        for (i=0, len=arguments.length; i<len; i++) {
            args.push(arguments[i]);
        }
        e = args.shift()
        if (!e) var e = window.event;
        e.cancelBubble = true;
        e.returnValue = false;
        if (e.stopPropagation) e.stopPropagation();
        if (e.preventDefault) e.preventDefault();
        return decoratedFunction.apply(this, args);
    }
    return wrap;
}

function test(key, value) {
    /**
    "Svarbi" verslo logikos funkcija, grąžinanti "svarbų" rezultatą.
    Viskas čia labai rimta.
    */
    return key + " = " + value;
}
// Dekoruojam "svarbią" funkciją.  Rezultatas tebūnie
// pavadintas kitu vardu, kad vis dar būtų įmanoma kreiptis ir į
// originalią funkciją.
var test_from_link = cancelEvent(test);

window.onload = function() {
    // pasikrovus puslapiui, susirandam nuorodą su ID "test"
    // ir priskiriam jai įvykį onclick apdorojančią funkciją, kuri
    // kvies mūsų dekoruotąją test
    document.getElementById("test").onclick = function(e) {
        alert(test_from_link(e, 'vardas', 'Aidas'));
    }
}

Beje šitame pavyzdyje darau prielaidą, kad puslapio HTML kode nėra jokių onclick atributų – tik semantiškas turinys, o JavaScript kaip ir CSS patalpinti atskiruose failuose.

Serveriniame interneto programavime dekoratoriai gali būti naudojami apriboti tam tikrų funkcijų vykdymą tik tiems lankytojams, kurie turi atitinkamas teises, kešuoti sudėtingų skaičiavimų ar teksto apdorojimo rezultatus ir tuo pačiu paimti kešuotą turinį iš sparčiosios atmintinės bei kitose situacijose (kas turit gerų idėjų – mestelkit komentaruose).

Tai tiek apie dekoratorius. Einu įsipilt tepalo.