48 nélkülözhetetlen Drupal fejlesztői tipp a Lullabot-tól

Az alábbi tippeket Justin Emond gyűjtötte egy négynapos Lullabot tréningen, melynek fő témái a sminkelés, form API, menu API, modulfejlesztés és jQuery voltak.

  1. Mindig nyomtassuk ki a $body_classes változót a body elem class attribútumaként a sminkünkben. Ezzel számos hasznos osztály válik elérhetővé CSS-ből, pl. "front", "not-front", "logged-in", stb.
  2. Az /admin/build/block oldal az egyetlen olyan admin oldal, ami nem használja az adminisztrációs sminket.
  3. A két leggyakrabban kifelejtett sminkváltozó a page.tpl.php-ben a $closure és a $tabs.
  4. Alapvető sminkelési módszer, hogy a módosítani kívánt sablon file-t előbb átmásoljuk a sminkünkbe az őt definiáló modul könvytárából, majd a másolatot szerkesztjük, pl. node.tpl.php.
  5. A fordítható szövegekben használjunk paramétereket (ún. placeholder tokeneket), mert a fordításban lehet, hogy más lesz a szórend. Pl. 


     $variables['submitted'] = t('On @date', array('@date'=>format_date($variables['created'],'custom','F jS')));
  6. Főverziók közötti frissítéskor legjobb, ha újraírjuk az összes smink függvényt, amiket korábban felülírtunk, így biztosan nem hagyunk ki fontos kódváltoztatást.
  7. Ha nem szeretnénk használni a teljes $content változót a node.tpl.php file-okban, akkor nyugodtan hagyjuk ki. Helyette nyomtassuk ki a szükséges mezőket egyenként.
  8. Teljesítmény: nézeteknél használjuk a "Mezők" sor stílust a "Tartalom" helyett, mivel utóbbi egy-egy node_load() hívást végez a nézet minden egyes sorára, ami egyenként több mint 50 lekérdezés is lehet. A "Mezők" stílus ezzel szemben csak a valóban szükséges adatokat gyűjti össze.
  9. A dpm() függvény a – CakePHP rendkívül hasznos pr() függvényéhez hasonlóan – komplex adatok rendezett megjelenítésére való, mely főként a hibakeresésben nyújt hasznos segítséget.
  10. Saját moduljainkat tegyük egy külön csomagba, így a modul listában jól elkülönülnek majd, továbbá ezzel a későbbi fejlesztők munkáját is megkönnyítjük.
  11. Használjuk a coder modul-t a Drupal 6 és 7 közötti API változások kiderítéséhez.
  12. Hasznos szokás, ha a "$user" változónevet az aktuálisan (tehát a kód futtatásának pillanatában) az oldalra bejelentkezett felhasználó jelölésére használjuk. Az egyéb okból betöltött felhasználót tartalmazó objektum jelölésére használjuk az "$account" változónevet.
  13. Teljesítmény: A teljes variable tábla előre betöltésre kerül minden oldallekéréskor, ezért ügyeljünk rá, hogy mekkora adatot tárolunk benne.
  14. Teljesítmény: A variable_get() hívása nem kerül semmibe (nem nyúl az adatbázishoz), hiszen minden Drupal változó már a memóriában van.
  15. Ne használjuk a t() függvényt a menük "title" és "description" elemein, mert azokat a Drupal cache-ből olvassa be, így a gyorstár felépítésekori nyelv lesz úgyis a mérvadó.
  16. Használjuk a MENU_LOCAL_TASK konstanst a hook_menu()-ben az ún. fülek (tabok)
    létrehozásához, ahogy az a /node vagy /user oldalon is látható.
  17. Teljesítmény: a terjedelmes menü callback függvényeinket tegyük külön .inc file-okba a menü tömb "file" kulcsának használatával. Így hatékonyabb lesz a memóriakezelés, mivel a Drupal a .module file-okat minden oldalletöltéskor memóriába tölti, viszont a .inc file-okat csak amikor szükséges.
  18. A hook_menu()-ben létrehozott útvonalakban a %user és %node jelölők (ún. magic handler-ek) használata esetén a Drupal automatikusan meghívja a node_load() ill. user_load() eljárásait a jelölők helyén álló aktuális ID-vel. Pl. $items['node/%node/edit'] menü útvonal esetén nem kell külön betölteni a $node objektumot a callback függvényünkben.
  19. Az előzőhöz hasonlóan lehetőség van saját magic handlerek használatára is. Pl. %yourown jelölő esetén a Drupal automatikusan meghívja a yourown_load() eljárásunkat mielőtt a hozzá tartozó menü callback-et meghívná. Fontos, hogy ezek a függvények a .module file-ban legyenek.
  20. Saját modulunkban bármikor használhatjuk a 

     $GLOBALS['conf']['cache'] = FALSE;
    utasítást, hogy kikapcsoljuk a Drupal gyorsítótárát az adott oldalon. (Megjegyzés: ha az oldal már a gyorstárban van, akkor ürítsük azt, különben nem fogjuk látni az utasítás hatását.)
  21. Könnyen kideríthetjük egy webhelyről, hogy Drupal alapú-e. Nézzük meg a page expire date-et a szerver által visszaküldött HTTP header-ben. Ha ez 1978. november 19. (a Drupal készítőjének, Dries Buytaert-nak a születésnapja), akkor nagy valószínűséggel az.
  22. Route-olás Drupalban: custom_url_rewrite_inbound() és custom_url_rewrite_outbound().
  23. A megfelelő dátum mezőtípus kiválasztása CCK-ban: 

    - Date (iso date): történelmi és nem teljes dátumok tárolására alkalmas (pl. csak év és hónap).

    - Datestamp (Unix epoch): a Drupal alaprendszer által használt formátummal megegyező dátum formátum.

    - Datetime (ajánlott): natív formában tárolja a dátumot az adatabázisban, tehát így lehetőség van az adatbázis szintjén dolgozni a dátumokkal, ami gyors.
  24. Osszuk fel a sites/all/modules könvytárunkat contrib és custom alkönyvtárakra. A contrib-ba tegyük a drupal.org-ról letöltött kiegészítő modulokat, míg a custom-ba a sajátjainkat.
  25. Ha egy kiegészítő modul kódján változtatnunk kell, akkor ezt mentsük ki egy patch file-ba, így lehetőség lesz a kódváltozások verziókövetésére, valamint a javítás beküldésére. Ezeket a patch-eket egy külön könyvtárba gyűjtsük. Később, ha frissíteni kell a módosított modulokat, ellenőrizzük, hogy továbbra is szükség van-e a módosításainkra. Amennyiben egy patch bekerült a modul hivatalos kiadásába, törölhetjük. Különben egyszerűen alkalmazzuk a patch-et.
  26. Saját moduljainkban a hook_menu() legyen mindig az első függvény, mert hasznos útmutatóként szolgál arról, hogy az adott modul mit csinál és hol érhető el ez.
  27. A form tömbök kulcsai azért kezdődnek kettőskereszttel (#), hogy lehessen akár újabb formokat is definiálni a tömbben.
  28. A Drupal minden form state-hez hozzáad egy "clicked_button" attribútumot, hogy lehetővé tegye a kép típusú űrlap beküldő gombok használatát Internet Explorer-ben is, ugyanis az nem használja a beküldő gomb name attribútumát a beküldő gombokon, ahogy azt a többi böngésző teszi.
  29. Űrlap beküldésekor beágyazott mezőkön a következő módon lehet hibát jelezni: "parent][child". Példa: "home][street", ahol street a mező, home pedig az őt tartalmazó űrlap.
  30. Az előzővel megegyező feladatot lát el a form_error() függvény, azonban tisztább és érthetőbb módon működik, mint a form_set_error(). 


     form_set_error('home][street','You must enter the street address.');
    form_error($form['home']['city'], 'You must enter the street address.');
  31. Ha a $form_state['storage'] tömbelembe bármit is teszünk, akkor a Drupal figyelmen kívül hagy minden korábban definiált átirányítást (ld. $form_state['redirect']), és újraépíti az űrlapot beküldés után. Hogy ezt elkerüljük, töröljük a $form_state['storage'] elemét (ld. php unset() függvény).
  32. Bármilyen HTML-t használhatunk modulunk smink függvényeiben, mert a Drupal sminkek képesek ezt később felülírni.
  33. Űrlap építéskor a Drupal automatikusan lerendereli a $form tömb maradék elemeit, amiket mi nem rendereltünk le korábban. Tehát elegendő csak azokkal foglalkozni, amiket mi magunk szeretnék lekezelni (ld. drupal_render() eljárás).
  34. Ha menet közben külső adatbázisra szeretnénk váltani, használjuk a db_set_active() függvényt a váltáshoz. Ekkor a settings.php-ban megadott kapcsolatok közül választhatunk.
  35. A Table Wizard modul segítségével bármilyen adatbázis táblából készíthetünk saját nézetet, sőt több táblánál megadhatjuk a kulcsokat is, amik alapján össze is kapcsolhatjuk őket (ld. még Migrate modul).
  36. Ha egy űrlapelemnek beállítunk egy értéket (a "#value" kulccsal), akkor a beküldés után mindig az lesz az értéke, független attól amit a felhasználó esetleg beállított az űrlapon.
  37. A "value" típusú űrlap elemek ("#type => "value") nem jutnak el a felhasználóig. Ezek értékét az űrlap adatok között tárolja a Drupal, ahol modulunk függvényéiből érhetjük el őket.
  38. Az inline módon beszúrt JavaScript betöltéséig a böngészők nem töltenek semmi mást, tehát blokkoljuk az oldalletöltést arra az időre. Vigyázzunk ezzel.
  39. A VisualjQuery.com oldalon egy hasznos, vizuális jQuery API-t találunk.
  40. Firebug tipp: A konzol alján található ">>>" szimbólum után saját JavaScript kódot futtathatunk bármely betöltött weboldalon. (Megjegyzés: Drupal oldalakon akár jQuery kódot is, hiszen a jQuery a Drupal része.)
  41. HTML tipp: néhány böngésző kidobja a href attribútum nélküli A tag-eket.
  42. jQuery tipp: class keresése sokkal gyorsabb, ha megadjuk a HTML elem típusát is, mert ekkor a jQuery a böngészők beépített getElementysByTagName() eljárását használja. Pl. 
 

    - Gyors: $('.content');
    - Gyorsabb: $('div.content');
    (Megjegyzés: hasonlóan, ID alapú kiválasztás esetén ne használjunk tag-et, mert akkor nem használja a böngészők beépített getElementNameById() eljárását, helyette végig járja az összes lehetséges tag-et, a megadott ID után kutatva.) 

  43. jQuery tipp: A szelektor függvényekben használt $(this) gyorsabb, mintha újra meghívnánk az aktuális szelektort.
  44. Nézeteink kezelésére egy hasznos módszer, ha kiexportáljuk őket egy saját modulba. Az így kapott php kód verziókezelhető, és védett az oldal felhasználóitól, ugyanis így akár ki is kapcsolhatjuk a Views UI modult. További előnye, hogy bármikor visszatérhetünk a nézetünk egy korábbi verziójára, ha szükséges.
  45. Nagy patch-ek kezelése: készítsünk egy modult, amiben a hook_update() hurkot használva végezzük el a szükséges beállításokat. Ezután frissítsuk a patch-elni kívánt modul kódját, futtassuk az update.php-t, végül alkalmazzuk a patch-et.
  46. Mikor figyeljünk a felhasználótól származó inputtal: általánosságban kijelenthető, hogy a sablon rétegben levő adatok biztonságosak, minden e fölötti szinten már nem. Használjuk a check_plain() eljárást, ha nincs HTML az adatban, és check_markup()-ot, ha pedig van (utóbbi a webhely alapértelmezett beviteli szűrőjét használja).
  47. A Drush make modullal lehetőségünk van modulok, sminkek, telepítési profilok és külső függvény könyvtárak egy listáját előre rögzíteni egy ún. drush make file-ba, majd ezt a file-t egy drush parancsként lefuttatva egy üres Drupal odalt kapunk pillanatok alatt, a megadott kiegészítőkkel. Előnye, hogy nem kell újra és újra ismételgetni az unalmas feladatokat minden egyes új projekt kezdetén.
  48. Használjuk a cache_get() és cache_set() eljárásokat ahol csak lehet, hiszen a gyorstárból jövő adatok jóval kevesebb adatbázis terhelést okoznak.


Jelen írás egy fordított kivonat, melyet zserno készített. Az eredeti itt található:
http://www.missingfeatures.com/2010/02/16/48-essential-drupal-developmen...

Köszönet drifternek, hogy megmutatta az eredeti cikket twitteren: http://twitter.com/drifter/status/13919347596!

Ha bármi hasznos tipped van amit nem találsz a fenti listában, kérlek írd meg hozzászólásban.