Jelen írás egy fordított kivonat, melyet zserno készített. Az eredeti itt található:
http://www.trellon.com/content/blog/cck-creating-new-field-types
A CCK a legfontosabb rövidítés, amit ismernünk kell ha a Drupal tartalomkezeléséről beszélünk. Az eredeti rövidítés a Content Construction Kit szavakból áll össze, ami egy olyan keretrendszer, melynek segítségével egy webhely felhasználói különféle információkat küldhetnek be.
A többi Drupal kiegészítőhöz hasonlóan a CCK igazi szépsége sem csupán az általa kínált funkcionalitásban rejlik, hanem sokkal inkább a többi modul számára kínált kibővíthetőségében. A CCK API lehetővé teszi más modulok számára, hogy saját mezőtípusokat definiáljanak, melyek aztán tökéletesen illeszkednek a Drupal platformba.
A CCK sikerét jól jellemzi, hogy nagy részét már a Drupal 7-es alapcsomag is tartalmazza
A legismertebb CCK-ra épülő modulok a Filefield, Imagefield, Emfield, Link és Email, de összesen közel 300 CCK-val cimkézett Drupal 6 modul található a http://drupal.org-on. Függetlenül a felhasználási területtől, ezek mindegyike a CCK API-ját használva képes saját mezőtípusait definiálni, melyek azután bármelyik tartalomtípusban felhasználhatók.
Egy egyszerű példaként Matthias Hutterer Email modulját fogjuk megvizsgálni. Ez a modul a CCK API-t használva egy saját mezőtípust deklarál, amivel megfelelően formázott e-mail címeket tárolhatunk saját tartalomtípusainkban. Meg fogjuk vizsgálni a kulcsfontosságú függvényeket, amik az egyedi mezőtípus definiálásához szükségesek, és ahol szükséges, rövid magyarázattal szolgálunk a konfigurációs lehetőségekről.
Kezdjük a hozzávalókkal (a legfőbb hook-ok és eljárások, amiket használhatunk):
- Telepítés:
- content_notify
- Mező beállítások (field settings):
- hook_field_info
- hook_field_settings
- hook_field
- Felületi elemtípus beállítások (widget settings):
- hook_widget_info
- hook_widget_settings
- hook_widget
- hook_elements
- Sminkelés (theming):
- hook_theme + theme_MY_ELEMENT
- custom formatters
A lista hosszú, vágjunk is bele.
Telepítés
Első lépésként tudatnunk kell a CCK-val, hogy modulunk mikor áll használatra készen:
function email_install() { drupal_load('module', 'content'); content_notify('install', 'email'); }
A *.install file-ban közölhetjük vele, amikor modulunk telepítése, engedélyezése, kikapcsolása vagy eltávolítása zajlik. Ezt a megfelelő hook-ban (pl. hook_install, hook_enable, stb), a megfelelő paraméterrel (install, enable, stb.) meghívott content_notify CCK eljárással tehetjük meg.
Mező beállítások
Az email.module file-ban látható, ahogy a mező formát ölt.
A fenti kóddal regisztráltuk a mezőnket, az "email" belső azonosítóval és egy "Email" címkével.
function email_field_settings($op, $field) { switch ($op) { case 'database columns': $columns['email'] = array('type' => 'varchar', 'length' => 255, 'not null' => FALSE, 'sortable' => TRUE); return $columns; } }
Itt az Email modul arra kéri a CCK-t, hogy kezelje ő a szükséges adatbázissal kapcsolatos teendőit. Egy külön oszlopot kér az őt használó tartalomtípusok tábláiban. Az oszlop elnevezése a majdan létrehozott mezők nevétől függően mindig "field_MEZŐNÉV_email" alakú lesz, beállításait pedig a $columns['email'] tömbben megadott jellemzők határozzák meg. Az $op változó a "database columns" értéken kívül még a "form" szöveget is tartalmazhatja, amivel egyedi űrlap készíthető a további szükséges beállításoknak (ld. a CCK Text modulját).
Végül nézzük hogyan tudjuk validálni a mezőnk tartalmát.
function email_field($op, &$node, $field, &$items, $teaser, $page) { switch ($op) { case 'validate': if (is_array($items)) { foreach ($items as $delta => $item) { if ($item['email'] != '' && !valid_email_address(trim($item['email']))) { form_set_error($field['field_name'],t('"%mail" is not a valid email address',array('%mail' => $item['email']))); } } } break; //...
Ha a mezőnek van értéke, akkor a fenti kód a Drupal valid_email_address eljárásával ellenőrzi, hogy az valódi e-mail cím-e.
Felületi elemtípus beállítások
Miután felvázoltuk a mezőtípusunk logikai összetevőit, jöhet a felületi elemtípus (ún. widget) űrlapjának definiálása, hogy a végleges HTML űrlapelem megkaphassa a megfelelő attribútumokat. A hook_field* függvényekhez hasonlóan a hook_widget* függvényeknek is van _info és _settings változata.
function email_widget_info() { return array( 'email_textfield' => array( 'label' => t('Text field'), 'field types' => array('email'), 'multiple values' => CONTENT_HANDLE_CORE, 'callbacks' => array( 'default value' => CONTENT_CALLBACK_DEFAULT, ), ), ); } //… function email_widget_settings($op, $widget) { switch ($op) { case 'form': $size = (isset($widget['size']) && is_numeric($widget['size'])) ? $widget['size'] : 60; $form['size'] = array( '#type' => 'textfield', '#title' => t('Size of textfield'), '#default_value' => $size, '#element_validate' => array('_email_widget_settings_size_validate'), '#required' => TRUE, ); return $form; case 'save': return array('size'); } }
Vegyük észre hogy a hook_widget_info a hook_field_info-val hasonló struktúrát használ (name és label kulcsok), azonban kiegészíti a felhasználható mezőtípusok listájával ('field types' => array('email')).
A hook_field_settings-hez hasonlóan, a hook_widget_settings-ben is lehetőség van finomítani a beállítások űrlapján (kettőjük végeredményét látjuk az "admin/content/node-type/[TARTALOMTÍPUS NEVE]/fields/[MEZŐNÉV]" útvonalon).
Az Email modul (akárcsak a Text modul) ezt arra használja, hogy a "size" mezőnek (mely a bevihető szöveg maximális hosszát határozza meg) biztosan legyen értéke.
Ahhoz, hogy az űrlapelemünk megjelenjen az űrlapon, a hook_widget-et kell használnunk:
function email_widget(&$form, &$form_state, $field, $items, $delta = 0) { $element = array( '#type' => $field['widget']['type'], '#default_value' => isset($items[$delta]) ? $items[$delta] : '', ); return $element; }
Tehát amikor a CCK hozzáadja a mezőnket az űrlaphoz, tudatjuk vele, hogy állítsa be a megfelelő widget típust (ez esetünkben az "email_textfield") és az alapértelmezett értéket, ha az létezik. Ha a modulunk több widget típust is használna, akkor itt a widget típus szerinti feltételes elágazással tudnánk a megfelelő attribútumokat beállítani. A legtöbb esetben azonban a fenti függvény elegendő (bővebben: nodereference.module).
Miután minden szükséges információt tudattunk a CCK-val, még a Drupal Form API-jának is el kell magyarázni, hogy miként bánjon a mezőnkkel. Ezt a hook_elements függvénnyel tehetjük meg:
function email_elements() { return array( 'email_textfield' => array( '#input' => TRUE, '#columns' => array('email'), '#delta' => 0, '#process' => array('email_textfield_process'), ), ); }
Vegyük észre, hogy itt az "email" azonosító helyett az "email_textfield"-et használjuk, mert a Fom API az új widget-re kíváncsi, amit még a hook_widget_info-ban a mezőnkhöz kapcsoltunk. Továbbá azt is megmondjuk, hogy hol találja az új űrlapelem feldolgozásakor használandó kódot: '#process' => array('email_textfield_process').
Az eddig tárgyalt függvények mind az új mezőnk létrehozásával foglalkoztak: definiálták annak beállításait és létrehozták a szükséges widget-et. Egyikük sem foglalkozott azonban azzal, hogy a Drupal hogyan is fogja a widget-ünket szabályos HTML űrlapelemként megjeleníteni egy node szerkesztő form-on. Ennek leírása a (hook_elements-ben már említett) "#process" attribútumban megadott callback függvénnyel tehető meg:
function email_textfield_process($element, $edit, $form_state, $form) { $field = $form['#field_info'][$element['#field_name']]; $field_key = $element['#columns'][0]; $delta = $element['#delta']; $element[$field_key] = array( '#type' => 'textfield', '#title' => $element['#title'], '#description' => content_filter_xss($field['widget']['description']), '#required' => $element['#required'], '#maxlength' => 255, '#size' => !empty($field['widget']['size']) ? $field['widget']['size'] : 60, '#attributes' => array('class' => 'text', 'dir' => 'ltr'), '#default_value' => isset($element['#value'][$field_key]) ? $element['#value'][$field_key] : NULL, ); return $element; }
A Form API-t ismerőknek ez a kódrészlet már első ránézésre sokat elárul. A mezőnk egy szöveges beviteli mező (textfield) lesz, melyhez felhasználtuk a korábban definiált mező- és widget beállításokat ('widget' kulcs a fenti kódban), valamint a CCK-tól kapott információkat (ilyen pl. az $element['#title'], ami a "Mezők kezelése" oldalon egy új mezőcímke beküldésekor kerül beállításra).
Most hogy a CCK már tud az új mezőtípusunkról és a FAPI is tudja, hogy miként jelenítse meg azt a node szerkesztő űrlapon, nincs más hátra, mint az összegyűjtött adatok sminkelése.
Sminkelés
A hook_elements meghívásakor a Drupal feltételezi, hogy léteznek a deklarált elemekhez azok sminkfüggvényei is. Így pl. az Email modul esetében mivel az egyetlen deklarált elemünk az "email_textfield" volt, ezért létre kell hoznunk egy "theme_ email_textfield" nevű sminkfüggvényt. Habár a Drupal automatikusan összekapcsolja az űrlapelemet a hozzá tartozó sminkfüggvénnyel, szükség van a szokásos hook_theme függvény megírására is, hogy tudja: ez egy sminkelhető függvény.
function email_theme() { return array( 'email_textfield' => array( 'arguments' => array('element' => NULL), ), // More theme functions declared here… ); } function theme_email_textfield($element) { return $element['#children']; }
A theme_email_textfield eljárás nem csinál semmi különöset, mindössze a Drupal Form API-ja által generált HTML értéket adja vissza (ahogy az az 'includes/form.inc'-ben látható). Érdemes tudni, hogy lehetne ennél komolyabb sminkfüggvényt is írni az element['field_name'] és $element['delta'] értékek felhasználásával (ezek az űrlapelem nevét és pozícióját tárolják).
Utolsó simításként készíthetünk a felhasználók által kezelhető ún. egyedi mező formázókat is, melyek az adott tartalomtípus "Megjelenítési beállítások" oldalán érhetők el (admin/content/node-type/[TARTALOMTÍPUS NEVE]/display).
Példa: az Email modul a hook_field_formatter_info segítségével definiálja saját mező formázóit, majd a hook_theme-ben deklarálja az azokat előállító callback függvényeket, végül megvalósítja az így deklarált theme_EGYEDI_FORMÁZÓ függvényeit, melyekben összeállítja a végső HTML kimeneteket.
---
A cikk hossza ellenére még csak a felszínét súroltuk a CCK lehetőségeinek. Az említett függvényekről bővebben a CCK csomagban található kiegészítő modulokban olvashatunk (pl. text, nodereference), melyek gazdag dokumentációt tartalmaznak.
Hozzászólások
nagyon jó
kíváncsian várom a többi részt is. ezek igazi színfoltjai lesznek a drupal.hu kézikönyvnek. habár angolul rengeteg információt lehet ezekről a dolgokról elérni, az angol szövegértés, mint bottleneck :) folyamatosan jelen van a fórumon, bizonyos problémák megoldás-javaslatainak megítélésekor.
szép kerek mondat. :)
remek lett, megy a karma ;)
-
clear: both;
Nagyon koszi!
Az elismeres pedig a Trellon csapatat is eppugy megilleti. Apropo kuldom is nekik a linket a forditasrol. :)
Végre jött egy ember, aki
Végre jött egy ember - akire 2010 május 30-ig vártunk kezdők -, aki felismerte hogy ez a cikk igazi csemege kivétel nélkül minden Drupalos kezdőnek a CCK titkairól. /De talán nem csak nekik./
Nagy köszönet Zserno Neked és a Trellon Csapatnak ezért a kiváló, értékes munkáért!!!
Üdvözöllek: Dzsozef
Ez az első nap, hol a többi magyarul persze?
...csak egy kicsit vagyok telhetetlen.:)
üdv: Dzsozef
Megasztárok mp3 és videó klippek
Gratulalok!
Nagyon szep es hasznos forditas.
Most mar CCK mezot is tudok irni :D.
Varjuk a folytatast es a sok sok egyeb hasznos forditast.
---
http://drupalaton.hu