Zope-ra alapozott web-helyek kialakítása

A Zope-ot bemutató cikkben ismertetett fogalmak és módszerek alkalamazása egy gyakorlati példán keresztül.

Bevezetés

A Zope kezelõfelületének használatáról, DTML scripting-rõl és Python eljárások Zope-ba integrálásáról lesz szó, amit egy kitalált feladat megvalósításával fogunk szemléltetni. Jelen cikk keretei csak az alapvetõ eszközök és technikák ismertetését teszi lehetõvé, de ezek megértése nélkülözhetetlen az összetett feladatok zope-os kivetelezése során. A Python programozási nyelv ismerete nem szükséges a megértéséhez, de legalább a Chip Magazin júliusi számában megjelent „Az árnyékban bujkáló óriáskígyó rejtelmei” címû cikket mindenkinek érdemes elolvasni.

Feladatspecifikáció

Képzeletbeli vállalatunk web-helyét szeretnénk Zope segítségével kialakítani. Legyen a vállalat neve Álomgyár és legyen két részlege Rózsaszín álom és Rémálom. A web-hellyel szemben támasztott minimális követelmények:

  1. Álomgyár és mindkét részlege külön lappal rendelkezzen és a fõlapról linkek mutassanak a részlegek lapjaira,
  2. minden lap alján cím, telefon és annak a munkatársnak a neve szerepeljen aki az adott lap tartalmával kapcsolatban bõvebb információkkal tud szolgálni,
  3. minden lapon legyen számláló,
  4. a részlegek lapjainak stílusa illeszkedjen a részleg tevékenységéhez.

Az elsõ követelmény megvalósítása

Browser-ünkel menjünk a Zope manage lapjára és a gyökér mappában Álomgyárnak hozzunk létre egy külön mappát. A mappa létrehozásának lépései:

Az idagy mappán belül hozzunk létre két mappát a két részleg számára idrem Id-val, Rémálom Title-al és idrozs Id-val, Rózsaszín álom Title-al! Ha mindezt elvégeztük, akkor az alább látható mappaszerkezettel kell rendelkeznünk:

1kep.gif (16972 bytes)

Egy másik browserban a http://localhost:9673/idagy, http://localhost:9673/idagy/idrem, http://localhost:9673/idagy/idrozs címekre pozicionálva megtekinthetjük eddigi munkánk eredményét.

A manage lapon válasszuk ki az idagy/index.html dokumentumot és a megjelenõ Edit fülön viszgáljuk meg a tartalmát:

<!--#var standard_html_header-->


<h2><!--#var title_or_id--></h2>


<p>


This is the <!--#var id--> Document.


</p>


<!--#var standard_html_footer-->

Nézzük mit is jelent az elsõ sor!. A DTML scripting - a szerver oldali HTML programozásban járatosak számára ismert - <!--#tag-név attributumok --> formátumot használja. A var a leggyakoribb DTML tag, amivel egy változó értékét helyettesítjük be a szövegbe, azaz jelen esetben a standard_html_header tartalmát. Már csak az a kérdés, hogy hol van ez a változó és hogyan tudom a tartalmát megváltoztatni? A Zope telepítés után generál egy standard_html_header DTML metódust a gyökér könyvtárba és minden mappába ez öröklõdik. Amennyiben az egész Zope-ra egységesen akarjuk megváltoztatni a tartalmát akkor átírhatjuk a gyökérben, ha csak az idagy-on belül akkor létre kell hoznunk egy standard_html_header DTML metódust az idagy mappában, ami eltakarja a gyökérben levõt. A második sorban csak a title_or_id változó szorul magyarázatra: ha a dokumentumnak van Title értéke akkor azt tartalmazza, ha nincs akkor az Id-t. Esetünkben nincs Title érték, tehát index.html feliratot fog megjeleníteni(errõl a http://localhost:9673/idagy cím megtekintésével meg is gyõzõdhetünk). A többi sor az elõzõek fényében már érthetõ. Mind a három index.html dokumentum Title változóját töltsük ki (pl. Álomgyár honlap, Rémálmok honlapja, Rózsaszín álmok honlapja), a 4. sorát pedig töröljük ki és a Change gomb megnyomásával mentsük el!

Az idagy/index.html-be tegyünk két linket, ami a részlegekre mutat: „<a href=idrem>Rémálmok honlapja</a>” és „<a href=idrozs>Rózsaszín álmok honlapja</a>”.

A második követelmény megvalósítása

A legegyszerûbb megoldás az lenne, ha minden mappa index.html dokumentumába beírnánk a szükséges információkat, de ez nem a legszerencsésebb, mert:

Ezért inkább a mappákhoz rendeljük az adatokat és minden dokumentumban csak hivatkozunk rájuk.

Elõször rendeljük az idagy mappához a cím, telefon és munkatárs adatokat! Az idagy mappát választva a jobb oldalon válasszuk a Properties fült és adjuk hozzá egyenként a változókat cim, telefon és munkatars Id-val, string Type-al és tetszõleges Value értékkel. Az Id-ban ékezet használatát nem javaslom(bár többnyire mûködik). Ha ezzel kész vagyunk csináljunk egy saját standard_html_footer-t, amit az elõzõleg létrehozott változók tartalmával fogunk kiegészíteni! Másoljuk le a gyökér standard_html_footer DTML metódusát az idagy mappába. A másolást a mappák Contents fülén található Copy és Paste gombok segítségével tudjuk végrehajtani: az elemek elõtti választó kapcsolóval kijelöljük a másolandó elemeket megnyomjuk a Copy gombot, átmegyünk a célmappába és megnyomjuk a Paste gombot. Az így létrejött standard_html_footer-t kiválasztva az Edit fülön rögtön a dokumentum elejére var tag-el szúrjuk be a korábban létrehozott változókat:

<p><!--#var cim--></p>


<p><!--#var telefon--></p>


<p><!--#var munkatars--></p>


<p><!--#var ZopeAttributionButton--></p>


</BODY></HTML>

Ha most ellenõrizzük browser-bõl oldalaink megjelenését, akkor azt tapasztalhatjuk, hogy a részlegek lapján is megjelennek az idagy-nál definiált adatok, mert a korábbiakban már említett öröklõdés lép mûködésbe, ami nekünk jól is jöhet ha például a részlegek bizonyos adatai megegyeznek a fõoldal adataival. Amennyiben bizonyos adatok a részlegnél mások mint a fõoldalon akkor azok változóit létre kell hozni a megfelelõ tartalommal a részlegek mappáinak Properties fülén.

A harmadik követelmény megvalósítása

Azt hiszem az elsõ és a második lépést már mindenki tudja: kell csinálni egy int tipusú counter változót 0 Value-val a mappák Properties fülén és var tag-el hivatkozni kell rá a standard_html_footer dokumentumban. A kérdés az, hogyan fogjuk növelni a counter változó értékét? Több lehetõség közül-demonstrációs okok miatt- "Externel Method"-os megoldást választottam. External method használata azoknak lehet kényelmes akik otthonosan mozognak a Python nyelvû programozás témakörében. Ezzel a módszerrel meglévõ eljárásainkat ill. függvényeinket tudjuk a Zope-al integrálni.

Az alábbi python függvényt fogjuk beilleszteni a rendszerbe:

def scounter(self):


    self.counter=self.counter+1

A függvény kapcsán talán csak a misztikus self argumentum igényel némi magyarázatot: ebben az esetben a self reprezentálja a mappa objektumot, azaz függvényünk a mappa metódusaként fog viselkedni. A self használata nem kötelezõ, ha nem szerepel akkor függvényünk nem fog metódusként viselkedni.

A fájlrendszerben a Zope gyökérkönyvtárában létre kell hoznunk egy Extensions nevû könyvtárat(a külsõ metódusok egyik szabványos helye) oda másoljuk be a függvényünket tartalmazó counter.py modult. Ezután a Zope manage lapján válasszuk ki az idagy mappát és Contents fülén adjunk hozzá egy External Method elemet! A megjelenõ "New External Method" lapon idscounter értéket adjunk meg Id-ként, scounter szerepeljen Function name-ként és counter Python modul file-ként majd nyomjuk meg az Add gombot!

Mostmár hivatkozhatunk eljárásunkra az idscounter néven! Mivel ez a hivatkozás outputot nem produkál, ezért nem a var tag-et használjuk hanem a call-t. A call mint neve is sugallja meghívja a paraméterként kapott elemet és nem ír ki semmit. Készítsünk egy másolatot a standard_html_header DTML metódusról is az idagy alá és ebbe tegyük bele a counter értékét növelõ külsõ metódus hívását:

<!--#call idscounter-->


<HTML><HEAD>


<TITLE><!--#var title_or_id--></TITLE>


</HEAD>


<BODY background=idbackground>

Figyelem az öröklõdés ebben az esetben is mûködik, azaz ha csak idagy rendelkezik counter változóval, akkor az minden oldal hozzáfáréseit számlálja és minden lapon ezt az összesített értéket látjuk. Ha viszont a részegyégek mappáinak is van counter változója, akkor a hozzáférések számlálása laponként külön történik és miden lapon csak az adott laphoz tartozó hozzáférések száma jelenik meg.

Egy igazán általános megoldás két külsõ metódust használna(esetleg többet is összetettebb statisztikák készítése céljából), az egyikkel a számlálót növelnénk a másikkal a mappához tartozó számláló értéket kapnánk vissza és a számlálókat egy dictionary-re alapozott adatszerkezetben tárolnánk. Ennek megvalósítását a kedves olvasókra bízom.

A negyedik követelmény megvalósítása

Az elõzõ követelményekhez képest ez már viszonylag kevés újdonságot tartalmaz. Mindegyik mappához hozzáadunk egy Image elemet(id=idbackground, Image=nekünk szimpatikus image fájl) és a standard_html_header-t kiegészítjük a szükséges információkkal(ld. 5 kép).

A „background=idbackground” helyett talán jobb megoldás „background=<!--#var "idbackground.absolute_url()"-->”-t használni, mert ekkor nem relatív elérési címet használ a Zope és így chache használata esetén a háttér csak egyszer kerül letöltésre. A másik megjegyzésem, hogy az öröklõdés itt is él, tehát ha Álomgyárunk alapvetõen Rémálomgyár, akkor elég két Image objektumot létrehoznunk: egyet az idagy és egyet az idrozs alatt és idrem az idagy hátterét fogja örökölni.

Kiegészítések

A cikk írásakor még béta változatban létezõ 2.0-ás változat az itt ismertetet DTML szintaxison kívül egy új fromátumot is támogat és a jövõben már ennek használata javasolt.

Néhány a zope.org-on megtalálható, a cikk témájához kapcsolódó dokumentáció:

Cikkben többször megemlítettük a DTML dokumentumot és a DTML metódust, de mi is a különbség közöttük? A DTML metódus mint nevébõl is sejthetõ, az õt tartalmazó mappa metódusaként viselkedik, azaz a <!--#var title_or_id --> kifejezés egy DTML metódusban az õt tartalmazó mappa Title vagy Id értékét helyettesíti be, mig ugyanez a kifejezés egy DTML dokumentumban a dokumentum Title vagy Id értékét helyettesíti be.

Összegzés

A fenti pédákkal igyekeztem megvilágítani a Zope mûködésének néhány jellegzetes vonását és talán sikerült a más fejlesztõkörnyezektõl gyökeresen eltérõ zope szemléletet is bemutatnom:

Ami kimaradt és talán egy következõ alkalmommal kerül kifejtésre:

Bízom benne, hogy az ismertetett példa és az ajánlott irodalom elégséges lesz mindenkinek a zope-os kezdõlépések megtételéhez.