Periferiatik, erral
zope3
Erantzunen RSSa daukagu orain
Blog produktu gisa Quills erabiltzeak, Plone eta bere inguruan sortutako zope3keria guztiak bezala, lan errepikakorrak ekiditea ekarri digu. Orain era erraz baten, nahi dugun edozeren RSSak ditugu. Hori ez dela zaila esango du batek baino gehiagok eta arrazoia du. Baina RSS horiek, RSS, ATOM, RDF edo dena delakoaren plantila behin eta berriz kopi-pasteatu gabe lortzen ditugu.
DISCLAIMER: gaurkoa astuna izan daiteke programatzailea ez bazara. Zoperi buruz ezer ez badakizu, agian zerbait txineraren antzekoa dela usteko duzu. Python ez badakizu, ikasi egin behar zenuke, ikusi ze erraza den Python idaztea.
Denaren erroan Zoperen Component Architechture delakoa dago. Honen oinarria esaldi bakarrean labur daiteke: idatzi osagai txikiak baina bere funtzioa oso definituta dutenak, horrela berrerabilgarriak izango baitira. Teoria erraza da, eta praktika ere bai, eta adibide batekin azaltzen saiatuko naiz.
Guk badakigu nolakoa izan behar duen RSS edo ATOM formatua duen jario batek. Estandarrak dira eta Interneten aurki ditzakegu euren espezifikazioak. Badakigu zein eremu diren derrigorrezkoak eta zein hautazkoak. Hori jakinda kontratu bat sinatu dezakegu: zuk izenburu bat, webgunearen URLa eta jarioan erakutsi beharreko elementuak ematen badizkidazu, nik horrekin RSS edo ATOM jario bat emango dizut. Honek tranpa bat ere badu barnean, jarioan erakutsi beharreko elementuak ere eman behar baitizkidazu. Jarri diezaiogun beste balditza bat kontratuari: elementu horietako bakoitzak, izan ditzala bere izenburua, deskribapena, testu osoa, URLa, egilea, data eta etiketak edo kategoriak emango dituzten metodo batzuk. Kontratu hori onartzen dugunez, idatz dezagun kontratu hori programazio lengoaia baten (Pythonen gure kasuan), interfaze batzuen bidez:
# Hau interfaces.py fitxategian gordeko dugu
from zope.interface import Interface
class IFeed(Interface):
""" Hau izango da gure jarioaren kontratua """
def getBaseURL():
""" Webgunearen URLa emango du metodo honek """
def title():
""" Gure jarioaren izenburua emango du metodo honek """
def getFeedEntries():
""" Metodo honek jarioan erakutsi beharreko elementuak emango dizkigu """
class IFeedEntry(Interface):
""" Hau izango da jarioan erakutsiko diren elementuek bete beharko duten kontratua """
def title():
""" Izenburua """
def description():
""" Deskribapena """
def body():
""" Testu osoa """
def getURL():
""" Elementuaren URLa """
def author():
""" Egilea """
def date():
""" Data """
def tags():
""" Etiketa edo kategoriak. Zerrenda bat itzuliko du honek """
Kontratu hori izanda RSS edo ATOM plantilla idaztea zuen esku uzten dut, baina espezifikazioari begiratzea besterik ez dago hori egiteko.
Kontratu hori baldin badaukagu, bete besterik ez dugu egin behar. Gure jarioa eta jarioan erakutsi beharreko elementuak zein diren jakin beharko dugu. Gure kasuan, jarioan erakutsi beharreko elementuak erantzunak dira, baina hementxe topatzen dugu lehen arazoa: erantzunak errepresentatzeko Ploneren objektuek ez dute IFeedEntry kontratua betetzen.
Orduan kontratua betearazi beharko diegu euren kodea aldatuz. Baina horrek arazo nabarmen bat azaleratuko digu: zer gertatuko da beste arrazoiren bategatik erantzunek beste kontratu bat bete behar badute? erantzun objektuei behin eta berriz kodea gehitzen ibili behar gara? Erantzuna ezezkoa da. Gure erantzunak kontratua betetzeko disfrazatu egin beharko ditugu, eraldatu edo adaptatu egin beharko ditugu.
Zope munduan, adapter edo eraldatzaileak, objektu bat hartu eta kontratu bat betetzeko aldaketak egiten dituzten osagaiak dira. Konbentzioz, klasearen context aldagaian gordetzen da objektua, eta bere jatorrizko metodoak erabiltzen dira kontratua betetzeko behar diren metodoak sortzeko. Ikus dezagun adibide bat erantzunekin:
# Hau syndication.py fitxategian gordeko dugu
from zope.interface import implements
from interfaces import IFeedEntry
class DiscussionFeedEntry:
""" Objektu arrunt bat sortuko dugu, IFeedEntry interfazea edo kontratua
betetzen duena, hori esateko da hurrengo implements sententzia """
implements(IFeedEntry)
def __init__(self, context):
""" Hauxe da metodo hasieratzailea, adapterra sortzerakoan
metodo honi deitzen zaio objektua context aldagaian pasatuz
eta konbentzioz context aldagaian gordetzen dugu """
self.context = context
def title(self):
return self.context.pretty_title_or_id()
def description(self):
return self.context.Description()
def body(self):
return self.context.CookedBody()
def getURL(self):
return self.context.absolute_url()
def author(self):
return self.context.Creator()
def date(self):
return self.context.created()
def tags(self):
# Erantzunek ez dute tagik edo etiketarik gure kasuan
return []
Egin dugu gure erantzunek kontratua betetzeko lana. Kontratu hori bete dugula esan behar diogu Zoperi orain, hori ZCML deritzon XMLren dialekto baten egiten da, honela:
<adapter
for="Products.CMFDefault.interfaces.IDiscussionItem"
provides=".interfaces.IFeedEntry"
factory=".syndication.DiscussionFeedEntry"
/>
Konfigurazio fitxategi horrekin, IDiscussionItem kontratua betetzen duten elementu guztiei (hori da erantzun elementuek betetzen duten kontratua), IFeedEntry kontratua betearazten dien eraldatzailea erregistratzen dugu, DiscussionFeedEntry klaseari esker.
Ez zarete galdu, ezta? Gauza bera egin beharko dugu IFeed kontratuarekin, kasu honetan blogeko erantzunen RSSa erakutsi nahi dugunez, blogarentzako eraldatzailea idatzi beharko dugu. Honela:
# hau ere syndication.py fitxategian idatziko dugu
from zope.interface import implements
from interfaces import IFeed, IFeedEntry
class WeblogRepliesFeed:
def __init__(self, context):
""" Lehen bezala, metodo hasieratzailea """
self.context = context
def getBaseURL(self):
return self.context.absolute_url()
def title(self):
return '%s - %s' % (self.context.Title(), 'Erantzunak')
def getFeedEntries(self):
""" Katalogoari eskatuko dizkiogu blog honetako erantzun guztiak
eta ondoren IFeedEntry bihurtuta bidaliko ditugu, hori baita
IFeed kontratuak eskatzen diguna """
weblog_path = '/'.join(self.context.getPhysicalPath())
brains= self.context.portal_catalog(portal_type='DiscussionItem',
path=weblog_path,
sort_on='created',
sort_order='reverse')
# Katalogoak brain izeneko objektu arin batzuk itzultzen ditu
# horietatik abiatuz jatorrizko objektuak, DiscussionItem-ak
# lortu behar ditugu, eta horiek ondoren IFeedEntry bihurtu
objects = [brain.getObject() for brain in brains]
return [IFeedEntry(obj) for obj in objects]
Azken lerro horretan dago trukoa, IFeedEntry(object) sententziarekin, Zoperen Component Architechture delakoa jartzen da martxan, object elementuaren interfazeetako bat, eta IFeedEntry interfazearen arteko bihurketa egiten duen adapter edo eraldatzaile bat bilatzeko. Gure kasuan, gorago definitutako DiscussionFeedEntry aurkituko du eta horrela IFeedEntry kontratua beteko dugu.
Geratzen den gauza bakarra, IFeed kontratua betetzen dutenentzat bista bat definitzea da, RSS eta ATOM plantilla eta IFeed interfazea lotzeko.
Beste adibide bat ikusteko, guk darabilgun Quills produktuaren syndication.py eta syndication.zcml moduluak ikus ditzakezu, basesyndication eta fatsyndication osagai txikiak nola erabiltzen dituzten ikusteko. Osagai txiki horiei esker da orain hain erraza edozeri RSS edo ATOM jarioa jartzea, plantilla ikutu beharrik gabe.
Inor heldu al da honaino? Opari bat emango diot hona heltzen den lehenari :)
Beste lau Plone prest
Iazko azaroan argitaratu genituen bi Plone webgune berri.: Goiena.net eta Unibertsitatea.net.
Aurtengo azaroa ere ez da atzean geratuko, eta argitaratu berri ditugu beste lau Plone: Karkara.com - Orio eta Aiako orainkaria, Zingizango.com - Legazpiko Euskara Elkartea, Amorebieta-Etxanoko Udala eta IMH - Elgoibarko Makina Herramintaren Institutua, azken hau Tolon eta Kororen lan itzelarekin batera.
Hurrengoak? Ba ikusiko dugu, baina azken urte honetan asko ikasi dugu. Gure Plone sektak beste partaide bat ere badu, Lur, argazkian nirekin eta Ploneren 3. bertsioaren bultzatzaile handienetakoa izan den Martin Aspelirekin ageri dena.
Hurrengo pausuak Plone 3 erabiltzea, produktuak Python arrautza bihurtzea eta Buildout erabiltzea izango dira. Badarabilt zerbait eskuartean.
Honetan aritu nahi duzu? Ez ahaztu CodeSyntaxek zu bezalako hackerrak behar ditu.
