Időnként agybajt lehet kapni a drupaltól, hogy ilyen pici apróság megváltoztatása, mint egy alapértelmezett szöveg a date modulban, mennyire bonyolult. Pedig nem az, csak sokszor kideríteni nehéz, hogy merre kell nyúlkálni, most is jó időbe telt, mire erre rájötten, még friss az élmény, úgyhogy levésem gyorsban.
Nos, a date mezővel nincs többé ilyen gond, lássuk mi a helyzet, amikor már kevés a hook_form_alter ahhoz, hogy egy form bizonyos beállításait megváltoztassuk.
Szóba jöhet egyébként preprocess és egyéb varázslás is, igen ám, de kizárólag a sminkrétegből nem érünk el olyan adatokat (például az egész $form tömb), amikre esetleg szükségünk van.
Itt jegyezném meg, ha netán valami zöldséget látnál, ne habozz kommentelni, a leírtak egy részét az elmúlt órákban szedtem össze.
Nézzünk be először picit a form api mögé. Ahogy az a form apiban meg van írva, ahhoz, hogy egy form elemet a drupal kirajzoljon, meg kell adni az elem típusát, hogy például checkbox, radio vagy sima szöveges mező kell a formra. Ezekkel mindenki találkozott már, aki valaha kódból készített formot, netán hook_form_alterrel befolyásolt egy-egy elemet.
Nos, ezek az elemtípusok drupalban az ún. element-ek. A drupal saját maga is definiál egy csomó elementet (legyen már ezek után formelem típus, mert összeakad a nyelvem, ahogy hangosan olvasom..), ezek azok, amik a form api referenciaoldalán találhatók a táblázat fejlécében.
Íme egy példa a core-ból:
$types['button'] = array( '#input' => TRUE, '#name' => 'op', '#button_type' => 'submit', '#executes_submit_callback' => FALSE, '#limit_validation_errors' => FALSE, '#process' => array('ajax_process_form'), '#theme_wrappers' => array('button'), );
Ezeket a formelem típusokat a hook_element_info() függvény implementálásával lehet deklarálni. Látszik, hogy sok default értéket lehet hozzákapcsolni, saját validációs függvényt, sminkfüggvényt, feldolgozófüggvényt stb.
Na és itt jön a képbe a date modul. Az a kis szemét nem átallott saját elemtípust készíteni, és természetesen jó mélyen belekódolta azt szöveget, amit nekünk le kell cserélni. Na és vajon hogyan lehet beleszólni vajon a hook_element_info()-ban deklarált változókba? Naná, hogy a hook_element_info_alter() megvalósításával.
Amúgy ha kiváncsiak vagyunk, hogy milyen elemtípusok vannak a rendszerünkben, csináljuk meg ezt, lesz ám meglepi:
function MODULNEVE_element_info_alter(&$type) { dsm($type); }
Akkor vissza a date elemtípushoz: Ő deklarál magának egy #process függvényt, amivel a sminkfüggvényéhez készíti elő az adatokat. Nos, az sehol nincsen megszabva, hogy egyetlen #process függvényünk legyen, csapjuk tehát hozzá a sajátunkat, és módosítsuk azt, ami nekünk kell:
/** * Implementation of hook_element_info_alter(). */ function MODULNEVE_element_info_alter(&$type) { if (isset($type['date_text'])) { //We need a custom process function to modify some text $type['date_text']['#process'][] = 'MODULNEVE_text_element_process'; } } /** * Modify default description was set in date date_text process * * @param array $element * @return array * the timezone form element * * @see date_text_element_process($element, $form_state, $form) */ function MODULNEVE_text_element_process($element, $form_state, $form) { //Itt bújt el a description $element['date']['#description'] = ' ' . t('Format: mm/yyyy (eg. @date)', array('@date' => date_now()->format($element['#date_format']))); return $element; }
Igazából ennyi az egész. Igen ám, de honnan tudjam meg, hogy éppen nekünk az hook_element_info_altert kell bántani? Hát ez egy marha jó kérdés.. Én most úgy csináltam, hogy fogtam a devel_themert, belekattintok a legbelső form elemre, és elkezdtem a devel_themer ablakában visszafelé lépkedni a függvényeken. Aztán vagy rájövök valamire, vagy nem..
Előtte persze próbálkoztam hook_form_alterben debugolni, de ott sem találtam értelmeset. Talán ott érdemes megfogni, hogyha form_alterben egy legbelső elem #type értéke valami egzotikus, akkor érdemes megnézni az emlegetett hook_element_info_alterben.