Címke: wordpress

Avagy hogyan migráltam a webni.innen.hu tartalmát erre a WordPress oldalra? Ebben a bejegyzésben a költöztetés első lépéséről olvashatsz: milyen, nem teljesen erre a feladatra kitalált technológiával exportáltam a régi oldalam tartalmait.

A webni.innen.hu költöztetése című bejegyzésben már nagyvonalakban leírtam a folyamatot, most egy jóval részletesebben mutatom be az első lépéseket. Ez a tapasztalatok azoknak lehetnek érdekesek, akik komplexebb weboldalak tartalmait szeretnék maguk is költöztetni.

Első lépés: a Zwiki-vel készült szájt szkrépelése

Strukturált tartalom előállítása

Egy webszájt költöztetésének első lépése, hogy a megszüntetésre ítélt szájton fent lévő tartalmat valamilyen strukturált formába öntsük. Mivel hogy esetünkben egy Zwiki tartalomkezelő rendszerrel készült szájtról beszélünk, a strukturált szón különös hangsúly van. A Wiki jellegű weboldalak egyik fő ismérve, hogy igen gyakran egy adott weblapon megjelenített összes tartalom egyetlen mezőben játszik: a Zwiki esetében például ugyanabban a sima szöveges mezőben kapott helyet az oldal tulajdonképpeni tartalma és az összes, az oldalhoz szó szerint hozzáfűzött komment. A rendszer pedig ebből az ömlesztett szövegből egy egyszerű speciális szövegformázási megoldás értelmezésével ismerte fel, hogy melyek a hozzászólások, és melyik az oldal szövegtörzse. Emiatt az oldal tartalmának strukturált letöltése során az én szkriptemnek is meg kellett találnia ezeket a jellegzetességeket, hogy külön el tudjam raktározni a szövegtörzset és az egyes hozzászólásokat.

Speciális markup formázás kezelése

További kihívás volt, hogy a Zwiki, a többi wiki rendszerrel egyetemben, egy speciális, a HTML-nél jóval egyszerűbb formázási nyelvet használ, amit egy mai tartalomkezelő rendszer nem ismer fel. Pl. a fejezetcímet és annak szintjét úgy lehetett renkívül egyszerűen meghatározni, hogy hány szóköz szerepelt egy sortörés után következő sor elején. Emiatt a szerkesztőfelületen a szerkesztőmezőből kinyert szöveggel nem sokat tudtam volna kezdeni, így a publikus felületről kellett leszedni a már HTML formátumban renderelt tartalmakat.

Letöltés emberi látogatók imitálásával

Mivel alaposan ismerek és használok egy pár web scraper / web automatizáló eszközt, ezért a költöztetésnél is erre – az eredendően az emberi látogatók imitálására épülő –technológiára esett a választásom. Mintha egy átlagos látogató végigkattintaná az összes elérhető weblapot, és lementené a saját meghajtójára. Ezzel a módszerrel nem kötött az, hogy milyen export formátumokat kínál fel a régi oldal (semmilyet), és milyen import formátumokat tesz elérhetővé az új CMS. Ezekkel az online marketing programozás-ról szóló bejegyzésemben is említett rendszerekkel bármelyik részét meg tudom szerezni egy weboldalnak, bármilyen reguláris kifejezéssel fel tudom dolgozni, továbbá tetszőleges formátumban le tudom menteni.

A letöltő (szkréper) szkript logikája

A Wiki alapú tartalomkezelő rendszereknek van egy jó tulajdonsága, ami nagyban megkönnyíti az általuk kezelt oldal összes tartalmának megtalálását: szinte mindegyiküknél van ugyanis egy tartalomjegyzék-szerű weblap, ahol az összes wikilap ki van listázva. Emiatt a letöltő szkriptnek nagyon egyszerű logikája lehetett: kinyitni a tartalomjegyzék-oldalt, leszedni az összes ottani linket, majd egyenként végigmenve a linkek listáján, megnyitni az összes lapot, megtalálni a html kódban a címet, a szülőoldalakat, a szövegtörzset és a hozzászólásokat, majd átkattintani változtatástörténet aloldalára, ahonnan a legutolsó módosítás dátumát lehetett megszerezni.

Kimenetként készült egy .csv fájl, ami az oldalhierarchiát tartalmazta: hogy melyik weblapnak melyek a szülőoldalai, egy másik .csv táblázat, ami a lapok főbb adatai (mint az eredeti URL, cím, módosítás dátuma) mellett a tulajdonképpeni szövegtörzset tartalmazta egy-egy sorban. Készült még egy fájl, ami soronként tartalmazta az összes hozzászólást, szintén főbb adataikkal, végül egy hibakeresésre szolgáló fájl, ahol ömlesztve volt a fent említett egyetlen szöveges mező tartalma a szövegtörzzsel és a hozzászólásokkal – ha netán valamit elrontottam volna az utófeldolgozásnál.

A szkript megvalósítása UBot Studio-val

Mivel az egész folyamat nem tűnt túl bonyolultnak, ezért az Ubot Studio-ra esett a választásom a megvalósításnál. Ez egy olyan vizuális programozási felületet ad, ami elsősorban kevés elágazással és egymásba ágyazott ciklussal rendelkező, lineáris logikájú szkripteknél tud jól működni. Ezt a szoftvert tulajdonképpen egy online marketingeseknek való autmatizáló rendszerként hírdetik, de a fejlesztésének eredeti célja a weboldalak szkrépelése és szpemmelése volt linkbeküldésekkel, hozzászólások elküldésével, stb. Ettől függetlenül még számos egyéb webes automatizációs feladatra használható. Egyik legjobb funkciója, hogy segítségével .exe formátumú, Windows operációs rendszereken egyszerűen futtatható programokat építhetünk. A botok futtatásához tehát nincsen szükség magára – az egyébként elég borsos árú – szoftverre. Mivel magyar nyelvterületen kb. rajtam kívül még egy-két helyen használták ezt a tartalomkezelő rendszert, ezért ezt az .exe fájlt nem raknám ki letölthető formában, de ha írsz nekem, vagy hozzászólsz ehhez a bejegyzéshez, akkor szívesen elküldöm, ha szükséged lenne a saját ZWiki oldalad költöztetéséhez erre.

A másik érdekes koncepciója az Ubot Studionak, hogy a vizuális programozási nézetből – ahol dobozokat húzkodsz, majd nyitsz meg a paraméterek beállítása céljából – át lehet váltani kódnézetbe is, ahol egy egyszerű szintaxisú kódnyelv segítségével is áttekintheted illetve szerkesztheted a szkriptedet. Egy kis türelemmel és az alábbi kód elolvasásával megértheted, hogy pontosan hogyan is épült fel ez a szkript:

 ui text box("Domain to scrape (without http(s)://):",#domain)
 allow javascript("No")
 navigate("{#domain}/FrontPage/contents","Wait")
 wait for browser event("Everything Loaded","")
 wait(5)
 set(#scraped,$scrape attribute(<class="formcontent">,"innerhtml"),"Global")
 add list to list(%pageurls,$find regular expression(#scraped,"(?<=href=\")[^\"]+"),"Delete","Global")
 loop($list total(%pageurls)) {
     set(#pageurl,$list item(%pageurls,1),"Global")
     navigate(#pageurl,"Wait")
     wait for browser event("Everything Loaded","")
     wait(5)
     set(#content,$scrape attribute(<class="content">,"innerhtml"),"Global")
     set(#content,$replace regular expression(#content,"<a\\ class=\"new\\ .+?(?=</a>)</a>","<!-- no wikipage yet -->"),"Global")
     set(#content,$replace(#content,$new line,$nothing),"Global")
     set(#content,$replace regular expression(#content,"\\t"," "),"Global")
     set(#contentonly,$replace regular expression(#content,"<p><div\\ class=\"subtopics\"><a\\ name=\"subtopics\">.+",$nothing),"Global")
     set(#contentonly,$replace regular expression(#contentonly,"<p><a name=\"comments\">.+",$nothing),"Global")
     set(#contentonly,$replace regular expression(#contentonly,"<a name=\"bottom\">.+",$nothing),"Global")
     add list to list(%parents,$scrape attribute(<class="outline expandable">,"innertext"),"Delete","Global")
     set(#parentlist,$list item(%parents,0),"Global")
     clear list(%parents)
     add list to list(%parents,$list from text(#parentlist,$new line),"Delete","Global")
     set(#parentlist,$replace(#parentlist,$new line,";"),"Global")
     set(#posttitle,$list item(%parents,$eval($subtract($list total(%parents),1))),"Global")
     set(#posttitle,$replace(#posttitle," ...",$nothing),"Global")
     if($comparison($list total(%parents),"> Greater than",1)) {
         then {
             set(#parent,$list item(%parents,$eval($subtract($list total(%parents),2))),"Global")
         }
         else {
             set(#parent,$nothing,"Global")
         }
     }
     append to file("{$special folder("Desktop")}\\{#domain}-page-hierarchy.csv","{#pageurl}    {#posttitle}    {#parent}    {#parentlist}    {$new line}","End")
     clear list(%parents)
     add list to list(%comments,$find regular expression(#content,"<p><a[^>]+name=\"msg.+?(?=<p><a[^>]+name=\"msg.+)"),"Delete","Global")
     loop($list total(%comments)) {
         set(#comment,$list item(%comments,0),"Global")
         set(#date,$find regular expression(#comment,"(?<=name=\"msg)[^@]+"),"Global")
         set(#title,$find regular expression(#comment,"(?<=<b>).+?(?=</b>\\ --)"),"Global")
         set(#title,$replace regular expression(#title,"<[^>]+>",$nothing),"Global")
         set(#author,$find regular expression(#comment,"(?<=</b>\\ --).+?(?=<a\\ href=\"{#pageurl})"),"Global")
         set(#author,$replace regular expression(#author,"<[^>]+>",$nothing),"Global")
         set(#author,$replace regular expression(#author,",\\ *$",$nothing),"Global")
         set(#comment,$find regular expression(#comment,"(?<=<br(|\\ /)>).+"),"Global")
         set(#comment,"<p>{#comment}","Global")
         set(#comment,$replace regular expression(#comment,"\\t"," "),"Global")
         append to file("{$special folder("Desktop")}\\{#domain}-page-comments.csv","    {#pageurl}    {#date}    {#title}    {#author}    {#comment}    {$new line}","End")
         remove from list(%comments,0)
     }
     navigate("{#pageurl}/history","Wait")
     wait for browser event("Everything Loaded","")
     wait(5)
     scrape table(<outerhtml=w"<table>*">,&edithistory)
     set(#lastedited,$table cell(&edithistory,0,4),"Global")
     clear table(&edithistory)
     append to file("{$special folder("Desktop")}\\{#domain}-page-content-raw.csv","{#pageurl}    {#lastedited}    {#content}    {$new line}","End")
     append to file("{$special folder("Desktop")}\\{#domain}-page-content-only.csv","{#pageurl}    {#posttitle}    {#lastedited}    {#contentonly}    {$new line}","End")
     remove from list(%pageurls,0)
 }

2. lépés: A tartalom feltöltése erre a WordPress oldalra

Miután végigment a szkript az összes tartalmon és strukturált formátumba hozta a tartalmat, majd lementette .csv fájlokba, további szkriptekre volt szükségem ahhoz, hogy ezekből a táblázatokból „táplálkozva” feltöltsem a tartalmakat a WordPress oldalra. Ennél a résznél is egy hasonló technológiához folyamodtam, tehát a szkriptem bejelentkezett az oldal admin felületére, majd megnyomta az „Új oldal létrehozása” gombot, kitöltötte a szerkesztő űrlap különböző mezőit, kiválasztotta a legördülő menükben a megfelelő opciókat, majd megnyomta a „Közzététel” gombot. Hogy hogyan és miért így csináltam, és mi volt ennek az értelme, arról talán majd egy következő bejegyzésben lesz szó.

Az elmúlt években sokat keresgéltem a Themeforest WordPress sablonjai között, de annyira nem találtam olyat, ami közelítene ahhoz, amit én mostanában a weboldalakról gondolok, úgyhogy a végén felfújtam a pofám és csináltam egy saját, ultra-minimalista, mobile-first WordPress sablont az oldalgazda.hu számára, amit ezúton teszek ingyenesen letölthetővé bárkinek.

Miért csináltam saját WordPress sablont?

Bár tulajdonképpen még mostanában sem volt különösebb gondom azzal a régebbi — azóta már a forgalomból kivont —, Blogrid nevű WP sablonnal, amit az oldalgazda.hu-n használtam, azonban valahogy nem éreztem különösen magaménak, illetve nem tetszett nekem százszázalákosan. Mivel mostanában hobbiból foglalkozok az oldalgazda.hu-val, ezért fontos számomra, hogy olyan legyen az oldal kinézete, amivel szívesen bütykölök, ráadásul kellően egyszerű, átlátható legyen a felépítése, hogy könnyen belenyúlhassak ott, és ahogy akarok.

Bár nagyon sok szuper WordPress sablon található mindenfelé, amik között számtalan kedvenc van, mint például a Mila vagy az Evolutive, a problémám ezekkel és a hozzájuk hasonló témákkal az volt, hogy túlságosan képközpontúak voltak: tehát ha kivonom a képeket a sablonok demó tartalmaiból, akkor sokkal kevésbé látványos oldalakat kapok. Másrészt viszont nagy hatással volt rám ez, a weboldalak méreteinek túlburjánzásáról szóló cikk, ezért bármennyire is tetszenek a Masonry, Isotope és hasonló Javascript megoldásokkal készített dinamikus oldalak, szerettem volna valami igazán minimalista webdizájnt készíteni saját oldalamhoz, ami csak a legszükségesebb kódmennyiséget adja hozzá a tartalomhoz. Mindemellett pedig lehetővé teszi azt, hogy arra koncentráljak, ami fontos: a tartalomra.

Mi a lényege a Sixpack sablonomnak?

  • Ultraminimalista: Mint azt a sablon elnevezése is mutatja, az egésznek az a vezérlő elve, hogy hat tartalmi egységnél egyszerre sosem lehet több a képernyőn. Mindez azt a célt szolgálja, hogy minél könnyebben, egyszerűbben áttekinthető legyenek egy adott weblap főbb üzenetei. Természetesen szkrollozással még további tartalmi egységek is elérhetőek, de még eközben sem szabad egyszerre hatnál több egységnek megjelennie.
  • Csempés: A tartalmi egységek csempeszerűen jelennek meg: szerintem nagy újítása volt a Windowsnak, amikor bevezették a csempés felületet, hiszen különböző, gyakran kis méretű képernyők esetén egyedül ez a formátum tud konzisztens megjelenést biztosítani.
  • Mobile-first: Bár a sablon fejlesztése asztali gépen történt, de az egész folyamat során elsősorban azt tartottam szem előtt, hogy a kisebb képernyőkön, a mobil eszközökön hogyan tud értelmesen megjelenni az információ úgy, hogy a sablon eredeti céljai ne csorbuljanak. Így kisebb képernyőkön még a hatnál is kevesebb, 2-3-4 tartalmi egység jelenik meg maximum egyszerre.
  • Kötött táncrend: Ezzel a sablonnal ideális kinézetű akkor lesz az oldal, ha a bejegyzések mindengyikének van egy rövid bevezetője és egy illusztrációként szolgáló, kiemelt képe. Az oldalakat (Page) és bejegyzéseket (Post) nagyon hasonlóan kezeli, szinte ugyanúgy listázza. Weboldal logó, ill. bemutatkozás helyett sticky post-ok használatával lehet olyan kiemelt információkat megjeleníteni, mint hogy mi az oldal címe, stb.

Milyen egyéb jellegzetességei vannak még?

  • Nincsenek állítható paraméterei: míg egyfelől nagyon kényelmes egy weboldal-tulajdonosnak, hogy egy vizuális kezelőfelületen testre szabja egy adott WordPress sablon kinézetét, összességében nagyon perverz, hogy a webszervernek tulajdonképpen minden weblap-megjelenítés esetén pluszban le kell kérdeznie és ki kell számolnia dolgokat ahelyett, hogy ezek az életben igen gyakran csak egyszer eldöntött változók értékei fixen be lennének drótozva.
  • JavaScript-mentes: a sablon maga nem tartalmaz egy sor JavaScript-tet sem. A különböző pluginek persze berakják a saját JavaScript fájljaikat, de a sablon működéséhez csak HTML és CSS kód kell: amit ráadásul  igyekeztem minimális mennyiségűre csökkenteni.
  • Nincsen logo, header, sidebar, widget: ez a ”rámoljunk be még az oldalsó oszlopba, láblécbe a kevésbé fontosabb dolgokat, hátha érdekel valakit” típusú hozzáállás szerintem manapság igencsak okafogyottá vált, ezért ezeket a – sztenderdnek számító — WordPress funkciókat nem építettem be a sablonba. Szintén ugyanezt gondolom a mindenhol jelen levő logókról, fejlécekről.
  • Nincsen navigációs menü, hamburger menü, stb.: manapság nagyon ritka, hogy valakit nem csak egy-egy bejegyzés erejéig tudunk weboldalunkra csábítani, ezért nem éreztem különösen fontosnak, hogy hagyományos navigációs elemek beépítésre kerüljenek a weboldal dizájnjába.
  • Oldalon belüli keresés háttérbe szorítva: a fenti ok, plusz az az evidencia, hogy a WordPress keresőfunkciói nagyon rosszak, mind arra sarkalltak, hogya honlapon ne legyen fennt egy mindenhol jelen levő keresőmező.
  • Kapcsolatfelvétel a keresőoldalon: fontosnak éreztem, hogy ha valaki mégis keres az oldalon, akkor legyen neki egy plusz opciója a találati oldalakon, amikoris tőlem, az oldal üzemeltetőjétől egy e-mailben segítséget tud kérni, ha nem talál valamit az oldalon.
  • Kapcsolatfelvétel a 404 Not found oldalon: hasonlóan fontosnak éreztem, hogy ha a látogató egy nem létező weblapot kér le a szerverről, akkor a megjlenített tartalom ne elsősorban egy hiba nyugtázásáról szóljon, hanem arról, hogy a látogató minél hamarabb megtalálja a keresett vagy ahhoz hasonló tartalmat. Ezért a hibaoldal nagyban hasonlít az oldaltérkép oldalra, és itt szintén van egy link, mely segítségével a látogatók egyszerűen egy e-mailt küldhetnek nekünk, ha nem találnának valamit.
  • Nem általános célú sablon: az egyszerűsítés értelmeszerűen korlátokat is magában hordoz, de egyébként sem volt cél, hogy minden típusú oldalt ki tudjon szolgálni a sablon – mint pl. egy webshop-ot.

Mások dolgai, amit felhasználtam a sablonhoz

Az underscores.me sablonból kiindulva alakítottam ki a magam sablonját, felhasználva a Blogger Sans betűtípust és az Alegreya Sans betűtípust.

Sixpack WordPress sablon ingyenes letöltése

Összefoglalás

Mint ahogy a webfejlesztés általában, úgy egy WordPress sablon sem lesz soha tökéletes – sosincs vége, minden órányi munkával jobb és jobb lehetne. Nyilván a mostani verzióban is vannak hibák, inkonzszisztens megoldások, továbbá már most vannak ötleteim, hogy hogyan lehetne tovább fejleszteni, azonban mostanra már remélhetőleg elérte a „megosztásra érdemes” státuszt.

Érdekes volt annyi év után megint egy komplett web design elkészítésén dolgozni, és nagyon jó érzés volt, hogy már korántsem kellett annyit a különböző böngészők hülyeségeivel szenvedni. A kétezres évekhez képest annyi volt a legfőbb változás, hogy immár nem az Internet Explorer, hanem a Safari és az iOS „furcsaságai” miatt kellett plusz dolgokat berakni a kódba – ahonnan egyébként direkt kivettem a régebbi böngészőkkel való kompatibilitást fenntartó megoldásokat.

Az oldal korántsem annyira villámgyors, mint amilyen akár lehetne is a sablon miatt. Nem jutottam ugyanis még el odáig, hogy feltegyek egy sebességre optimalizált WordPress környezetet tegyek fel egy VPS szerverre,  ne pedig egy osztott tárhelyről üzemeltessem a szájtot, mint most.

Egyszer remélhetőleg elérető lesz a sablon a hivatalos WordPress.org sablongyűjteményből is – azonban ahogy elnézem, a feltöltés után még hónapokat kell várni arra, hogy valaki egyáltalán nekilásson átnézni a sablont, és ellenőrizze, hogy megfelel-e mindenben a követelményeknek. Egyébként mindenben úgy alakítottam ki az oldalt, még ha ez plusz munkát is jelentett, mint pl. a könnyű lokalizálhatóság.

Amikor már nem elég egy sima osztott tárhely ahhoz, hogy minőségi módon kiszolgálja az egyre komplexebbé váló WordPress oldalaidat, viszont nem szeretnéd kifizetni illetve vállalni a managed WordPress hosting (WPEngine és társai) költségeit és kötöttségeit, akkor ideális választás egy VPS felhúzása. A Digitalocean nem csak azért szuper, mert hihetetlenül olcsó, hanem azért is, mert a tárhely mellé olyan tudásbázissal szolgál, ami gyakorlatilag minden szokásos beállítást részleteiben leír. Kicsit el kell molyolni, míg megtalálod az ideális beállításokat, de ha hosszú távon nem szeretnél 20-30 dollárokat kifizetni havonta egy komolyabb WP oldal hosztolásához, akkor mindenképp érdemes megfontolni.

Jó hír, hogy már a Jetpack Publicize modulja segítségével is automatikusan közzétehetjük a Google+ oldalunkon új posztjainkat

Noha én magamtól azt mondanám, hogy ingyenes WordPress sablonokat sosem érdemes használni, ez a bejegyzés néhány érdekes példával és meglátással illusztrálja, hogy az üzleti WP sablonoknak is meglehetnek a maguk problémái  a programozó és site adminisztrátor szemszögéből.