Tag Archives: programavimas

Programavimo nuotykiai: bazinių klasių perrašymas įgyvendinant Django daugiakalbius modelius

Django yra tikrai patogi žiniatinklio karkasinė sistema Python programavimo kalbai, bet kaip ir kiekviena karkasinė sistema, ši atsineša į programavimo pasaulį savų apribojimų žiniatinklio meistrui. Django turi daug gyvenimą palengvinančių savybių: autentikacijos, sesijų, švarių URL, išvaizdos šablonų, sparčiosios atmintinės valdymą, duomenų bazės programavimo interfeisą, standartinę duomenų administravimo sistemą, statiško turinio vertimų mechanizmą ir kt., tik ne mechanizmą modeliams su daugiakalbiu turiniu, ką kiekvienas meistras turi susikurti savaip.

Trumpai supažindinsiu su Django projektų (svetainių ar žiniatinklio programų) architektūra. Įprastai kiekvienas projektas turi savo kodą, išvaizdos šablonus ir mediją. Kodas susideda iš projekto nustatymų, URL valdymo taisyklių, komandinėj eilutėj vykdomo projekto valdiklio ir atskirų taikomųjų programų (application), kurios kuriamos pagal projekto reikalavimus, pavyzdžiui blogas, forumas, galerija, naujienų prenumerata, meniu sistema, reitingai ar kt. Kiekviena taikomoji programa savo ruožtu turi modelius, reliatyvių URL valdymo taisykles ir peržiūros funkcijas. Modeliai apibūdina esybes, jų savybes, standartinės administravimo sistemos nustatymus. Kiekvieną modelį atitinka atitinka viena duomenų bazės lentelė. Pavyzdžiui toliau aprašytam puslapio modeliui modeliui bus sukurta DB lentelė puslapiai_puslapis(*) su VARCHAR(200) tipo lauku pavadinimas ir TEXT tipo lauku turinys:

# puslapiai/models.py
from django.db import models

class Puslapis(models.Model):
    pavadinimas=models.CharField("Pavadinimas", maxlength=200)
    turinys=models.TextField("Turinys")
    irasyta=models.DateTimeField("Sukūrimo data", auto_now_add=True)

    class Meta:
        ordering=["pavadinimas", "-irasyta"]
        verbose_name="puslapis"
        verbose_name_plural="puslapiai"

    class Admin:
        list_display=["pavadinimas", "turinys", "irasyta"]

    def __str__(self):
        return self.pavadinimas

Šitam modeliui bus automatiškai sukuriama sritis administravimo sistemoje. Parametras list_display nusako, kad puslapių sąraše bus rodomas pavadinimas, turinys ir sukūrimo data, ordering – kad standartiškai sąrašas bus išrūšiuotas pagal pavadinimą abėcėlės tvarka ir sukūrimo datą nuo naujausio. Daugiau apie modelių kūrimą skaityk Django dokumentacijoj.

Vienas iš paprasčiausių būdų įgyvendinti modelio daugiakalbiškumą būtų tiesiog kiekvienam daugiakalbiam laukui sukurti po grupę kopijų vertimams. Vertimai būtų neprivalomi. Laukai vertimams turėtų plėtinius su dviraidžiu kalbos kodu. Standartinės kalbos laukas neturėtų plėtinio ir būtų privalomas. Jei vertimas nerastas, rodoma standartinės kalbos lauko reikšmė. Kaip tariam, taip ir padarom:

# puslapiai/models.py
from django.db import models
from django.utils import translation
from django.utils.translation import gettext_lazy as _

class Puslapis(models.Model):
    pavadinimas=models.CharField("Pavadinimas", maxlength=200)
    pavadinimas_en=models.CharField("Title", maxlength=200)
    pavadinimas_de=models.CharField("Titel", maxlength=200)
    turinys=models.TextField("Turinys")
    turinys_en=models.TextField("Content")
    turinys_de=models.TextField("Inhalt")
    irasyta=models.DateTimeField(_("Sukūrimo data"), auto_now_add=True)

    class Meta:
        ordering=["pavadinimas", "-irasyta"]
        verbose_name=_("puslapis")
        verbose_name_plural=_("puslapiai")

    class Admin:
        list_display=["pavadinimas", "turinys", "irasyta"]

    def __str__(self):
        return self.gauk_pavadinima()

    def gauk_pavadinima(self, kalbos_kodas=None):
        return getattr(self, "pavadinimas_%s" % kalbos_kodas or \
            translation.get_language()[:2], "") or self.pavadinimas

    def gauk_turini(self, kalbos_kodas=None):
        return getattr(self, "turinys_%s" % kalbos_kodas or \
            translation.get_language()[:2], "") or self.turinys

Viskas būtų kaip ir šaunu, tik va standartinėj administravimo sistemoj objektų sąraše šiuo atveju bus rodomas tik lietuviškas pavadinimas ir turinys, ir objektai bus rūšiuojami pagal lietuvišką pavadinimą, net jei administratorius bus pasirinkęs kitą kalbą administravimui. Iš pirmo žvilgsnio atrodo, kad būtų galima tiesiog Meta klasėj rūšiavimą nurodyti priklausomą nuo šiuo metu pasirinktos kalbos:

ordering = ["lt" == translation.get_language()[:2] and "pavadinimas" \
    or "pavadinimas_%s" % translation.get_language()[:2], "irasyta"]

Deja modelio sisteminio analizavimo metu dar nėra žinoma naudotojo (administratoriaus) pasirinkta kalba ir translation.get_language() grąžina standartinę — mūsų atveju lietuvių — kalbą. Naudotojo pasirinkta kalba sistemai sužinoma tik vėliau, apdorojant modelio informaciją ir atvaizduojant jo objektus administravimo sistemoj. Laimei, atviras karkasinės sistemos kodas ir objektiškai orientuota Python prigimtis leidžia pergudrauti apribojimus. Idėja tokia: perrašysiu bazinę sąrašo (list) klasę taip, kad ji grąžintų nuo naudotojo pasirinktos kalbos priklausomus rezultatus tada, kai į ją kreipiamasi. Konstruktorius paims sąrašą simbolių eilučių, kurios nurodys reikalingus laukus. Jei eilutė baigsis vienu pabraukimo simboliu "_", tuomet laukas bus laikomas daugiakalbiu ir vietoj šitos reikšmės bus grąžinamas atitinkamas laukas, priklausantis nuo naudotojo pasirinktos kalbos.

class LaukuSarasas(list):
    def __init__(self, sarasas=[]):
        self.sarasas = sarasas

    def __iter__(self):
        return iter(self._gauk_sarasa())

    def __getitem__(self, indeksas):
        return self._gauk_sarasa()[indeksas]

    def __nonzero__(self):
        return bool(self.sarasas)

    def __len__(self):
        return len(self.sarasas)

    def __str__(self):
        return str(self._gauk_sarasa())

    def __repr__(self):
        return repr(self._gauk_sarasa())

    def _gauk_sarasa(self):
        kalbos_kodas = translation.get_language()[:2]
        rezultatas = []
        for elementas in self.sarasas:
            if elementas[:1]=="-":
                rusiavimo_tvarka = "-"
                elementas = elementas[1:]
            else:
                rusiavimo_tvarka = ""
            if elementas[:2] == "__" or elementas[-1:] != "_":
                rezultatas.append(rusiavimo_tvarka + elementas)
            else:
                if kalbos_kodas == "lt":
                    rezultatas.append(rusiavimo_tvarka + elementas[:-1])
                else:
                    rezultatas.append(rusiavimo_tvarka + elementas + kalbos_kodas)
        return rezultatas

Belieka atnaujinti mūsų pavyzdinį modelį, pasinaudojant šita mandra sąrašo klase.

# puslapiai/models.py
from django.db import models
from django.utils import translation
from django.utils.translation import gettext_lazy as _

class Puslapis(models.Model):
    pavadinimas=models.CharField("Pavadinimas", maxlength=200)
    pavadinimas_en=models.CharField("Title", maxlength=200)
    pavadinimas_de=models.CharField("Titel", maxlength=200)
    turinys=models.TextField("Turinys")
    turinys_en=models.TextField("Content")
    turinys_de=models.TextField("Kontent")
    irasyta=models.DateTimeField(_("Sukūrimo data"), auto_now_add=True)

    class Meta:
        ordering=LaukuSarasas(["pavadinimas_", "-irasyta"])
        verbose_name=_("puslapis")
        verbose_name_plural=_("puslapiai")

    class Admin:
        list_display=LaukuSarasas(["pavadinimas_", "turinys_", "irasyta"])

    def __str__(self):
        return self.gauk_pavadinima()

    def gauk_pavadinima(self, kalbos_kodas=None):
        return getattr(self, "pavadinimas_%s" % kalbos_kodas or \
            translation.get_language()[:2], "") or self.pavadinimas

    def gauk_turini(self, kalbos_kodas=None):
        return getattr(self, "turinys_%s" % kalbos_kodas or \
            translation.get_language()[:2], "") or self.turinys

Tai tiek, mieli programuotojai! Štai jums mano variantas, kaip žaist su daugiakalbiškumu. Gal kas susidomėjot Python’u ir Django? Atsiprašau visų kitų, kurie nieko nesuprato. Ir einu tūsintis :cool:.

(*) Kintamųjų vardai visuomet turėtų būti angliški, kad kodą lengviau suprastų skirtingų šalių žmonės, bet dėl aiškumo (kas yra karkasinės sistemos dalis, o kas — mano kodas) tuos vardus sulietuvinau.

SVG: Labas Pasauli!

Pastaruoju metu apsirūpinau technine literatūra. Savišvietai ir pasirėmimui programuojant, asmeniniams ir darbiniams projektams, įsigijau knygų apie Flash ActionScript’ą, suvienytą modeliavimo kalbą (UML) ir keičiamo mastelio vektorinę grafiką (SVG). O’Reilio leidykla valdo.

Štai mano pirmasis eksperimentinis SVG failiukas. Surask margutį 1.


1 Margutis (angl. Easter Egg) yra užslėptas programinės įrangos funkcionalumas, dažniausiai sukurtas dėl smagumo eilinių programuotojų be vadovybės žinios.

CSS galvosūkis: turit pasiūlymų?

Try on top
Jau kurį laiką nerašiau į blogą, nes nusprendžiau, kad „mažiau kalbų, daugiau darbų“, ir panirau į internetinio Halmos žaidimo programavimą. Žinau žinau, jis per ilgai kuriamas. Man reikėtų daugiau ryžto ir valios prisėst prie jo laisvu metu, kas nėra paprasta, kai užsikabliuoji LOST’uose ir dar pradedi sportuoti (kad nesutrūnyčiau). Bet stengiuos. Ir štai priėjau liepto galą.

Animaciniai veikėjai moka iš mažo lagaminėlio išsitraukti didelį kūjį ar kitą daiktą. O aš moku tokį HTML ir CSS fokusą: mažame lentelės langelyje patalpinu didelį kvadratą. Mano problema ta, kad IE mano fokusą interpretuoja ne taip, kaip Firefox bei Opera. Man reikia, kad didelis kvadratas būtų pakilęs virš lentelės, kurioje jis yra, o IE jis uždengiamas iškart po jo einančių langelių kraštais.

HTML pavyzdys

Gal kas nors žino, kaip IE pasiekti tokį pat rezultatą kaip su Firefox ir Opera?

XHTML skamba gerai

Visai neseniai rašiau apie Javascript tinkamumą internetiniams žaidimams. Vienas bičelis dig‘e paprieštaravo, argumentuodamas, kad Javascript’ui trūksta galimybės skleisti žaidimo garsus. Nenuleidau rankų ir pradėjau ieškoti esamų sprendimų. Radau nemažai pakvaišusių ir senovinių metodų, kaip naudoti garsus javaskriptiniame žaidime, tačiau žinojau, jog turi būti ir TEISINGAS BŪDAS — būdas, paklusnus standartams!

Jie siūlė man naudoti <bgsound> žymes, <embed> žymes, Java apletus, Flash’ą ir net <img> žymes, kad priversčiau kliento kompą grot ir dainuot. Bet šios technologijos — arba pernelyg sunkiasvorės, arba nesitaikstančios su žiniatinklio standartais.

Giliai smegenų ląstelėse žinojau, kad TEISINGAS sprendimas įtraukti mediją į tinklalapį yra <object> žymė. Ir tada visai netikėtai australų kūrėjas Karl Rudd tai nušvietė Drupal naujienų grupių gijoje.

Perrašiau jo pasiūlytą kodą iš Flash animacijos valdymo į garso valdymą. Pateiktas žymėjimas atitinka griežtą XHTML ir puikiai veikia populiariausiose standartus palaikančiose naršyklėse: IE, Firefox ir Opera).


<!--[if !IE]><-->
<object type="audio/x-wav" width="0" height="0" data="testas.wav" id="garsas">
<!--><![endif]-->
<!--[if IE]>
<object type="audio/x-wav" width="0" height="0" classid="clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95" id="garsas" class="iegarsas">
<![endif]-->
    <param name="src" value="testas.wav"></param>
    <param name="ShowAudioControls" value="false"></param>
    <param name="ShowControls" value="false"></param>
    <param name="AutoStart" value="true"></param>
    <param name="loop" value="false"></param>
    <p>Garso nėra.</p>
</object>

Reikia paaiškinimo? Še! Žymė <object> pasirodė žiniatinklio standartuose vėliau nei IE naršyklėje. IE objekto žymė laukia parametro classid (programos klasės id). Šis apibrėžia kokretų ActiveX valdiklį (pvz., Windows Media Player), kuris ir doros mediją. Pagal standartą naudojama objekto žymė tikisi parametro type (MIME tipas), kuris nurodo naršyklei naudotis įskiepiu, kuris kliento kompiuteryje susietas su tuo medijos tipu. Šį skirtumą apeiname, pasinaudami sąlyginiais komentarais. Sąlyginiai komentarai vykdo pasirinkimo logiką IE naršyklėje, tuo pat metu komentaruose (<!-- -->) paslėpdami neteisingą žymėjimą nuo kitų naršyklių ir tikrintuvų.

Naudodamas pateiktą kodą, gali į tinklalapį įterpti nesikartojantį foninį garsą. Tačiau tai dar neleidžia groti ir stabdyti garsus, esant tam tikriems įvykiams, kaip kad pelės užvedimas virš mygtuko. Metas žvilgtelt į Javascript.

Gražiausias būdas bendrauti su egzistuojančiu objektu būtų toks:


var oGarsas = document.getElementById("garsas");
oGarsas.Play();
/* Alternatyvos:
oGarsas.object.Play();
oGarsas.play();
oGarsas.object.play();
*/

Deja, tai veikia tik su tam tikrais konkrečiais per skriptą pasiekiamais įskiepiais arba ActiveX valdikliais (pvz., Windows Media Player IE naršyklėje). Kad turėtume tarpnaršyklinį ir tarpplatforminį sprendimą, naudosime „automaginį“ objekto žymės įterpimą ir ištrynimą, kur tik metodai play() ir stop() nėra palaikomi.


function stabdytiGarsa() {
    var oGarsas = document.getElementById('garsas');
    if (oGarsas && oGarsas.object) {
        oGarsas.stop();
    } else {
        oGarsas.parentNode.removeChild(oGarsas);
    }
}

function grotiGarsa() {
    var oGarsas = document.getElementById('garsas');
    if(oGarsas && oGarsas.object) {
        oGarsas.play();
    } else {
        if (oGarsas) {
            oGarsas.parentNode.removeChild(oGarsas);
        }
        var GARSO_FAILAS = 'testas.wav';
        oGarsas = document.createElement('object');
        oGarsas.setAttribute('id', 'sound');
        oGarsas.setAttribute('width', '0');
        oGarsas.setAttribute('height', '0');
        oGarsas.setAttribute('data', GARSO_FAILAS);
        oGarsas.setAttribute('type', 'audio/x-wav');
        var oParametras = document.createElement('param');
        oParametras.setAttribute('name', 'src');
        oParametras.setAttribute('value', GARSO_FAILAS);
        oGarsas.appendChild(oParametras);

        oParametras = document.createElement('param');
        oParametras.setAttribute('name', 'ShowAudioControls');
        oParametras.setAttribute('value', 'false');
        oGarsas.appendChild(oParametras);

        oParametras = document.createElement('param');
        oParametras.setAttribute('name', 'ShowControls');
        oParametras.setAttribute('value', 'false');
        oGarsas.appendChild(oParametras);

        oParametras = document.createElement('param');
        oParametras.setAttribute('name', 'AutoStart');
        oParametras.setAttribute('value', 'true');
        oGarsas.appendChild(oParametras);

        oParametras = document.createElement('param');
        oParametras.setAttribute('name', 'loop');
        oParametras.setAttribute('value', 'true');
        oGarsas.appendChild(oParametras);
        document.body.appendChild(oGarsas);
    }
}


< ![endif]-->

Garso nėra.

Pabandyk, kaip veikia skriptas, užvesdamas pelę virš šio teksto.

Taigi garsai visai kontroliuojami XHTML’e. Manau, vieną dieną reikės pažaisti su tuo daugiau.

CSS ir praturtinto teksto redaktoriai

Dažniausiai svetainėse, valdomose turinio valdymo sistemomis, turinys dedamas ne iškart dokumento <body> bloke, o giliau atskirame <div> bloke (ar — vaje, kokia gėda — lentelėje <table>). Ir neretai to vidinio bloko stilius skiriasi nuo paties dokumento stiliaus. Jei turinio valdymo sistemoje integruotas praturtinto teksto redaktorius, gebantis naudoti svetainės stilių, susiduriame su problema — redaguojamas turinys neatitinka tos išvaizdos, kuri bus svetainėje. Šios problemos sprendimas šitame straipsnyje.

Skirtingose naršyklėse veikiantys praturinto teksto redaktoriai, kaip kad TinyMCE, naudoja įterptinius rėmelius <iframe> savo pagrindui. Įterptiniui rėmeliui aktyvuojama redaguojamumo savybė, o rėmelio šaltiniu tampa naujas dokumentas su redaguojamo lauko turiniu dokumento <body> bloke. Pakraunamas svetainės pakopinių stilių failas ir redaguojamas turinys įgyja <body> žymei nurodytą stilių.

Tarkime, turime svetainę, kurioje tamsiame margame fone centruotas vienspalvis šviesus turinio blokas su tamsiom raidėm. Kai turinį redaguosim, įterptiniame rėmėlyje matysime ne tamsias raides šviesiame fone, o tamsias raides tamsiame margame fone. Taip atsitiks todėl, kad dokumento <body> stilius skiriasi nuo turinio bloko stiliaus, o praturtinto teksto redaktorius turinį deda ne į turinio bloką kaip svetainėje, o tiesiai į <body>.

Vienas iš sprendimų būtų pasiredaguoti praturtinto teksto redaktorių, kad tas apgauptų turinį atitinkamu turinio bloku, tačiau šis sprendimas gali pasirodyti komplikuotas. Reiktų įsigilinti į redaktoriaus ir turinio valdymo sistemos architektūrą, ir rašyti hakus, kurie ypač pasunkintų praturtinto teksto redaktoriaus atnaujinimą ateityje.

Mano siūlomas sprendimas būtų atitinkamai paredaguoti pakopinių stilių failą ir vienu prisilietimu pakeisti svetainės šabloną. Štai žingsniai, kuriuos reiktų atlikti:

  1. Visą <body> žymei skirtą stilių priskirti tarkim CSS klasei „websiteBody“. Pavyzdžiui, tokį:
    
    body {
        color: black; /* tamsus tekstas */
        background: brown url("tamsus_margas.jpg"); /* tamsus margas fonas*/
    }
    

    perrašom taip:

    
    body {}
    .websiteBody {
        color: black; /* tamsus tekstas */
        background: brown url("tamsus_margas.jpg"); /* tamsus margas fonas*/
    }
    
  2. Visas <body> priklausomybes perrašyti CSS klasei „websiteBody“. Pavyzdžiui, tokį:
    
    body blockquote { /* visoms citatoms, kurios yra body dalyje */
        margin: 0px;
        margin-left: 30px;
    }
    

    perrašom taip:

    
    .websiteBody blockquote { /* visoms citatoms, kurios yra body dalyje */
        margin: 0px;
        margin-left: 30px;
    }
    
  3. Turinio bloko stilių nukopijuot į <body> aprašus, kurie būtų prieš „websiteBody“ klasės aprašus. Pavyzdžiui, taip:
    
    body {
        color: black; /* tamsus tekstas */
        background: yellow; /* šviesus vienspalvis fonas*/
    }
    .websiteBody {
        color: black; /* tamsus tekstas */
        background: brown url("tamsus_margas.jpg"); /* tamsus margas fonas*/
    }
    
  4. Galiausiai <body> žymei svetainės šablone priskirti CSS klasę „websiteBody“:
    <body class="websiteBody">

Kadangi turinio valdymo sistemose naudojami praturinto teksto redaktoriai <body> žymę dokumente sukurs be CSS klasės, tai visam redaguojamam turiniui bus nurodytas toks stilius, kaip ir svetainėje turinio bloke. Tuo tarpu, svetainėje <body> stiliaus taisyklės bus perrašytos „websiteBody“ klasėje nurodytomis taisyklėmis, nes priskiriant taisykles, klasės turi didesnio prioriteto svarbą.

Šita gudrybė sėkmingai panaudota ne vienam mano projekte ir aš savo patirtį be gailesčio perduodu Tau!

Konvertuojam XLS į XML

Bevielio Interneto įsivedimo proga, pateikiu trumpą bet labai naudingą kodo gabaliuką.

Kuriam laikui teko grįžti prie Microsoft operacinės sistemos. Kuriu tokią sistemą Langams… Ne ne — šįkart programinu ne kuo nors iš Microsoft Studio. Programinu Flash ActionScript su Flash projektoriaus ZINK papildais. Tiesiog prisireikė panaudoti ActiveX konvertavimui iš Excel *.xls formato į Excel *.xml formatą, kurį palaiko Microsoft Office 2003. Mat su dvejetainiu *.xls failu nieko doro nepadarysi, kol neišsiaiškinsi XLS formato. O kai jau išsiaiškinsi — tas formatas technologiškai pasens ir teks aiškintis naują :) O štai su XML gali mandravoti. XML gali lengvai nuskaityti ActionScript’u ir panaudoti duomenis pagal pageidavimus ar reikalavimus.

Štai čia konvertavimas JScript kalba:


var oExcel = new ActiveXObject("Excel.Application");
var oWorkbook = Excel.Workbooks.Open("C:\\file.xls");
oWorkbook.SaveAs("C:\\file.xml", 46); //46-xml formatas
oExcel.Application.Quit();

Kodo gabaliukas veikia tais atvejais, kai kompiuteryje įdiegta Microsoft Office 2003. Toks kaip yra („AS IS“) gali būti panaudotas HTML programoje (HTML Application) ar kokioj Internet Explorer skirtoje Internetinėje programoje (Web Application). Šiek tiek pritaikius, galima naudoti taikomojoje programoje, įgyvendintoje su Visual Basic ar kita aukšto lygio programavimo kalba, turinčia ActiveX/COM programavimo interfeisą.

Atrodo elementariai, tačiau kad jį suformuočiau, teko kelias valandas naršyti Internete, parsisiųsti Office bandomąją versiją, prisiminti Excel makrokomandų programavimą („46“ Interne nesimėto). Šitas elementarumas, mano manymu, nevertas tiek laiko, kiek man teko prie to sugaišti, dėl to užfiksuoju šitai čia ir internautai galės susigūglinti.

AJAX karkasinės sistemos

Šį savaitgalį praleidau valandėlę lygindamas tris PHP-AJAX įrankius. Skaičiau dokumentacijas ir vadovus bei bandžiau pavyzdžius. Šis įrašas yra trumpa mano tyrimo apžvalga.

Lyginau naujausias XAJAX, XOAD ir CPAINT versijas. Visos jos yra įrankiai asinchroniniam Javascriptui ir XML su PHP skriptu serverinėj daly. Tai technologijos, kurios pradedamos naudoti visame Pasauly ir laikomos Web 2.0 koncepto dalimi. Pagrindiniai palyginimo kriterijai buvo paprastumas, lankstumas ir dokumentuotumas.

XAJAX — tai mažiausiai subrendęs įrankis. Jis neturi vadovų, tik vikiais paremtą klasės dokumentaciją. Verta tavo dėmesio nebent… Nelabai ir įsivaizduoju, kodėl turėtum pasirinkti šį įrankį šiai dienai. Manau, kad projektui trūksta dar daug darbo, kad taptų populiarus. Tik leidžia perduoti duomenis į ir iš serverio, neperkraunant HTML puslapio. Tavo informacijai, įrankio svoris serveryje — 89,2 KB.

O tai akivaizdžiai mažai, palyginus su įrankio XOAD 253 KB. XOAD yra visa konstrukcinė sistema iš didžiosios „S“. Ji susideda iš daugiau nei dešimt bazinių klasių duomenų perdavimui plius siūlo sistemos išplėtimus, kaip kad XML saugojimas į laikiną atmintį tarnybinėje stotyje ar automatinis duomenų manipuliavimas kliento pusėje, naudojant serverio pusės API. XOAD siūlo savo naudotojams klasių dokumentaciją ir nedraugišką vadovą. XOAD naudojimosi būdas yra gana komplikuotas ir reikalauja kruopštaus pasidomėjimo. Ši konstrukcinė sistema verta dėmesio… Jei turi daug laiko.

Patraukliausiu AJAX įrankiu man pasirodė CPAINT. Pirmiausia jis turi aiškius ir suprantamus vadovus ir klasės dokumentaciją. Taip pat pateikiama naudojimo pagalbinukė, greitam akies užmetimui. Nors tai ir mažiausias įrankis (tik 70,4 KB), jis turi pilnai veikiantį AJAX varikliuką ir be to leidžia parsisiųsti domenis, pavyzdžiui RSS gabalą, iš kitų domenų, savajį naudojant kaip proksi. Netgi duodamas ASP tarnybinės stoties API, jei kartais sumanytum perrašyti svetainę iš PHP į ASP (arba jei kuri svetainę ASP kalba). CPAINT yra sukurtas turint omeny skirtingų naršyklių palaikymą ir funkcinį plečiamumą. Džiaugiuos, kad atradau kažką, kas palengvins mano gyvenimą.

Reziumuojant, CPAINT skina laurus. Ir jei artimiausiu metu tektų rinktis iš paminėtų trijų įrankių, gali pasitikėt manim ir pasirinkt nugalėtoją. Arba visada turi galimybę dubliuoti kitų darbą ir susiprogramuoti dar vieną analogą nuo nulio.

Tęsiant automatizavimo temą…

Visą šią savaitę ir dar keletą dienų prieš tai teko į linuksinį serverį įdieginėti įvairias tarnybines programas kaip kad „ezmlm-idx“ — elektroninio pašto grupių tvarkytuvę. Vaje, kaip lietuviška. Nesupratusiems išverčiu — mailing listo menedžerį. Man — vindozės naudotojui — tai nauja. Išbandžiau ir išmokau nemažai komadinės eilutės gudrybių. Bet ne dėl pasigyrimo čia nusprendžiau parašyti… Noriu pasidalinti su linuksų naujokais naudingu skriptuku, kuris pratęsia pakartotinų veiksmų automatizavimo temą.

Kai kartą prireiks pakeisti vieną žodį kitu visuose katalogo failuose, pasinaudok šituo skriptuku:


#!/bin/sh
for i in /kelias/iki/tam/tikro/katalogo/*
do
echo "Vykdomas keitimas faile $i."
sed 's/keistinas_zodis/i_ka_keisti/g' $i > TMPFILE
mv TMPFILE $i
done

Viską nusikopijuoji į failą belekoks_failas, pasiredaguoji pagal poreikius, tada terminale per komandinę eilutę nurodai failui paleisties teises


# chmod +x belekoks_failas

ir paleidi failą


# ./belekoks_failas

Pakeitimai įvyksta akimirksniu. Pasitikrini, ar viskas gerai, su


# cat /kelias/iki/tam/tikro/katalogo/tam_tikras_failas

Išdidžiai pereini prie kitų darbų. Pagalvojus, kad analogiškai būtų tekę rankiniu būdu kiekvienam faile tarkim iš 40-ties vykdyti Replace funkciją, smagumui nėra ribų! Užuojauta vindozės naudotojams. Jiems skriptą reikės pasirašyti patiems.

Kai „View Source“ nepakanka…

Šiais laikais, kai aiškiai skiriamas svetainės turinys, išvaizda ir funkcionalumas į tris nepriklausomas dalis, kai programinė įranga migruoja į Internetą, kai vis dažniau racionaliai išnaudojamas dinamiškumas AJAX pavidalu, Interneto kūrėjui reikia tobulesnių įrankių, nei išeities tekstų pažiūrėjimas. Reikia įrankio, kuris leistų pažiūrėti ne tik statiškai pateikto dokumento, bet ir dinamiškai įterpto turinio elementų savybes. Reikia įrankio, kuris leistų ne tik pasitikrinti svetainės kūrėjo, bet ir standartinius naršyklės nustatymus. Reikia įrankio, kuris leistų greitai susigaudyti dokumento struktūroje, bei atskirti, kas yra turinys, o kas — dizainas.

Sutikime, kad šių dienų populiariausios naršyklės yra Firefox, Mozilla, Opera ir Internet Explorer. Jos daugmaž palaiko Interneto XHTML ir CSS standartus. Deja nelauktai pasirodantys kodo interpretacijos skirtumai dažnai nustebina ir net sunervina ne vieną Interneto svetainių ir programų kūrėją. Išgąsdina ir paprastą svetainės lankytoją netinkamai įgyvendintu dizainu kūrėjų nenumatytoje naršyklėje.

Kita problema — Javascript. Nors visos modernios naršyklės palaiko JavaScript DOM, tačiau dažnai skiriasi įvykiai (events), objektų metodai ir atributai, formatuojamo redagavimo (rich text editing) įgyvendinamumas ir kiti dalykai, galintys praturtinti naudotojo patirtį bei palengvinti naudojamumą.

Čia susigaudyti neabejotinai padėtų Interneto kūrėjams skirtos naršyklių įrankių juostos:

Protingi programuotojai katės maiše neįdieginėja, todėl jaučiu pareigą trumpai apžvelgti, kokias galimybes turi šios įrankinės.

Visų pirma tai, kas bendra:

  • Sparčiosios atmintinės, paveikslėlių, skriptų, sausainėlių ir iššokančių langų blokiklio įjungimas/išjungimas.
  • Sparčiosios atmintinės, praeities registro, sausainėlių išvalymas.
  • Sausainėlių informacijos žiūrėjimas.
  • DOM naršymas ir keitimas, dokumento elemento parodymas struktūroje bei struktūros elemento parodymas dokumente.
  • Visų nuorodų URL rodymas.
  • Elementų dimensijų rodymas.
  • Tikslus lango dimensijų keitimas.
  • Paveikslėlių informacijos rodymas.
  • Kodo teisingumo tikrinimas.
  • Nuorodos į Interneto standartus.

Taip pat IE ir FF/Moz pagal pareikalavimą išrenka ir apibraukia vienos rūšies žymes, tiesiog puslapyje parodo elementų CSS klases (class) ir identifikatorius (id), pasiekimo tvarkos indeksus (tab indexes), greitojo pasiekimo klavišus (access keys).

Be to FF/Moz ir Operai skirtos įrankių juostos dar rodo dokumento atvaizdavimo režimą (standard ar quirks), suteikia galimybę pažiūrėti HTML be CSS, tik CSS, HTML su kitu dinamiškai pakrautu CSS, keisti formų duomenų siuntimo metodus, rodyti paslėptus formos elementus, rodyti atvirus slaptažodžius įvedimo laukuose, rodyti dokumento topografinę (kas kame guli?) informaciją. Šiose naršyklėse įrankių juostas galėsite rodyti/slėpti vieno mygtuko navigacijos įrankių juostoje paspaudimu. O IE juostą laikinai paslėpsite įprastai kaip kitas juostas: View → Toolbars → Developer Toolbar.

Ir visa tai — dar ne visos gudrybės, kuriomis gali pasigirti Interneto kūrėjų įrankių juostos. Interneto dizainerius-maketuotojus IE maloniai nustebins liniuote, kuria bus galima matuoti atstumus tarp dviejų bet kurių taškų Interneto dokumente bet kuria kryptimi. FF/Moz įrankių juosta galėtų pasipuikuoti galimybe parodyti puslapio antraštes (response headers), bei galimybe priartinti dokumentą (zoom). Operos įrankinė turi pagarbiai tolerantiškus mygtukus atidaryti svetainę kitose naršyklėse bei rodo puslapio krovimosi laiką.

Tikram Interneto svetainių ir programų kūrėjui siūlyčiau susidiegti įrankių juostas į visas naršykles ir besidarbuojant nepamiršti paieškoti savo projekto skirtumų skirtingose naršyklėse. Akivaizdžių skirtumų neakivaizdžias priežastis turėtų būti nesudėtinga atrasti minėtais įrankiais. Dėl laiko stokos išsamesnės apžvalgos ir ekrano nuotraukų nedarysiu, tačiau tikiuosi, kad tai, ką kątik perskaitėte, pravers ne vienam. Taigi laukiu komentarų, pastabų ir pagyrimų :)