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.
- 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.
- Az /admin/build/block oldal az egyetlen olyan admin oldal, ami nem használja az adminisztrációs sminket.
- A két leggyakrabban kifelejtett sminkváltozó a page.tpl.php-ben a $closure és a $tabs.
- 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.
-
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')));
- 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.
- 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.
- 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.
- 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.
- 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.
- Használjuk a coder modul-t a Drupal 6 és 7 közötti API változások kiderítéséhez.
- 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.
- 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.
- 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.
- 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ó.
-
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ó. - 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.
- 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.
- 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.
-
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.) - 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.
- Route-olás Drupalban: custom_url_rewrite_inbound() és custom_url_rewrite_outbound().
-
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. - 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.
- 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.
- 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.
- A form tömbök kulcsai azért kezdődnek kettőskereszttel (#), hogy lehessen akár újabb formokat is definiálni a tömbben.
- 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.
- Ű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.
-
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.');
- 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).
- Bármilyen HTML-t használhatunk modulunk smink függvényeiben, mert a Drupal sminkek képesek ezt később felülírni.
- Ű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).
- 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.
- 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).
- 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.
- 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.
- 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.
- A VisualjQuery.com oldalon egy hasznos, vizuális jQuery API-t találunk.
- 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.)
- HTML tipp: néhány böngésző kidobja a href attribútum nélküli A tag-eket.
-
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.) - jQuery tipp: A szelektor függvényekben használt $(this) gyorsabb, mintha újra meghívnánk az aktuális szelektort.
- 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.
- 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.
- 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).
- 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.
- 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.
Hozzászólások
Nézeteink kezelésére egy
A 44-es pontot valaki bővebben ki tudná fejteni ? Esetleg valami linket tud valaki ahol van valami bővebb információ erről ?
Hogy lesz az exportált views-ból modul ?
...mit tudok: http://web.termuves.hu
mini-modul
Kell írni egy mini-modult, ami megvalósítja a hook_views_default_views()-ot.
Pl. a Calendarba less bele, ezt használja.
Választ szeretnél? - Új kérdés, új téma - Tesztoldal - Trollkezelés - Frissítés
Geppuskakezu Nevergone :)
Geppuskakezu Nevergone :)
Sajat modulban hook_views_default_views
Igy: http://drupalcontrib.org/api/function/hook_views_default_views/6
vigyazat, kell majd hozza a hook_views_api is.
"ugyanis így akár ki is
"ugyanis így akár ki is kapcsolhatjuk a Views UI"
Tudtommal a views_ui-t bármikor kikapcsolhatjuk, ha már nem kell többet szerkeszteni a nézetet.
----
Rájöttem, miért kérdezek olyan ritkán a drupal.hu-n. Amíg szedem össze az infokat a kérdéshez, mindig rájövök a megoldásra.
18-ashoz pontos(abb)ítás
Nem csak %user és %node esetén fut le a user_load() meg a node_load(), hanem %whatever esetén is lesz whatever_load(), ha implementálva van - továbbá ha az FALSE-t ad vissza, akkor kapsz egy jó kis 403-at (vagy 404-et, nem emlékszem fejből pontosan), valamint utána az így betöltött objektumot megkapja az access és page callback is - mindenesetre lásd a PDD2 77. oldalán a Wildcards and Parameter Replacement fejezetet.
Ugy van!
Igen, barmilyen jelolot hasznalhatunk, Lasd 19.
A betoltott objektumot/objektumokat viszont csak akkor kapjak meg a callback fuggvenyek, ha megadjuk azt/azokat a 'page arguments', 'title arguments' ill. 'access arguments' kulcsokkal (igeny szerint). Pl.
Huh
Ezt irtam az eredetihez:
Nate called these magic handlers. <= He might but these are called just load functions in menu.inc. There is nothing magical about them, same as _submit or _validate for forms.
In your module, you can use $GLOBALS['conf']['cache'] = false to turn off caching for a page. <= If you want this for development reasons, then in settings.php add $conf['cache_inc'] = './includes/cache-install.inc'; this nulls every cache operation and so breaks multistep forms but otherwise it's great.
To avoid this you must unset $form_storage. <= $form_state['storage']
Use db_set_active() to switch between the database connections you have specified in your settings file on-the-fly in a routine to easily go outside of the core Drupal database for external content or data. <= and switch back ASAP as watchdog and session writes and so on will not be happy when the table they want to write is not there.
A form type ("#type") of "value" is never sent to the user but kept in the form data so you can access the data in other functions in your module. <= this is largely deprecated in Drupal 6, just use $form['#foo']. Earlier $form was not passed around so you needed the values in $form_values (which is now $form_state['values']).
Managing major patches: Create an empty module and use hook_update() to push major site configuration changes (settings, etc). <= nothing to do with patches. Good tip nonetheless.
The reason the keys in form arrays start with a pound sign is to allow the nesting of forms in the array. <= NO! It allows nesting of form _elements_. Nesting forms is a very complicated matter.
Hol?
Hol irtad ezeket az eredetihez?
moderalt kommentek
Es talan meg nem jelentek meg.
Valoban
Mar kint is van. Koszonom szepen az eszreveteleket. :)
hiba/pontosítás
A 42-esnél a megjegyzés nincs rosszul fogalmazva? Nem kéne pont az ID alapú kiválasztásnál is megadni a tag-et, hogy ne nézze végig az összeset?
Vagy ha nem, akkkor nem értem, hogy az miért jó, hogyha a böngésző beépített getElementysByTagName() eljárását használja a kódunk, és az miért nem jó, ha a getElementNameById()-t. Ide jó lenne egy kis pontosítás. Próbáltam az eredetiben megnézni, de ott ez a megjegyzés nem is szerepel.
Amúgy nagyon jó kis lista, köszi a beküldést!
--
Csonka Gergely
http://cheppers.com
nem jól gondolod
Ott kezdődik a történet, hogy ID-ből csak egy lehet az oldalon, ha az oldal szabályos.
A getElementById() egy elég gyors függvény (bár ha jól tudom, a jQuery már nem is a böngészők által megvalósított kódot használja, hanem egy jóval gyorsabb sajátot). A getElementysByTagName() is elég gyors a lehetőségekhez képest, viszont csak most jelent meg a Javascriptben olyan metódus, amivel egy adott osztály elemei is lekérdezhetőek (Selector API).
Szóval ha csak CSS osztálynevet használsz, akkor végig kell menni a DOM minden elemén egyesével, és megvizsgálni, hogy az adott elem rendelkezik-e a kért osztállyal. -> lassú
Ha használod a tag-et is a keresésnél, akkor a böngésző használhatja először a getElementysByTagName()-t azért, hogy kigyűjtse az adott típusú HTML elemeket, majd ezen az eredménylistán kell már csak végiglépkednie ciklussal, hogy az osztály egyezőségét vizsgálja. -> gyorsabb
Ha csak ID-t adsz meg, akkor nincs mese, használja a getElementNameById()-t az adott ID-jű elem elérésére, és nagyon bízik benne, hogy az oldalon nincs több ilyen ID-vel rendelkező elem. -> leggyorsabb
Ha van Tag és ID is megadva, akkor először lekéri az adott típusú elemeket a getElementysByTagName()-vel, majd abban kutakodik az adott ID-jű elem után. Plusz mivel a getElementysByTagName() eredménye nem DOM-töredék, ezért az eredményére nem használható a getElementNameById(), hanem ciklus kell -> majdnem ugyanott vagyunk, mint a második pontban.
Választ szeretnél? - Új kérdés, új téma - Tesztoldal - Trollkezelés - Frissítés
Köszönet!
Köszönet a fordításért! Igazán hasznos munka!